Skip to content

Commit 9fb8e9e

Browse files
committed
Added better debouncer.
1 parent f5000c3 commit 9fb8e9e

File tree

3 files changed

+92
-28
lines changed

3 files changed

+92
-28
lines changed

rtl/comp/debouncer.vhd

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
--------------------------------------------------------------------------------
2+
-- PROJECT: SIMPLE UART FOR FPGA
3+
--------------------------------------------------------------------------------
4+
-- MODULE: DEBOUNCER
5+
-- AUTHORS: Jakub Cabal <[email protected]>
6+
-- LICENSE: The MIT License (MIT), please read LICENSE file
7+
-- WEBSITE: https://github.com/jakubcabal/uart-for-fpga
8+
--------------------------------------------------------------------------------
9+
10+
library IEEE;
11+
use IEEE.STD_LOGIC_1164.ALL;
12+
use IEEE.NUMERIC_STD.ALL;
13+
14+
entity DEBOUNCER is
15+
Generic (
16+
-- latency of debouncer in clock cycles, minimum value is 2,
17+
-- value also corresponds to the number of bits compared
18+
LATENCY : natural := 4
19+
);
20+
Port (
21+
CLK : in std_logic; -- system clock
22+
DEB_IN : in std_logic; -- input of signal from outside FPGA
23+
DEB_OUT : out std_logic -- output of debounced (filtered) signal
24+
);
25+
end DEBOUNCER;
26+
27+
architecture RTL of DEBOUNCER is
28+
29+
constant SHREG_DEPTH : natural := LATENCY-1;
30+
31+
signal input_shreg : std_logic_vector(SHREG_DEPTH-1 downto 0);
32+
signal output_reg_rst : std_logic;
33+
signal output_reg_set : std_logic;
34+
35+
begin
36+
37+
-- parameterized input shift register
38+
input_shreg_p : process (CLK)
39+
begin
40+
if (rising_edge(CLK)) then
41+
input_shreg <= input_shreg(SHREG_DEPTH-2 downto 0) & DEB_IN;
42+
end if;
43+
end process;
44+
45+
-- output register will be reset when all compared bits are low
46+
output_reg_rst_p : process (DEB_IN, input_shreg)
47+
variable or_var : std_logic;
48+
begin
49+
or_var := DEB_IN;
50+
all_bits_or_l : for i in 0 to SHREG_DEPTH-1 loop
51+
or_var := or_var or input_shreg(i);
52+
end loop;
53+
output_reg_rst <= not or_var;
54+
end process;
55+
56+
-- output register will be set when all compared bits are high
57+
output_reg_set_p : process (DEB_IN, input_shreg)
58+
variable and_var : std_logic;
59+
begin
60+
and_var := DEB_IN;
61+
all_bits_and_l : for i in 0 to SHREG_DEPTH-1 loop
62+
and_var := and_var and input_shreg(i);
63+
end loop;
64+
output_reg_set <= and_var;
65+
end process;
66+
67+
-- output register
68+
output_reg_p : process (CLK)
69+
begin
70+
if (rising_edge(CLK)) then
71+
if (output_reg_rst = '1') then
72+
DEB_OUT <= '0';
73+
elsif (output_reg_set = '1') then
74+
DEB_OUT <= '1';
75+
end if;
76+
end if;
77+
end process;
78+
79+
end RTL;

rtl/uart.vhd

Lines changed: 10 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,6 @@ architecture FULL of UART is
4848

4949
signal uart_clk_cnt : unsigned(CLK_CNT_WIDTH-1 downto 0);
5050
signal uart_clk_en : std_logic;
51-
signal uart_rxd_shreg : std_logic_vector(3 downto 0);
5251
signal uart_rxd_debounced : std_logic;
5352

5453
begin
@@ -75,34 +74,19 @@ begin
7574
uart_clk_en <= '1' when (uart_clk_cnt = CLK_CNT_MAX) else '0';
7675

7776
-- -------------------------------------------------------------------------
78-
-- UART RXD SHIFT REGISTER AND DEBAUNCER
77+
-- UART RXD DEBAUNCER
7978
-- -------------------------------------------------------------------------
8079

8180
use_debouncer_g : if (USE_DEBOUNCER = True) generate
82-
uart_rxd_shreg_p : process (CLK)
83-
begin
84-
if (rising_edge(CLK)) then
85-
if (RST = '1') then
86-
uart_rxd_shreg <= (others => '1');
87-
else
88-
uart_rxd_shreg <= UART_RXD & uart_rxd_shreg(3 downto 1);
89-
end if;
90-
end if;
91-
end process;
92-
93-
uart_rxd_debounced_reg_p : process (CLK)
94-
begin
95-
if (rising_edge(CLK)) then
96-
if (RST = '1') then
97-
uart_rxd_debounced <= '1';
98-
else
99-
uart_rxd_debounced <= uart_rxd_shreg(0) or
100-
uart_rxd_shreg(1) or
101-
uart_rxd_shreg(2) or
102-
uart_rxd_shreg(3);
103-
end if;
104-
end if;
105-
end process;
81+
debouncer_i : entity work.DEBOUNCER
82+
generic map(
83+
LATENCY => 4
84+
)
85+
port map (
86+
CLK => CLK,
87+
DEB_IN => UART_RXD,
88+
DEB_OUT => uart_rxd_debounced
89+
);
10690
end generate;
10791

10892
not_use_debouncer_g : if (USE_DEBOUNCER = False) generate

sim/sim.tcl

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
vlib work
1212

1313
# Compile VHDL files
14+
vcom -93 ../rtl/comp/debouncer.vhd
1415
vcom -93 ../rtl/comp/uart_parity.vhd
1516
vcom -93 ../rtl/comp/uart_tx.vhd
1617
vcom -93 ../rtl/comp/uart_rx.vhd
@@ -21,6 +22,6 @@ vcom -93 ./uart_tb.vhd
2122
vsim work.uart_tb
2223

2324
# Setup and start simulation
24-
add wave *
25-
#add wave sim:/uart_tb/utt/*
25+
#add wave *
26+
add wave sim:/uart_tb/utt/*
2627
run 200 us

0 commit comments

Comments
 (0)