fpga项目: 按键状态机检测法 - minichao9901/TangNano-20k-Zynq-7020 GitHub Wiki

状态图

image

image

代码

module key_filter(
    input clk,
    input rst_n,
    input key,
    
    output reg down_flag,
    output reg up_flag

    );

reg [19:0] cnt;
reg down_pulse;
reg up_pulse;
reg [1:0] r_key;
reg [1:0] state;

parameter IDLE=0;
parameter P_FILTER=1;
parameter WAIT_R=2;
parameter R_FILTER=3;
parameter TCNT=1000_000-1;

always @(posedge clk or negedge rst_n)
if(rst_n==0)
    r_key<=2'b00;
else
    r_key<={r_key[0],key};

assign down_pulse=~r_key[0] && r_key[1];
assign up_pulse=r_key[0] && ~r_key[1];

always @(posedge clk or negedge rst_n)
if(rst_n==0) begin
    state<=IDLE;
    cnt<=0;
end
else case(state)
    IDLE: if(down_pulse) state<=P_FILTER;
    P_FILTER: if(up_pulse && cnt<TCNT)
                state<=IDLE;
              else if(cnt==TCNT) begin
                state<=WAIT_R;
                cnt<=0;
              end  
              else
                cnt<=cnt+1;
    WAIT_R: if(up_pulse)
               state<=R_FILTER;
    R_FILTER: if(down_pulse && cnt<TCNT)
               state<=WAIT_R;
              else if(cnt==TCNT) begin
               state<=IDLE;
               cnt<=0;
              end
              else
                cnt<=cnt+1;
    default: state<=IDLE;
    endcase


always @(posedge clk or negedge rst_n)
if(rst_n==0) begin
    up_flag<=0;
    down_flag<=0;
end
else case(state)
    IDLE: up_flag=0;
    P_FILTER: if(cnt==TCNT)
                down_flag=1;
    WAIT_R: down_flag=0;
    R_FILTER: if(cnt==TCNT)
                up_flag=1;  
    default: begin up_flag=0; down_flag=0; end              
endcase
      
   
endmodule

测试代码

module test;
    reg clk, rst_n;
    initial clk=0;
    always #10 clk=~clk;
    
    initial begin
        rst_n=0;
        #1000;
        rst_n=1;
    end
    
    reg key;
    initial begin
    key=1;
    wait(rst_n==1);
    #100000;
    key=0;
    #50;
    key=1;
    #100;
    key=0;
    #200;
    key=1;
    #50;
    key=0;
    
    #1000000;
    
    key=1;
    #100;
    key=0;
    #200;
    key=1;
    #50;
    key=0;    
    #50;
    key=1;      
    
    end


key_filter 
#(
    .TCNT(1000_0-1)
)
key_filter_inst
(
    .clk(clk),
    .rst_n(rst_n),
    .key(key),
    
    .down_flag(down_flag),
    .up_flag(up_flag)

    );

endmodule

波形

image