用Verilog实现按键抖动消除电路,抖动时间可以设置。
RTL代码:
module key_glitch
#(
parameter CNT_KEY = 6
)
(
input clk,
input rst_n,
input key_in,
output reg key_flag
);
reg [7:0]cnt;
reg key_in_r0;
reg key_in_r1;
wire key_edge;
always@(posedge clk or negedge rst_n)
if(!rst_n)begin
key_in_r0 <= 1'b0;
key_in_r1 <= 1'b0;
end
else begin
key_in_r0 <= key_in;
key_in_r1 <= key_in_r0;
end
assign key_edge = (~key_in_r1 & key_in_r0)|(key_in_r1 & ~key_in_r0);
always@(posedge clk or negedge rst_n)
if(!rst_n)
cnt <= 'd0;
else if(key_edge)
cnt <= 'd0;
else if(cnt == CNT_KEY)
cnt <= cnt;
else
cnt <= cnt + 1'b1;
always@(posedge clk or negedge rst_n)
if(!rst_n)
key_flag <= 1'b0;
else if(cnt == CNT_KEY-1)
key_flag <= key_in;
endmodule
仿真:
module key_glitch_tb;
// Inputs
reg clk;
reg rst_n;
reg key_in;
// Outputs
wire key_flag;
// Instantiate the Unit Under Test (UUT)
key_glitch
#(.CNT_KEY(3))
uut(
.clk(clk),
.rst_n(rst_n),
.key_in(key_in),
.key_flag(key_flag)
);
initial clk = 0;
always#10 clk = ~clk;
initial begin
// Initialize Inputs
rst_n = 0;
key_in = 0;
// Wait 100 ns for global reset to finish
#100;
rst_n = 1;
key_in = 1;
#20;
key_in = 0;
#70;
key_in = 1;
#50;
key_in = 0;
#90;
key_in = 1;
#200;
key_in = 0;
#20;
key_in = 1;
#30;
key_in = 0;
#60;
key_in = 0;
#90;
key_in = 1;
#20;
key_in = 0;
#20;
key_in = 1;
#90;
$stop;
// Add stimulus here
end
endmodule