按键计数消抖动
			 2025-07-14
			  6
			 0
			
			
			这里设计4个状态
按下时为key=0,抬起时时KEY=1
- S0:未按下状态,检测到KEY=0,进入S1,否则依旧为S0
- S1:进入后,依旧为按下,进入S2(表示持续了很长的按下),否则S0
- S2:上次处于下状态,如继续处于按下状态,依旧为S2,抬起进入D3
- S3:抬起状态,如果依旧为抬起则进入S0,否则为抖动进入S2
工程代码如下:
module key(
input clk,
input rst,
input key,
output cap
    );
parameter KEY_S0 = 2'd0;
parameter KEY_S1 = 2'd1;
parameter KEY_S2 = 2'd2;
parameter KEY_S3 = 2'd3;    
reg[3:0] en_cnt;
always@(posedge clk)
begin
    if(!rst)
        en_cnt<=0;
     else if(en_cnt==4)
        en_cnt<=0;
     else
        en_cnt<= en_cnt+1;
end
reg[1:0] key_cur = 2'd0;
reg[1:0] key_pre=2'd0;
always@(posedge clk)
begin
    if(en_cnt==4)
    begin
        case(key_cur)
            KEY_S0:begin
                if(!key)
                    key_cur<=KEY_S1;
                else
                    key_cur<=KEY_S0;
             end
             KEY_S1:begin
                if(!key)
                    key_cur<=KEY_S2;
                else 
                  key_cur<=KEY_S0;  
             end
             KEY_S2:begin
                if(key)
                    key_cur<=KEY_S3;
                else
                    key_cur<=KEY_S2;
             end
             KEY_S3:begin 
                if(key)
                    key_cur<=KEY_S0;
                 else
                    key_cur<=KEY_S2;
             end
        endcase     
    end
end
always@(posedge clk)
begin
    key_pre<=key_cur;    
end
assign cap = key_cur == KEY_S2 && key_pre==KEY_S1;
endmodule
仿真代码
module key_tb();
  reg clk;
  reg rst;
  reg key;
  wire cap;
  initial
  begin
    rst = 0;
    clk = 0;
    key = 1;
    #10
    key = 1;
    rst = 1;
    #60
    key = 0;
    #200
    key = 1;
   end
 always #5 clk= ~clk;
 key key_inist(
 .clk(clk),
 .rst(rst),
 .key(key),
 .cap(cap)
 );

 FPGA入门练习
			FPGA入门练习
			




