第一: 项目需求
使用按键控制蜂鸣器发声。初始状态为蜂鸣器鸣叫,按下开关后蜂鸣器停 止鸣叫,再次按下开关,蜂鸣器重新鸣叫。
注意:本篇博客的主要目的是练习仿真
第二:仿真运行的源代码
module key_beep(
input clk,
input rst_n,
input key,
output reg beep,
output reg key_value,
output reg key_flag
);
reg key_reg;
reg [31:0] delay_cnt;
//按键的消除抖得过程
always@(posedge clk or negedge rst_n)begin
if(!rst_n)begin
delay_cnt<=32'd0;
key_reg<=1'b1;// 初始化为高电平,按键按下时应该为低电平.
end
else begin
key_reg<=key;//第一步等于始化赋值
if(key_reg!=key)//第二步不等于的
delay_cnt<=32'd1000_000;
else if(key_reg==key) begin//第三
if(delay_cnt>32'd0)
delay_cnt<=delay_cnt-1'b1;
else
delay_cnt<=delay_cnt;
end
end
end
always@(posedge clk or negedge rst_n)begin
if(!rst_n) begin
key_flag<=1'b0;
key_value<=4'b1;
end
else begin
if(delay_cnt==32'd1)begin //
key_flag<=1'b1;
key_value<=key;
end
else begin
key_flag<=1'b0;
key_value<=key_value;
end
end
end
always@(posedge clk or negedge rst_n)begin
if(!rst_n)
beep<=1'b1;
else if (key_flag&&(~key_value))
beep<=~beep;
else
beep<=beep;
end
endmodule
第三:测试用的仿真源代码
`timescale 1ns/1ns
module key_beep_tb();
reg clk;
reg rst_n;
reg key; //此处的先后顺序代表了,仿真图上的先后顺序
wire key_value;
wire key_flag;
wire beep;
parameter T=20;
initial begin
key=1'b1;
clk=1'b0;
rst_n=1'b0;
#20 rst_n = 1'b1; //在第20ns的时候复位信号信号拉高
#50 key=1'b0; //150ns
#70 key=1'b1; //170ns
#100 key=1'b0; //200ns
#20_000200 key=1'b1; //20ms +20ns
#20_000250 key=1'b0; //20ms+250ns
#50_000000 key=1'b1; //50ms
#50_500000 key=1'b0; //55ms*/
$stop;
end
always#(T/2) clk<=~clk;
key_beep key_beep_u0(
.clk (clk),
.rst_n (rst_n),
.key (key),
.beep (beep),
.key_value (key_value),
.key_flag (key_flag)
);
endmodule
运行结果:
第四:收获
1:仿真时数据出现 数值出现 1'bz, 代表这个输出为高阻态或者悬空,应该是这个变量没有例化。
2: 仿真时数出现数值1’bx ,代表这个数值没有初始化。
3: wire 代表输出,reg 代表输入。 注意先后顺序,因为与仿真图得数据先后顺序有关。
4: 仿真文件得输入变量通常是包含初始化得,但是输出变量不包含初始化。