/*当有按键按下时,为了消除抖动,一般抖动会有5-10ms
启动延时计数器,如果按键保持低电平的时间足够长,
计数一定会满足设定的计数条件,否则计数器清零,等待下一次按键到老
*/
module key(
input clk,
input rst_n,
input key_in,
output reg[3:0]sum
);
reg[10:0]counter;//消抖延时计数器
reg state;
reg pos_flag;//尖峰计数器
always@(posedge clk or negedge rst_n)
if(!rst_n)
begin
counter<=0;
state<=0;
pos_flag<=0;
end
else begin
case(state)
0:begin
if(counter<10)
begin
if(!key_in)
counter<=counter+1;
else
counter<=0;
end
else begin
pos_flag<=1;
counter<=0;
state<=1;
end
end
1:begin
pos_flag<=0;
if(key_in)
state<=0;
end
default:state<=0;
endcase
end
always@(posedge clk or negedge rst_n)
if(!rst_n)
sum<=0;
else if(pos_flag)
sum<=sum+1;
endmodule
`timescale 1ns/1ns
module key_tb;
reg clk;
reg rst_n;
reg key_in;
wire [3:0]sum;
initial begin
clk=0;
rst_n=0;
key_in=1;
#100;
rst_n=1;
#30 key_in=0;
#30 key_in=1;
#20 key_in=0;
#90 key_in=1;
#1000 key_in=0;
#200 key_in=1;
#10000 key_in=0;
#120 key_in=1;
#2000;
$stop;
end
always #10 clk=~clk;
key key(
. clk(clk),
. rst_n(rst_n),
. key_in(key_in),
.sum(sum)
);
endmodule