fpga 键盘防抖动模块设计

module PushButton_Debouncer(clk, PB, PB_state, PB_up, PB_down,rest);
input clk;  // "clk" 时钟信号
input PB;  // "PB" 有毛刺的、异步的、低有效的按键信号
input rest;
output PB_state;  // 当按键被按下时输出1
output PB_down;  // 按键被按下的瞬间输出一个高电平脉冲
output PB_up;  // 按键被松开的瞬间输出一个高电平脉冲
// 首先使用两个触发器来同步PB信号
reg PB_sync_0;  always @(posedge clk) PB_sync_0 <= ~PB;  // 翻转PB,使之高有效
reg PB_sync_1;  always @(posedge clk) PB_sync_1 <= PB_sync_0;
// 声明一个16位的计数器
reg [15:0] PB_cnt;
// 当按键被按下或松开时,计数器计数
// 当计数器计数溢出时,便认为按键的状态的确已经改变
reg PB_state;  // 按键状态 (0:松开, 1:按下)
wire PB_idle = (PB_state==PB_sync_1);
wire PB_cnt_max = &PB_cnt; //当PB_cnt为全1时,输出为真
always @(posedge clk)

if(rest==0)

PB_state<=0;

else
if(PB_idle)
    PB_cnt <= 0;  // 没发生任何事情
else
begin
    PB_cnt <= PB_cnt + 1;  // 按键被按下或者松开, 增加计数器的值r
    if(PB_cnt_max) PB_state <= ~PB_state;  // 如果计数器溢出,改变PB_state的值
end
wire PB_down = ~PB_state & ~PB_idle & PB_cnt_max;  // 当按键被按下时,有效一个时钟周期
wire PB_up   =  PB_state & ~PB_idle & PB_cnt_max;  // 当按键被松开时,有效一个时钟周期
endmodule

使用16位的计数器、20MHz的时钟,需要3ms的时间才能使计数器溢出。在用户眼里,3ms的时间很短,甚至来不及反应,但是毛刺却正是在这3ms内被除去的。根据具体的按键和系统时钟,你可能需要修改计数器的宽度。

你可能感兴趣的:(fpga 键盘防抖动模块设计)