This Verilog module implements a key debounce function. It filters out spurious signals caused by mechanical noise during keypresses, ensuring accurate and reliable detection of key events.

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 

Debouncing Logic Breakdown

  1. Initial Sampling: The module captures the input key signal (i_key) into a register (key_samp1) on every clock edge.

  2. First-Stage Latching: This sampled value is then latched into another register (key_samp1_locked) to preserve its state across clock cycles.

  3. Change Detection: By comparing the current value (key_samp1) with the latched value (key_samp1_locked), the module identifies any transitions in the input signal, indicating a potential keypress or release. The detected transitions are marked in a signal (key_changed1).

  4. Debouncing Counter: A counter (cnt) is used to determine the duration of the change. The counter resets whenever a change is detected. This helps filter out short-duration noise spikes.

  5. Second-Stage Sampling: If the counter reaches a specific threshold (20ms in this case), indicating a sustained change, the input signal is captured into a second register (key_samp2). This represents a more stable value of the key input.

  6. Second-Stage Latching: The value of key_samp2 is then latched into key_samp2_locked for consistent comparison across clock cycles.

  7. Stable Key Detection: The final debounced key value (o_key_val) is determined by comparing the second-stage sampled value (key_samp2) with its latched version (key_samp2_locked). This ensures the output signal represents a stable key state.

This approach effectively removes noise spikes and ensures that the output represents a clean, debounced key signal. The code is well-commented and easy to understand, making it suitable for integration into various digital designs requiring robust key input processing.

Verilog Key Debounce Module: Effective Noise Reduction for Keypresses

原文地址: https://www.cveoy.top/t/topic/olv8 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录