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:
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:
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: