FPGA-based key debounce

Scenarios and principles

Key in the circuit due to the material of the key, when the key press will bounce or jitter, this jitter is not allowed to exist in the FPGA. Because the jitter will have a key misjudgment, this is a very common phenomenon in the electronic circuit, jitter removal can be implemented in hardware circuitry, want to know the method can refer to the technical foundation stone Yan teacher of digital circuits this book, in trigger chapters have to say. The experiment is implemented using software code key debounce, the main principle is to achieve, when the two key jitter jitter does not exceed the time interval 20ms.

State transition diagram design

Even then simple code, we should follow the standard process to achieve. Because key debounce module contains a state machine, we draw the state transition diagram of the state machine, as follows:
Here Insert Picture Description
from the above state transition diagram, we can easily write code, no further explanation here. My tradition, directly on the code.

Module code key debounce

Debouncing key module code is as follows:

`timescale 1ns / 1ps
// *********************************************************************************
// Project Name : OSXXXX
// Author       : zhangningning
// Email        : [email protected]
// Website      : 
// Module Name  : key.v
// Create Time  : 2020-01-05 13:49:36
// Editor       : sublime text3, tab size (4)
// CopyRight(c) : All Rights Reserved
//
// *********************************************************************************
// Modification History:
// Date             By              Version                 Change Description
// -----------------------------------------------------------------------
// XXXX       zhangningning          1.0                        Original
//  
// *********************************************************************************

module key(
    input                       sclk            ,
    input                       rst_n           ,
    input                       key             ,
    output  reg                 key_o       
);
 
//========================================================================================\
//**************Define Parameter and  Internal Signals**********************************
//========================================================================================/
parameter       IDLE        =       4'b0001     ;    
parameter       S1          =       4'b0010     ;
parameter       S2          =       4'b0100     ;
parameter       S3          =       4'b1000     ;

reg                 [ 3:0]      state           ;
reg                 [ 9:0]      cnt             ;
reg                             key_r1          ;
reg                             key_r2          ;
reg                             key_r3          ;
reg                             nege_flag       ;
reg                             pose_flag       ;
 
//========================================================================================\
//**************     Main      Code        **********************************
//========================================================================================/
always @(posedge sclk)
    key_r1          <=      key;

always @(posedge sclk)
    key_r2          <=      key_r1;

always @(posedge sclk)
    key_r3          <=      key_r2;

always @(posedge sclk or negedge rst_n)
    if(rst_n == 1'b0)
        nege_flag       <=      1'b0;
    else if(key_r3 == 1'b1 && key_r2 == 1'b0)
        nege_flag       <=      1'b1;
    else
        nege_flag       <=      1'b0;

always @(posedge sclk or negedge rst_n)
    if(rst_n == 1'b0)
        pose_flag       <=      1'b0;
    else if(key_r3 == 1'b0 && key_r2 == 1'b1) 
        pose_flag       <=      1'b1;
    else
        pose_flag       <=      1'b0;

always @(posedge sclk or negedge rst_n)
    if(rst_n == 1'b0)
        state           <=      IDLE;
    else case(state)
        IDLE    :   if(nege_flag == 1'b1)
                        state           <=      S1;
                    else
                        state           <=      IDLE;                        
        S1      :   if(cnt == 10'd999)
                        state           <=      S2;
                    else if(pose_flag == 1'b1)
                        state           <=      IDLE;
                    else
                        state           <=      S1;                        
        S2      :   if(pose_flag == 1'b1)
                        state           <=      S3;
                    else
                        state           <=      S2;                        
        S3      :   if(cnt == 10'd999)
                        state           <=      IDLE;
                    else if(nege_flag == 1'b1)
                        state           <=      S2;
                    else
                        state           <=      S3;
                        
        default :   state           <=      IDLE;
    endcase

always @(posedge sclk or negedge rst_n)
    if(rst_n == 1'b0)
        cnt             <=      10'd0;
    else if(state != S1 && state != S3)
        cnt             <=      10'd0;
    else
        cnt             <=      cnt + 1'b1;

always @(posedge sclk or negedge rst_n)
    if(rst_n == 1'b0)
        key_o           <=      1'b0;
    else if(state == S1 && cnt == 10'd999) 
        key_o           <=      1'b1;
    else
        key_o           <=      1'b0;

endmodule

I often see the article believe the students are already familiar with the code above style, observing state transition diagrams and logic code can easily get to know the code. To prove the correctness of the program, I had a program simulation.

Key test code module debounce

Here's the test code also uses the task statement, and the use of task statements nested task statement, after this lesson of practice, we believe the wording of the test module has been well known.

`timescale 1ns / 1ps
`define     CLOCK       20
// *********************************************************************************
// Project Name : OSXXXX
// Author       : zhangningning
// Email        : [email protected]
// Website      : 
// Module Name  : key_tb.v
// Create Time  : 2020-01-05 14:09:55
// Editor       : sublime text3, tab size (4)
// CopyRight(c) : All Rights Reserved
//
// *********************************************************************************
// Modification History:
// Date             By              Version                 Change Description
// -----------------------------------------------------------------------
// XXXX       zhangningning          1.0                        Original
//  
// *********************************************************************************

module key_tb();
reg                         sclk                ;
reg                         rst_n               ;
reg                         key                 ;
wire                        key_o               ;

initial begin
    sclk            <=          1'b0;
    rst_n           =           1'b0;
    key             =           1'b1;
    #(100*`CLOCK)
    rst_n           =           1'b1;
    #(100*`CLOCK)
    key_pulse;
    #(100*`CLOCK)
    key_pulse;
    #(100*`CLOCK)
    key_pulse;
    #(100*`CLOCK)
    key_pulse;
    #(100*`CLOCK)
    key_pulse;
    #(100*`CLOCK)
    key_pulse;
    #(100*`CLOCK)
    key_pulse;
    #(100*`CLOCK)
    key_pulse;
end
always  #(`CLOCK/2)     sclk        <=      ~sclk;

task key_pulse;
    begin
        key         <=          1'b1;
        shake(1000);
        key         <=          1'b0;
        #(5000*`CLOCK)
        shake(1000);
        key         <=          1'b1;
        #(5000*`CLOCK);
    end
endtask

task shake   ;
    input      [10:0]           times   ;
    integer         i                   ;
    begin
        for(i = 0; i<times; i = i+1)begin
            key     <=          {$random} % 2;
            #(`CLOCK);
        end       
    end 
endtask

key key_inst(
    .sclk                   (sclk                   ),
    .rst_n                  (rst_n                  ),
    .key                    (key                    ),
    .key_o                  (key_o                  )
);  
endmodule

FIG modelsim simulation presented herein, as follows:
Here Insert Picture Description
From the figure we can see the simulation accuracy of our experiments.

Conclusion

I blog code can run the program directly, without any streamlining. Writing is not easy, that the article can help students like collection point support. What do you think of the article or need step closer exchange students, can join the following group:
Here Insert Picture Description

Published 14 original articles · won praise 4 · Views 593

Guess you like

Origin blog.csdn.net/zhangningning1996/article/details/103843241