当前位置:文档之家› Verilog写的按键消抖程序

Verilog写的按键消抖程序

前几天看了特权同学用Verilog写的按键消抖程序,感觉很经典。

在这里将程序贴出来分享一下。

module lcd_button2(clk,rst,seg,wei,sw1,sw2,sw3,sw4);//按键按下,数码管依次显示0-9input clk;input rst;input sw1,sw2,sw3,sw4;output [3:0] wei;output[7:0] seg;reg [7:0] seg;reg [3:0] wei;integer num;initial beginnum = 0;endreg[3:0] key_rst;always @(posedge clk or negedge rst)if(!rst)key_rst <= 4'b1111;elsekey_rst <= {sw4,sw3,sw2,sw1};reg[3:0] key_rst_r;always @(posedge clk or negedge rst)if(!rst)key_rst_r <= 4'b111;elsekey_rst_r <= key_rst;wire[3:0] key_an = key_rst_r & (~key_rst);reg[19:0] cnt;always @(posedge clk or negedge rst)if(!rst)cnt <= 0;else if(key_an) cnt <= 0;else cnt <= cnt+1'b1;reg [3:0] low_sw;always @(posedge clk or negedge rst)if(!rst)low_sw <= 4'b1111;else if(cnt==10'hfffff)low_sw <= {sw4,sw3,sw2,sw1};reg[3:0] low_sw_r;always @(posedge clk or negedge rst)if(!rst)low_sw_r <= 4'b1111;elselow_sw_r <= low_sw;wire [3:0] led_ctrl = low_sw_r[3:0] & (~low_sw[3:0]);reg d1,d2,d3,d4;always @(posedge clk or negedge rst)if(!rst) begind1 <= 0;d2 <= 0;d3 <= 0;d4 <= 0;endelse beginif(led_ctrl[0]) beginnum <= num+1;if(num==9)num <= 0;endendalways @(posedge clk ) beginwei <= 4'b1111;case(num)0: seg <= 8'hfc;1: seg <= 8'h60;2: seg <= 8'hda;3: seg <= 8'hf2;4: seg <= 8'h66;5: seg <= 8'hb6;6: seg <= 8'hbe;7: seg <= 8'he0;8: seg <= 8'hfe;9: seg <= 8'hf6;default: seg <= 8'h02;endcaseendendmodule参考了特权的代码。

/1375/21132.aspx-------------------------------------------------module key_debounce(input i_clk,input i_rst_n,input [4:1] i_key, // 按下为0,松开为1output reg [4:1] o_key_val // 键值);//++++++++++++++++++++++++++++++++++++++reg [4:1] key_samp1, key_samp1_locked;// 将i_key采集至key_samp1always @ (posedge i_clk, negedge i_rst_n)beginif(!i_rst_n)key_samp1 <= 4'hF;elsekey_samp1 <= i_key;end// 将key_samp1锁存至key_samp1_lockedalways @ (posedge i_clk, negedge i_rst_n)beginif(!i_rst_n)key_samp1_locked <= 4'hF;elsekey_samp1_locked <= key_samp1;end//--------------------------------------//++++++++++++++++++++++++++++++++++++++wire [4: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)beginif(!i_rst_n)cnt <= 20'h0;else if(key_changed1)cnt <= 20'h0;elsecnt <= cnt + 1'b1;end//--------------------------------------//++++++++++++++++++++++++++++++++++++++reg [4:1] key_samp2, key_samp2_locked;// 只有当按键不变化(不抖动),且维持20ms以上时// 才将i_key采集至key_samp2always @ (posedge i_clk, negedge i_rst_n)beginif(!i_rst_n)key_samp2 <= 4'hF;else if(cnt == 20'hF_FFFF) // 0xFFFFF/50M = 20.9715ms key_samp2 <= i_key;end// 将key_samp2锁存至key_samp2_lockedalways @ (posedge i_clk, negedge i_rst_n)beginif(!i_rst_n)key_samp2_locked <= 4'hF;elsekey_samp2_locked <= key_samp2;end//--------------------------------------//++++++++++++++++++++++++++++++++++++++wire [4:1] key_changed2;// 当key_samp2由1变为0时// key_changed2由0变为1,且维持一个时钟周期assign key_changed2 = key_samp2_locked & (~key_samp2); //--------------------------------------//++++++++++++++++++++++++++++++++++++++// 每次按键稳定后,都将键值取反always @ (posedge i_clk, negedge i_rst_n)beginif(!i_rst_n)o_key_val <= 4'hF;elsebeginif(key_changed2[1])o_key_val[1] <= ~o_key_val[1];if(key_changed2[2])o_key_val[2] <= ~o_key_val[2];if(key_changed2[3])o_key_val[3] <= ~o_key_val[3];if(key_changed2[4])o_key_val[4] <= ~o_key_val[4];endend//--------------------------------------endmodulemodule debounce(clk,rst_n,key_i,key_o);input clk;input rst_n;input key_i;output key_o;reg key_o;wire key;wire clk_slow;//分频电路reg [22:0] cnt;reg [25:0] cnt_out;wire key_o_reg ;always @ ( posedge clk or negedge rst_n )if ( !rst_n )cnt <= 23'd0;elsecnt <= cnt + 1'b1;assign clk_slow = cnt[22];//防反跳电路reg temp_r [2:0];reg key_r;integer i;always @ ( posedge clk_slow or negedge rst_n )if ( !rst_n )beginfor ( i = 0 ; i < 3; i = i+ 1)temp_r[i] <= 'd0;endelsebegintemp_r[0] <= key_i;temp_r[1] <= temp_r[0];temp_r[2] <= temp_r[1];endassign key = (~temp_r[0]) & temp_r[1] & temp_r[2]; // 防抖动电路always @ ( posedge clk or negedge rst_n )if ( !rst_n )key_r <= 1'b0;elsekey_r <= key;assign key_o_reg = key & (~key_r);/*always @ ( posedge clk or negedge rst_n )if( !rst_n )key_o <= 1'b0 ;elsebeginif( cnt_out<='d3******* )beginif( cnt_out=='d0 )beginif( key_o_reg )begincnt_out <= 'd1 ;key_o <= 1'b1 ;endelsebegincnt_out <= 'd0 ;key_o <= 1'b0 ;endendelsecnt_out <= cnt_out + 'd1 ;endelsecnt_out <= 'd0 ;end*/endmodule/bbs/bbs_content.jsp?bbs_sn=3870307&bbs_id=1029。

相关主题