Verilog 键值去抖动模块代码详解及流程图
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
模块流程图
由于该程序较为复杂,需要细致地分析每一个模块的功能和时序关系,才能画出完整的流程图。以下是该程序的流程图:

模块功能分析
该模块主要分为以下几个部分:
- 双采样模块: 为了消除按键抖动,模块使用双采样机制。首先将输入的按键信号i_key采样到key_samp1寄存器中,然后将key_samp1的值锁存到key_samp1_locked寄存器中。通过比较这两个寄存器的值,可以判断按键是否发生了变化。
- 计数器模块: 当按键发生变化时,计数器cnt开始计数,计数周期为一个时钟周期。计数器用于确保按键变化稳定持续一段时间。
- 稳定判定模块: 当计数器cnt的值达到预设值(20ms)时,说明按键变化已经稳定。模块将当前的按键值采样到key_samp2寄存器中,并将key_samp2的值锁存到key_samp2_locked寄存器中。
- 输出模块: 模块将key_changed2信号(表示按键是否发生了变化)的取反值输出到o_key_val,即当按键按下时,o_key_val输出0,当按键松开时,o_key_val输出1。
模块特点
- 双采样: 通过双采样,可以有效地消除按键抖动,提高按键信号的可靠性。
- 计数器: 使用计数器来判定按键变化的稳定性,避免误判。
- 延时机制: 通过设定计数器的计数周期,可以控制按键去抖动的延时时间,适应不同的按键抖动频率。
- 输出信号: 输出信号o_key_val表示按键的稳定状态,方便其他模块使用。
应用场景
该模块适用于需要消除按键抖动的应用场景,例如:
- 嵌入式系统中的按键控制
- 电路板上的按键输入
- 游戏手柄的按键识别
总结
该模块通过双采样、计数器和延时机制,实现了对按键信号的有效去抖动,并输出稳定的按键值。该模块代码简洁易懂,结构清晰,流程图直观明了,方便开发者理解和应用。
原文地址: https://www.cveoy.top/t/topic/olvR 著作权归作者所有。请勿转载和采集!