module anjian(clk,rst_n,key_in,key_vld);
parameter KEY_W= 6;//6个按键
input clk;
input rst_n;
input [KEY_W-1:0] key_in;//按键输入
output key_vld;//按键是否有效按下
wire add_count;
wire end_count;
reg [20:0] count;//计数 20ms消抖动
reg flag_add;
reg [KEY_W-1:0] key_in_ff1;//对key_in做2个delay
reg [KEY_W-1:0] key_in_ff0;
parameter TIME_20MS= 2_000_000;//T=10ns 2^20=1024*1024
reg [KEY_W-1:0] key_vld;
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
count<=21'b0;
end
else if (add_count) begin
if (end_count)
count<=21'b0;
else
count<=count+1;
end
else begin
count<=21'b0;
end
end
assign add_count= (flag_add==1'b0) && (&key_in_ff1==0); //有按键按下 并且<=20ms
assign end_count= (add_count) && (count== TIME_20MS-1);//有按键按下并且第20ms
//flag_add=1 按键按下>20ms且未松开
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
flag_add<=1'b0;
end
else if (end_count) begin//20ms下一时刻
flag_add<=1'b1;
end
else if (&key_in_ff1==1) begin
flag_add<=1'b0;
end
end
always @(posedge clk or negedge rst_n) begin
if(!rst_n) begin
key_in_ff0<={{KEY_W}{1'b1}};//6'b1
key_in_ff1<={{KEY_W}{1'b1}};//6'b1
end
else begin
key_in_ff0<=key_in;
key_in_ff1<=key_in_ff0;//打两拍
end
end
always @(posedge clk or negedge rst_n) begin
if(!rst_n) begin
key_vld<={{KEY_W}{1'b0}};
end
else if (end_count) begin//有按键按下并且第20ms的下一时刻
key_vld<=~key_in_ff1;//按键按下为0 而key_vld高电平有效
end
else begin
key_vld<={{KEY_W}{1'b0}};
end
end