按键去抖动模块 Verilog 代码实现

该 Verilog 代码实现了一个简单的按键去抖动模块,模块接收一个 10 位的按键输入信号,输出经过去抖动的按键值。

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. 采样: 模块使用两个采样寄存器 key_samp1key_samp2 来分别记录按键信号的两次状态。
  2. 计时: 模块使用一个 20 位的计数器 cnt 来计时,当按键按下时,计数器清零;当按键未变化时,计数器自增。
  3. 去抖动: 当计数器达到一个预定的值时(比如 20ms),认为按键已经稳定,并将当前的按键状态保存到 key_samp2 寄存器中。
  4. 输出: 模块最终将 key_samp2 中的按键状态输出,实现去抖动后的按键值。

模块实现细节:

  1. 模块使用两个always块分别采集和锁存按键信号。
  2. 模块使用一个assign语句来判断按键信号的变化。
  3. 模块使用一个always块来实现计数器功能。
  4. 模块使用一个assign语句来判断按键是否稳定。
  5. 模块使用一个always块来输出去抖动后的按键值。

总结:

该 Verilog 代码实现了一个简单的按键去抖动模块,利用两个采样寄存器和一个计数器,通过判断按键信号变化和计时来消除按键抖动,最终输出稳定的按键值。该模块适用于需要处理按键信号的数字电路设计中。

按键去抖动模块 Verilog 代码实现

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

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