参考链接:米联客教程:https://blog.csdn.net/jinry001/article/details/9969498
按键消抖子程序:
module key #
(
parameter CLK_FREQ = 100000000
)
(
input clk_i,
input key_i,
output key_cap
);
//10ms,100MHz时钟对应计数值,1/100_000_000*val=10*10^-3
parameter CNT_10MS = (CLK_FREQ/100 - 1'b1);
parameter KEY_S0 = 2'd0;
parameter KEY_S1 = 2'd1;
parameter KEY_S2 = 2'd2;
parameter KEY_S3 = 2'd3;
reg [24:0] cnt10ms = 25'd0;
reg [1:0] key_s = 2'b0;
reg [1:0] key_s_r = 2'b0;
wire en_10ms ;
//产生10ms计数时钟
assign en_10ms = (cnt10ms == CNT_10MS);
//按键按下的检测逻辑,
assign key_cap = (key_s==KEY_S2)&&(key_s_r==KEY_S1);
always @(posedge clk_i)begin //计数10ms
if(cnt10ms < CNT_10MS)
cnt10ms <= cnt10ms + 1'b1;
else
cnt10ms <= 25'd0;
end
always @(posedge clk_i)begin //key_s_r相对key_s延迟一个时钟,决定检测逻辑的写法
key_s_r <= key_s;
end
//消抖状态机,实质是在en_10ms计数时钟下的状态转移
always @(posedge clk_i)
begin
if(en_10ms)
begin
case(key_s)
KEY_S0:
begin
if(!key_i)
key_s <= KEY_S1;
end
KEY_S1:
begin
if(!key_i)
key_s <= KEY_S2;
else
key_s <= KEY_S0;
end
KEY_S2:
begin
if(key_i)
key_s <= KEY_S3;
end
KEY_S3:
begin
if(key_i)
key_s <= KEY_S0;
else
key_s <= KEY_S2;
end
endcase
end
end
endmodule
顶层程序,点亮LED灯。
module Key_debounce(
input clk_i,
input rst_n_i,
input key_i,
output [3:0] led
);
reg [3:0] led;
wire key_cap;
always @(posedge clk_i)begin
if(!rst_n_i)begin
led <= 4'b0000;
end
else if(key_cap)begin
led <= ~led;
end
end
key#
(
.CLK_FREQ(100000000)
)
key0
(
.clk_i(clk_i),
.key_i(key_i),
.key_cap(key_cap)
);
endmodule
来源:CSDN
作者:Bronceyang131
链接:https://blog.csdn.net/weixin_37728585/article/details/103570610