To put it simply, no matter how pure simulation, single chip microcomputer, DSP, arm and Other Processors, or our FPGA, the buttons are generally not used. Buttons: human-computer interaction control, mainly used for system control and signal release. So here, we have to talk about the key jitter of FPGA applications!
I. Why jitter elimination?
As shown in, during the brief moment when the button is pressed, the jitter on the hardware usually produces several milliseconds of jitter. At this time, if the signal is collected, it will inevitably lead to misoperation or even system crash; similarly, when the button is released, the hardware will experience jitter and the same consequences will occur. Therefore, in analog or digital circuits, we need to avoid signal acquisition and operations in the most unstable situations.
This is generally caused by the principle of dejitter. It can be divided into the following types:
(1) latency
(2) n low-level counts
(3) low-pass Filtering
In digital circuits, (1) (2) methods are generally used. This topic will be detailed later.
Ii. Various jitter elimination 1. Analog Circuit key jitter Elimination
In a simulated circuit, the capacitor or Schmidt-triggered circuit is generally used for dejitter. Schmidt trigger circuit is as follows. For details, refer to Baidu Library:
Http://wenku.baidu.com/view/c77025d9ce2f0066f5332276.html
2. Key jitter elimination in Single Chip Microcomputer
For the key jitter in single chip microcomputer, this section bingo is based on one of the Single Chip MicrocomputerCodeThe Code is as follows:
Unsigned char key_scan (void)
{
If (Key = 0) // It is detected to be pressed
{
Delay (5); // latency: 5 ms, deshake
If (key! = 0)
Retrurn 0; // It is a jitter and returns to exit
While (! Key1); // confirm to be pressed, wait for release
Delay (5); // latency: 5 ms, deshake
While (! Key1); // confirm to be released
Return 1; // return the press Signal
}
Return 0; // No signal
}
For the above Code, the order of dejitters is as follows:
(1) detected signal
(2) delay of 5 ms, dejitters
(3) continue to detect the signal and confirm whether it is pressed
A) Yes, start to wait for release
B) No, return 0 and exit
(4) latency of 5 ms, jitter Elimination
(5) confirm, return the press signal, and exit
Of course, in the single-chip microcomputer, you can also cyclically count to confirm whether it is pressed. Bingo believes that this is a waste of MCU resources, so it will not be said again.
3. De-jitter of buttons in FPGA
Many textbooks have not discussed the dejitters in FPGA. But Bingo thinks this is necessary. For signal stability and accuracy analysis, the key signal must have a stable pulse, otherwise it will have a great disturbance to system stability.
Here, Bingo uses two methods to analyze the jitter of buttons in FPGA. The first method is to directly transplant the above MCU code through the use of the state machine. This idea is very important in FPGA state machine. The second method is to determine whether a task is actually pressed by repeating n counts. This method is useful in High-Speed Parallel devices such as FPGA.
(1) using the state machine to transplant MCU button Jitter
This module was modified and tested by bingo countless times to form the final code. It can adapt to N buttons in terms of function, and uses the single chip microcomputer to eliminate jitter. You need to analyze the specific code implementation process on your own. This module is easy to transplant. The following is the sample code in the OpenGL module:
/*************************************** **********
* Module name: key_scan_jitter.v
* Engineer: crazy bingo
* Target device: ep2c8q208c8
* Tool versions: Quartus II 11.0
* Create Date: 2011-6-26
* Revision: V1.0
* Description:
**************************************** **********/
Module key_scan_jitter
#(
Parameter key_width = 2
)
(
Input CLK,
Input rst_n,
Input [KEY_WIDTH-1: 0] key_data,
Output key_flag,
Output Reg [KEY_WIDTH-1: 0] key_value
);
Reg [19: 0] CNT; // delay_5ms (249999)
Reg [2: 0] State;
//-----------------------------------
Always @ (posedge CLK or negedge rst_n)
Begin
If (! Rst_n)
CNT <= 20'd0;
Else
Begin
CNT <= CNT + 1' B1;
If (CNT = 20 'd249999)
CNT <= 20'd0;
End
End
//-----------------------------------
Reg key_flag_r;
Reg [KEY_WIDTH-1: 0] key_data_r;
Always @ (posedge CLK or negedge rst_n)
Begin
If (! Rst_n)
Begin
Key_flag_r <= 1 'b0;
Key_value <= {key_width {1 'b0 }};
End
Else if (CNT = 20 'd249999) // delay_5ms
Begin
Case (state)
0:
Begin
If (key_data! = {Key_width {1 'b1 }})
State <= 1;
Else
State <= 0;
End
1:
Begin
If (key_data! = {Key_width {1 'b1 }})
State <= 2;
Else
State <= 0;
End
2:
Begin
Key_flag_r <= 1 'b1;
Key_value <= key_data; // lock the key_value
State <= 3;
End
3:
Begin
Key_flag_r <= 1 'b0; // read the key_value
If (key_data =={ key_width {1 'b1 }})
State <= 4;
Else
State <= 3;
End
4:
Begin
If (key_data =={ key_width {1 'b1 }})
State <= 0;
Else
State <= 4;
End
Endcase
End
End
//---------------------------------------
// Capture the falling endge of the key_flag
Reg key_flag_r0, key_flag_r1;
Always @ (posedge CLK or negedge rst_n)
Begin
If (! Rst_n)
Begin
Key_flag_r0 <= 0;
Key_flag_r1 <= 0;
End
Else
Begin
Key_flag_r0 <= key_flag_r;
Key_flag_r1 <= key_flag_r0;
End
End
Assign key_flag = key_flag_r1 &~ Key_flag_r0;
Endmodule
The signal lines are described as follows:
CLK
Maximum system clock
Rst_n
System reset signal
Key_data
Key Signal (n-bit can be configured as needed)
Key_flag
Key confirmation signal
Key_vaule
Key Return Value
Similar to the above MCU key jitter status, this module can be simulated into five States, see state machine:
(2) number of cycles to eliminate Jitter
Similarly, this module is the final code of bingo's numerous modifications and tests. It uses fewer resources and is more suitable for the performance requirements of parallel High-Speed FPGA. For specific code implementation process, please analyze it on your own. This module uses the adaptation of the relevant clock and n counts to confirm the key signal. The following is the sample code in OpenGL:
/*************************************** **********
* Module name: key_scan.v
* Engineer: crazy bingo
* Target device: ep2c8q208c8
* Tool versions: Quartus II 11.0
* Create Date: 2011-6-25
* Revision: V1.0
* Description:
**************************************** **********/
Module key_scan
#(
Parameter key_width = 2
)
(
Input CLK, // 50 MHz
Input rst_n,
Input [KEY_WIDTH-1: 0] key_data,
Output key_flag,
Output Reg [KEY_WIDTH-1: 0] key_value
);
//---------------------------------
// Escape the jitters
Reg [19:0] key_cnt; // scan counter
Reg [KEY_WIDTH-1: 0] key_data_r;
Always @ (posedge CLK or negedge rst_n)
Begin
If (! Rst_n)
Begin
Key_data_r <= {key_width {1 'b1 }};
Key_cnt <= 0;
End
Else
Begin
Key_data_r <= key_data; // lock the key value
If (key_data = key_data_r) & (key_data! = {Key_width {1 'b1}) // 20 ms escape Jitter
Begin
If (key_cnt <20 'hfffff)
Key_cnt <= key_cnt + 1 'b1;
End
Else key_cnt <= 0;
End
End
Wire cnt_flag = (key_cnt = 20 'hffffe )? 1 'b1: 1' B0 ;//!!
//-----------------------------------
// Sure the key is pressed
Reg key_flag_r;
Always @ (posedge CLK or negedge rst_n)
Begin
If (! Rst_n)
Begin
Key_flag_r <= 0;
Key_value <= 0;
End
Else if (cnt_flag)
Begin
Key_flag_r <= 1;
Key_value <= key_data; // locked the data
End
Else // Let go your hand
Key_flag_r <= 0; // lock the key_value
End
//---------------------------------------
// Capture the rising endge of the key_flag
Reg key_flag_r0, key_flag_r1;
Always @ (posedge CLK or negedge rst_n)
Begin
If (! Rst_n)
Begin
Key_flag_r0 <= 0;
Key_flag_r1 <= 0;
End
Else
Begin
Key_flag_r0 <= key_flag_r;
Key_flag_r1 <= key_flag_r0;
End
End
Assign key_flag = ~ Key_flag_r1 & key_flag_r0;
Endmodule