VHDL Code for Debouncer: Syntax, Example, and Tips
A debouncer in VHDL filters out noisy button presses by sampling the input signal over time and only changing output when the input is stable. Use a
process with a counter and clock to implement this filtering logic.Syntax
A basic debouncer uses a clocked process that samples the noisy input signal. It uses a counter to measure how long the input stays stable before updating the output.
clk: The clock signal to synchronize sampling.rst: Reset signal to initialize the debouncer.noisy_in: The raw input signal that may bounce.debounced_out: The stable output signal after debouncing.counter: Counts clock cycles while input is unstable.
vhdl
process(clk, rst) begin if rst = '1' then debounced_out <= '0'; counter <= 0; elsif rising_edge(clk) then if noisy_in = debounced_out then counter <= 0; else counter <= counter + 1; if counter = MAX_COUNT then debounced_out <= noisy_in; counter <= 0; end if; end if; end if; end process;
Example
This example shows a simple debouncer that waits for 20 ms of stable input before changing the output. It assumes a 1 MHz clock (1 µs period), so 20,000 clock cycles equal 20 ms.
vhdl
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity Debouncer is
Port (
clk : in std_logic;
rst : in std_logic;
noisy_in : in std_logic;
debounced_out : out std_logic
);
end Debouncer;
architecture Behavioral of Debouncer is
constant MAX_COUNT : natural := 20000; -- 20 ms at 1 MHz clock
signal counter : natural range 0 to MAX_COUNT := 0;
signal stable_out : std_logic := '0';
begin
process(clk, rst)
begin
if rst = '1' then
stable_out <= '0';
counter <= 0;
elsif rising_edge(clk) then
if noisy_in = stable_out then
counter <= 0;
else
if counter < MAX_COUNT then
counter <= counter + 1;
else
stable_out <= noisy_in;
counter <= 0;
end if;
end if;
end if;
end process;
debounced_out <= stable_out;
end Behavioral;Output
The output signal <debounced_out> changes only after the input <noisy_in> remains stable for 20 ms, filtering out quick bounces.
Common Pitfalls
Common mistakes when writing a debouncer in VHDL include:
- Not resetting the counter properly, causing the output to never update.
- Using a counter size too small for the required debounce time.
- Sampling input asynchronously without a clock, leading to metastability.
- Updating output immediately on input change without waiting for stability.
Always synchronize input sampling with a clock and use a counter to confirm stability.
vhdl
process(clk, rst) begin if rst = '1' then debounced_out <= '0'; counter <= 0; elsif rising_edge(clk) then -- WRONG: output changes immediately without debounce debounced_out <= noisy_in; end if; end process; -- Correct way is to use a counter as shown in the example section.
Quick Reference
| Concept | Description |
|---|---|
| Clocked process | Use a clock to sample input and avoid glitches. |
| Counter | Count stable clock cycles before changing output. |
| Reset | Initialize output and counter to known state. |
| Stable output | Change output only after input is stable for debounce time. |
| Debounce time | Set counter max value based on clock frequency and desired delay. |
Key Takeaways
Use a clocked process with a counter to filter noisy input signals.
Only update the output after the input remains stable for the debounce period.
Reset the counter and output properly to avoid stuck states.
Choose the counter size based on your clock frequency and required debounce time.
Avoid asynchronous input sampling to prevent metastability.