按键去抖模块 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 锁存到 key_samp1_locked 中。
    • 通过比较 key_samp1key_samp1_locked 的值,检测按键状态是否发生了变化。
    • 当按键状态发生变化时,生成信号 key_changed1

    debounce1

  2. 计数抖动时间:

    • key_changed1 为高电平时,将计数器 cnt 清零。
    • key_changed1 为低电平时,开始计数。
    • 如果计数器计数到 20ms,则表示按键状态稳定。

    debounce2

  3. 输出稳定的键值:

    • cnt 计数到 20ms 时,将 i_key 的值采样到寄存器 key_samp2 中。
    • key_samp2 锁存到 key_samp2_locked 中。
    • 通过比较 key_samp2key_samp2_locked 的值,检测按键状态是否发生了变化。
    • 当按键状态发生变化时,生成信号 key_changed2
    • key_changed2 为高电平时,输出稳定的键值 o_key_val

    debounce3

总结

本代码通过采样、锁存、比较、计数等操作,实现了对按键输入信号的去抖处理,最终输出稳定的键值。

注意:

  • 代码中使用的计数器 cnt 的计数周期为 20ms,可以根据实际情况进行调整。
  • 该代码仅供参考,实际应用中可能需要根据具体需求进行修改。

希望这篇文章能帮助你理解按键去抖模块的工作原理,并能够应用到你的项目中。

按键去抖模块 Verilog 代码及流程图

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

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