Verilog Key Debounce Module: Effective Key Press Detection with Two-Stage Sampling
This Verilog module implements a key debounce function using a two-stage sampling and counting approach. The module ensures accurate key press detection by filtering out spurious signal changes caused by mechanical contact bounce. This effectively eliminates the need for software-based debouncing, improving system reliability.
module key_debounce(
input i_clk,
input i_rst_n,
input [9:1] i_key, // 按下为0,松开为1
output reg [9:1] o_key_val // 键值
);
//++++++++++++++++++++++++++++++++++++++
reg [9:1] key_samp1, key_samp1_locked;
// 将i_key采集至key_samp1
always @ (posedge i_clk, negedge i_rst_n)
if(!i_rst_n)
key_samp1 <= 9'h1FF;
else
key_samp1 <= i_key;
// 将key_samp1锁存至key_samp1_locked
always @ (posedge i_clk, negedge i_rst_n)
if(!i_rst_n)
key_samp1_locked <= 9'h1FF;
else
key_samp1_locked <= key_samp1;
//--------------------------------------
//++++++++++++++++++++++++++++++++++++++
wire [9:1] key_changed1;
// 当key_samp1由1变为0时
// key_changed1由0变为1,只维持一个时钟周期
assign key_changed1 = key_samp1_locked & (~key_samp1);
//--------------------------------------
//++++++++++++++++++++++++++++++++++++++
reg [19:0] cnt;
// 一旦有按键按下,cnt立即被清零
always @ (posedge i_clk, negedge i_rst_n)
if(!i_rst_n)
cnt <= 20'h0;
else if(key_changed1)
cnt <= 20'h0;
else
cnt <= cnt + 1'b1;
//--------------------------------------
//++++++++++++++++++++++++++++++++++++++
reg [9:1] key_samp2, key_samp2_locked;
// 只有当按键不变化(不抖动),且维持20ms以上时
// 才将i_key采集至key_samp2
always @ (posedge i_clk, negedge i_rst_n)
if(!i_rst_n)
key_samp2 <= 9'h1FF;
else if(cnt == 20'hF_FFFF) // 0xFFFFF/50M = 20.9715ms
key_samp2 <= i_key;
// 将key_samp2锁存至key_samp2_locked
always @ (posedge i_clk, negedge i_rst_n)
if(!i_rst_n)
key_samp2_locked <= 9'h1FF;
else
key_samp2_locked <= key_samp2;
//--------------------------------------
//++++++++++++++++++++++++++++++++++++++
wire [9:1] key_changed2;
// 当key_samp2由1变为0时
// key_changed2由0变为1,只维持一个时钟周期
assign key_changed2 = key_samp2_locked & (~key_samp2);
//--------------------------------------
//++++++++++++++++++++++++++++++++++++++
// 每次按键稳定后,输出键值
// 按下为0,松开为1
always @ (posedge i_clk, negedge i_rst_n)
if(!i_rst_n)
o_key_val <= 9'h1FF;
else
o_key_val <= ~key_changed2;
//--------------------------------------
endmodule
The module utilizes a two-stage sampling and counting mechanism. Initially, the input key signal is sampled into 'key_samp1' and then latched into 'key_samp1_locked'. A change detection signal 'key_changed1' is generated when 'key_samp1' transitions from 1 to 0, capturing the initial key press. A counter 'cnt' is used to measure the duration of the key press. Upon detecting a key press, the counter is reset. If the counter reaches a predetermined threshold (20ms in this case), the input signal is captured in 'key_samp2'. A second change detection signal 'key_changed2' is generated when 'key_samp2' transitions from 1 to 0, signifying a stable key press. Finally, the output 'o_key_val' reflects the state of the key, with 0 representing a key press and 1 representing a key release.
This approach effectively eliminates the effects of contact bounce by ensuring a stable key press signal before outputting the key value. The two-stage sampling ensures that any spurious signals caused by bounce are filtered out, resulting in a more reliable and accurate key press detection mechanism.
原文地址: https://www.cveoy.top/t/topic/olv7 著作权归作者所有。请勿转载和采集!