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 

模块流程图

由于该程序较为复杂,需要细致地分析每一个模块的功能和时序关系,才能画出完整的流程图。以下是该程序的流程图:

key_debounce_flowchart

模块功能分析

该模块主要分为以下几个部分:

  1. 双采样模块: 为了消除按键抖动,模块使用双采样机制。首先将输入的按键信号i_key采样到key_samp1寄存器中,然后将key_samp1的值锁存到key_samp1_locked寄存器中。通过比较这两个寄存器的值,可以判断按键是否发生了变化。
  2. 计数器模块: 当按键发生变化时,计数器cnt开始计数,计数周期为一个时钟周期。计数器用于确保按键变化稳定持续一段时间。
  3. 稳定判定模块: 当计数器cnt的值达到预设值(20ms)时,说明按键变化已经稳定。模块将当前的按键值采样到key_samp2寄存器中,并将key_samp2的值锁存到key_samp2_locked寄存器中。
  4. 输出模块: 模块将key_changed2信号(表示按键是否发生了变化)的取反值输出到o_key_val,即当按键按下时,o_key_val输出0,当按键松开时,o_key_val输出1。

模块特点

  • 双采样: 通过双采样,可以有效地消除按键抖动,提高按键信号的可靠性。
  • 计数器: 使用计数器来判定按键变化的稳定性,避免误判。
  • 延时机制: 通过设定计数器的计数周期,可以控制按键去抖动的延时时间,适应不同的按键抖动频率。
  • 输出信号: 输出信号o_key_val表示按键的稳定状态,方便其他模块使用。

应用场景

该模块适用于需要消除按键抖动的应用场景,例如:

  • 嵌入式系统中的按键控制
  • 电路板上的按键输入
  • 游戏手柄的按键识别

总结

该模块通过双采样、计数器和延时机制,实现了对按键信号的有效去抖动,并输出稳定的按键值。该模块代码简洁易懂,结构清晰,流程图直观明了,方便开发者理解和应用。

Verilog 键值去抖动模块代码详解及流程图

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

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