This program utilizes a two-stage sampling and counting approach for debouncing, as follows:

  1. First-Stage Sampling

Initially, the input key signal 'i_key' is captured in 'key_samp1' and simultaneously latched into 'key_samp1_locked'. A transition in 'key_samp1' from 1 to 0 indicates a key press. At this point, the 'key_changed1' signal switches from 0 to 1, signaling a change in key state. However, this change could be due to key bounce, requiring a second-stage sampling and counting for confirmation.

  1. Counting

Concurrently with the first-stage sampling, a counter 'cnt' keeps track of the duration of the unchanging key state. If 'key_samp1' transitions from 1 to 0 or 'cnt' reaches a specific time threshold (20ms), a second-stage sampling is initiated.

  1. Second-Stage Sampling

If the first-stage sampling and counting confirm a change in key state, the input key signal 'i_key' is captured in 'key_samp2' during the second-stage sampling and latched into 'key_samp2_locked'. A transition in 'key_samp2' from 1 to 0 signifies a stable key state. The 'key_changed2' signal switches from 0 to 1, indicating a confirmed key press.

  1. Output

Based on the state of 'key_changed2', the key state is output. A pressed state is represented by 0, while a released state is represented by 1. In essence, 'o_key_val <= ~key_changed2'.

This method efficiently eliminates false triggering caused by key bouncing while ensuring the stability of the detected key press.

Code Breakdown:

module key_debounce(
  input            i_clk,
  input            i_rst_n,
  input      [9:1] i_key,               // Pressed = 0, Released = 1
  output reg [9:1] o_key_val            // Key Value
);

//++++++++++++++++++++++++++++++++++++++
reg [9:1] key_samp1, key_samp1_locked;

// Capture i_key into key_samp1
always @ (posedge i_clk, negedge i_rst_n)
  if(!i_rst_n) 
    key_samp1 <= 9'h1FF;
  else         
    key_samp1 <= i_key;

// Latch key_samp1 into 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;

// When key_samp1 transitions from 1 to 0
// key_changed1 transitions from 0 to 1 for a single clock cycle
assign key_changed1 = key_samp1_locked & (~key_samp1); 
//--------------------------------------


//++++++++++++++++++++++++++++++++++++++
reg [19:0] cnt;

// Reset cnt upon key press
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;

// Capture i_key into key_samp2 only when the key state is stable and has remained so for at least 20ms
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;

// Latch key_samp2 into 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;

// When key_samp2 transitions from 1 to 0
// key_changed2 transitions from 0 to 1 for a single clock cycle
assign key_changed2 = key_samp2_locked & (~key_samp2); 
//--------------------------------------


//++++++++++++++++++++++++++++++++++++++
// Output the key value after each stable key press
// Pressed = 0, Released = 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 
Verilog Key Debounce Module: Two-Stage Sampling and Counting Method

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

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