Verilog 按键消抖模块:实现按键稳定采样

本 Verilog 模块实现按键消抖功能,通过计数器和锁存器确保按键信号稳定后才进行采样,有效避免按键抖动带来的误操作。

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

功能实现:

  1. 按键采样与锁存: 将输入的按键信号 i_key 采样到 key_samp1 中,并将其锁存到 key_samp1_locked 中。
  2. 按键变化检测:key_samp1 由 1 变为 0 时,将其视为按键发生了变化,并将该信息赋值给 key_changed1
  3. 计数器清零: 每次 key_samp1 由 1 变为 0 时,将计数器 cnt 清零,表示按键被按下了。
  4. 稳定性检测:cnt 达到一个固定的值(20ms)时,将 i_key 采样到 key_samp2 中,并将其锁存到 key_samp2_locked 中。
  5. 输出键值: 每次 key_samp2 稳定后,输出键值 o_key_val,按下为 0,松开为 1。

总结:

通过上述步骤,该 Verilog 模块实现了按键的消抖和采样功能,保证了按键信号的稳定性和可靠性。

Verilog 按键消抖模块:实现按键稳定采样

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

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