132 wrote:
> Take google.com, type vhdl debounce and find about 9000 hits.
Lets take the first one:
1 | process (CLK, x)
|
2 | variable SDC : integer;
|
3 | constant Delay : integer := 50000;
|
4 | begin
|
5 | if CLK'Event and CLK = '1' then
|
6 | ...
|
This looks like beginner style because x is not necessary in the
sensitivity list and is not a really good style to use variables in such
an extensive manner.
Additionally it is not good to load a couter with a given value and
count it down to 0 afterwards:
1 | :
|
2 | SDC := Delay;
|
3 |
|
4 | State <= S1;
|
5 | when S1 =>
|
6 | SDC := SDC - 1;
|
7 |
|
8 | if SDC = 0 then
|
9 | State <= S0;
|
10 | :
|
This probably needs more ressources, because the reset inputs of a
flipflop inside the FPGA cannot be used for loading the counter. The
better way is to reset a counter and compare it with the uppermost
value.
The third link is the best code, but it uses the old obsolete
std_logic_unsigned lib. And to size the counter is far to difficult. Of
course it is/seems very efficient to size the counter a way that the
overflow of it can be used to trigger the sampling event, but in real
life it is much easier and straight away just to spend a little bit
logic and let the synthesizer do the timing calculations...
Matt wrote:
> How can I obtain a clean output after the button has been pushed for
> 20ms? Thanks!
Implement a counter counting up to 20ms.
Reset this counter whenever you detect a change in the input signal.
Sample the input the counter reaches 20ms.
Done.
Now lets take the code from the last link and transform it to a kind of
"up-to-date" style using the fancy new numeric_std lib instead of the
old synopsis libs:
1 | LIBRARY ieee;
|
2 | USE ieee.std_logic_1164.all;
|
3 | USE ieee.numeric_std.all;
|
4 |
|
5 | ENTITY debounce IS
|
6 | PORT( clk : IN STD_LOGIC; --input clock
|
7 | button : IN STD_LOGIC; --input signal to be debounced
|
8 | result : OUT STD_LOGIC); --debounced signal
|
9 | END debounce;
|
10 |
|
11 | ARCHITECTURE behave OF debounce IS
|
12 | SIGNAL inff : STD_LOGIC_VECTOR(1 DOWNTO 0); -- input flip flops
|
13 | CONSTANT cnt_max : INTEGER := (33000000/50)-1 : -- 33MHz and 1/20ms=50Hz
|
14 | SIGNAL count : INTEGER range 0 to cnt_max := 0;
|
15 | BEGIN
|
16 | PROCESS(clk)
|
17 | BEGIN
|
18 | IF(clk'EVENT and clk = '1') THEN
|
19 | inff <= inff(0) & button; -- sync in the input
|
20 | IF(inff(0)/=inff(1)) THEN -- reset counter because input is changing
|
21 | count <= 0;
|
22 | ELSIF(count<cnt_max) THEN -- stable input time is not yet met
|
23 | count <= count + 1;
|
24 | ELSE -- stable input time is met
|
25 | result <= inff(1);
|
26 | END IF;
|
27 | END IF;
|
28 | END PROCESS;
|
29 | END behave;
|
> Thanks!
Youre welcome!