【按键消抖】— WuFan方法+野火方法

一、设计文件

第一种方法:WuFan

首选这种方法

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

// 功能:按键消抖

// 细节:检测按键下降沿

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

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

);
parameter MAX = 22'd2499_999;

reg [4:0] key_r;     

always @(posedge Clk or negedge Rst_n)begin
    if(Rst_n == 1'b0)
        key_r <= 1'b0;
    else begin
          key_r[0] <= key_in;
          key_r[1] <= key_r[0];
          key_r[2] <= key_r[1];
          key_r[3] <= key_r[2];
          key_r[4] <= key_r[3];
     end
end
     
always @(*) begin
    key_flag <= key_r[4]&(~key_r[3])&(~key_r[2])&(~key_r[1])&(~key_r[0])&(~key_in);
end
     
endmodule

第二种方法:野火

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

// 功能:按键消抖

// 细节:下降沿稳定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图

posted @ 2022-04-01 16:34  刘小颜  阅读(339)  评论(0)    收藏  举报