Verilog Key Debouncing Module with 20ms Timeout
Verilog Key Debouncing Module with 20ms Timeout
This module implements a key debouncing mechanism with a 20ms timeout, filtering out key press noise to ensure stable key values.
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 if(key_changed2)
o_key_val <= key_samp2_locked;
endmodule
Explanation
- Sampling and Locking: The module uses two sampling registers (key_samp1, key_samp2) to capture the input key value (i_key). These values are then locked into respective locked registers (key_samp1_locked, key_samp2_locked) to maintain the previous state for debouncing.
- Change Detection: Two signals (key_changed1, key_changed2) detect changes in the sampled values. These signals are set to 1 for a single clock cycle when the corresponding sampled value transitions from 1 to 0.
- Timeout Counter: A 20-bit counter (cnt) is used to track the time since the last key press. When a key press is detected (key_changed1), the counter is reset. The counter is incremented on each clock cycle.
- 20ms Timeout: The 20ms timeout is calculated based on the 50MHz clock frequency. The counter reaches the maximum value (0xFFFFF) after 20ms. When the counter reaches this value, the key is considered stable and the i_key value is sampled into key_samp2.
- Output: The final output (o_key_val) is updated when a stable key press is detected. It reflects the locked value of key_samp2_locked. This ensures that the output value only changes after the debouncing timeout.
20ms Timeout Calculation
The 20ms timeout is calculated as follows:
20ms = 0xFFFFF / 50MHz
Where 0xFFFFF represents the maximum value of the 20-bit counter and 50MHz is the clock frequency. The counter reaches the maximum value after 20ms, indicating the key has been stable for the desired duration.
This module provides a robust and reliable solution for debouncing key inputs in digital systems. By using a timeout mechanism and multiple sampling stages, it effectively filters out transient noise and ensures accurate key value readings.
原文地址: https://www.cveoy.top/t/topic/olwE 著作权归作者所有。请勿转载和采集!