0
0
VhdlHow-ToBeginner · 3 min read

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

ConceptDescription
Clocked processUse a clock to sample input and avoid glitches.
CounterCount stable clock cycles before changing output.
ResetInitialize output and counter to known state.
Stable outputChange output only after input is stable for debounce time.
Debounce timeSet 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.