出自正点原子《开拓者FPGA开发指南V1.3》第九章按键控制蜂鸣器实验
寄存器:key_flag 按键数据有效信号
寄存器:key_value 按键消抖后的数据
寄存器:delay_cnt 延时计数
系统时钟:50MHz
思路:一直检测按键状态,一旦按键状态发现变化,给delay_cnt计数器赋初值100_0000,也就是20ms计数。按键状态不发生改变,那么计数器开始递减计数,直到计数器减到1时,说明按键状态稳定保持20ms,此时给出一个时钟周期的按键有效通知信号key_flag,并将按键数据寄存器key_value锁存输出。
Verilog硬件语言和C语言的不同之一,C语言是顺序语言,如果给出一条赋值语句,左值会立刻变化,而Verilog语言的一条幅值语句需要一个时钟周期改变幅值,也就是一个时钟周期内,所有寄存器的值都不会被改变,只有下一个时钟信号到来,寄存器的值才会被改变。
module key_debounce(
input sys_clk,
input sys_rst_n,
input key,
output reg key_value,
output reg key_flag
);
reg [31:0] delay_cnt;
reg key_reg;
always @(posedge sys_clk or negedge sys_rst_n)begin
if(!sys_rst_n)begin
key_reg <= 1'b1;
delay_cnt <= 32'd0;
end
else begin
key_reg <= key;
if(key_reg != key)
delay_cnt <= 32'd100_0000;
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 sys_clk or negedge sys_rst_n)begin
if(!sys_rst_n)begin
key_flag <= 1'b0;
key_value <= 1'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
endmodule
来源:CSDN
作者:ngany
链接:https://blog.csdn.net/ngany/article/details/104802634