// Verilog简易按键消抖(button debounce)(假设clk为50MHz,持续按下或弹起1/25秒,即40ms,才确认按键状态) // 51个MacroCell,可按需简化 // sonic3d@gmail.com // 2023.Nov.02 module button_debounce ( input clk, input button, // 按钮输入,0表示按下,1表示弹起 output button_debounced // 按钮消抖后的输出,0表示按下,1表示弹起 ); // 消抖状态相关寄存器 reg [24:0] counter_pressed; // 按钮持续按下状态计数器 reg [24:0] counter_not_pressed; // 按钮持续弹起状态计数器 reg button_state = 1'b1; // 按钮消抖结果状态(1表示弹起,0表示按下) assign button_debounced = button_state; // 按钮结果状态输出 // 赋初值,注意这些初始化不会综合进最终硬件,仅用于模拟仿真 initial begin counter_pressed <= 25'b0; counter_not_pressed <= 25'b0; end // 时钟上升沿时进行消抖计数(假设时钟为50MHz,以下代码在2M周期后,即1/25秒后作消抖结果采样) always @ (posedge clk) begin // 按钮按下,且按钮现有消抖结果状态为弹起状态 if(!button & button_state) begin counter_pressed <= counter_pressed + 1'b1; // 消抖计数 end else begin counter_pressed <= 25'b0; // 重置消抖流程 end // 按下持续2M周期后,更新消抖结果值 if(counter_pressed == 25'd2000000) begin counter_pressed <= 25'b0; button_state = 1'b0; end // 按钮弹起,且按钮现有消抖结果状态为按下状态 if(button & !button_state) begin counter_not_pressed <= counter_not_pressed + 1'b1; end else begin counter_not_pressed <= 25'b0; end if(counter_not_pressed == 25'd2000000) begin counter_not_pressed <= 25'b0; button_state = 1'b1; end end endmodule