按键消抖


一、设计文件

第一种方法:野火

// ----------------------------

// 功能:按键消抖

// 细节:下降沿稳定20ms

// ----------------------------


module key_filter
(
    input wire Clk,
    input wire Rst_n,
    input wire key_in,
    
    output reg key_flag

);

reg [19:0] Count;//计数器:999_999

always @(posedge Clk or negedge Rst_n)begin
    if(Rst_n == 1'b0)
        Count <= 20'd0;
    
    else if(key_in == 1'b1)
        Count <= 20'd0;
        else if(Count == 20'd999_999)
        Count <= 20'd999_999;
    else 
        Count <= Count + 20'd1;
        
    end
    
always @(posedge Clk or negedge Rst_n)begin
    if(Rst_n == 1'b0)
        key_flag <= 1'b0;
    else if(Count == (20'd999_999-20'd1))
        key_flag <= 1'b1;
    else 
        key_flag <= 1'b0;
        
    end
endmodule
        
        

二、测试文件

`timescale 1ns/1ns
`define clk_per 20

module key_filter_tb;

reg clk;
reg rst;
reg key_in;

wire key_flag;

reg [7:0] count_key;

key_filter key1
(
    .Clk        (clk),
    .Rst_n    (rst),
    .key_in    (key_in),
    .key_flag(key_flag)

);

initial clk = 1'b1;
always #(`clk_per/2) clk = ~ clk;

initial begin

rst = 1'b0;
#(`clk_per*5) rst = 1'b1;

end

always@(posedge clk or negedge rst)begin
    if(rst == 1'b0)
        count_key <= 8'b0;
    else if (count_key == 8'd249)
        count_key <= 8'd0;
    else 
        count_key <= count_key + 8'd1;
        
    end
    
always@(posedge clk or negedge rst)begin
    if(rst == 1'b0)
        key_in = 1'b1;
    else if(((count_key >= 8'd19) && (count_key <= 8'd69)) 
        || ((count_key >= 8'd149) && (count_key <= 8'd169)))
        key_in <= {$random}%2;
    else if((count_key >= 8'd69) && (count_key <= 8'd149))
        key_in <= 8'd0;
    else 
        key_in <= 8'd1;

    end
endmodule

三、波形图

四、RTL图