Bird
Raised Fist0
Verilogprogramming~5 mins

Debouncer circuit design in Verilog

Choose your learning style10 modes available
Introduction

A debouncer circuit cleans up noisy button presses so the computer sees just one clear press.

When reading a push button input to avoid multiple signals from one press.
In a digital clock to make sure each button press changes time once.
For any mechanical switch input to get a clean, stable signal.
When you want to avoid errors caused by quick, repeated signals from a button.
Syntax
Verilog
module debouncer(
    input clk,
    input button_in,
    output reg button_out
);

// internal registers
reg [15:0] counter = 0;
reg button_sync_0 = 0;
reg button_sync_1 = 0;

always @(posedge clk) begin
    // synchronize button input to clock
    button_sync_0 <= button_in;
    button_sync_1 <= button_sync_0;

    if (button_sync_1 == button_out) begin
        counter <= 0; // reset counter if stable
    end else begin
        counter <= counter + 1; // count how long input is stable
        if (counter == 16'hFFFF) begin
            button_out <= button_sync_1; // update output after stable period
        end
    end
end

endmodule

This example uses a 16-bit counter to wait for the input to be stable.

Two flip-flops synchronize the button input to the clock to avoid timing issues.

Examples
A smaller counter for faster debounce but less noise filtering.
Verilog
module simple_debouncer(
    input clk,
    input button_in,
    output reg button_out
);

reg [3:0] count = 0;
reg button_sync_0 = 0;
reg button_sync_1 = 0;

always @(posedge clk) begin
    button_sync_0 <= button_in;
    button_sync_1 <= button_sync_0;

    if (button_sync_1 == button_out) begin
        count <= 0;
    end else begin
        count <= count + 1;
        if (count == 4'b1111) begin
            button_out <= button_sync_1;
        end
    end
end

endmodule
This version adds a reset input to initialize the debouncer.
Verilog
module debouncer_with_reset(
    input clk,
    input rst,
    input button_in,
    output reg button_out
);

reg [15:0] counter = 0;
reg button_sync_0 = 0;
reg button_sync_1 = 0;

always @(posedge clk or posedge rst) begin
    if (rst) begin
        counter <= 0;
        button_out <= 0;
        button_sync_0 <= 0;
        button_sync_1 <= 0;
    end else begin
        button_sync_0 <= button_in;
        button_sync_1 <= button_sync_0;

        if (button_sync_1 == button_out) begin
            counter <= 0;
        end else begin
            counter <= counter + 1;
            if (counter == 16'hFFFF) begin
                button_out <= button_sync_1;
            end
        end
    end
end

endmodule
Sample Program

This testbench simulates a noisy button press and shows how the debouncer cleans the signal.

Verilog
module testbench();
    reg clk = 0;
    reg button = 0;
    wire clean_button;

    // Instantiate debouncer
    debouncer uut(
        .clk(clk),
        .button_in(button),
        .button_out(clean_button)
    );

    // Clock generation
    always #5 clk = ~clk; // 100MHz clock

    initial begin
        $monitor($time, " Button: %b, Clean: %b", button, clean_button);

        // Simulate noisy button press
        #10 button = 1;
        #2 button = 0;
        #3 button = 1;
        #2 button = 0;
        #10 button = 1; // stable press

        #100 $finish;
    end
endmodule

module debouncer(
    input clk,
    input button_in,
    output reg button_out
);

reg [15:0] counter = 0;
reg button_sync_0 = 0;
reg button_sync_1 = 0;

always @(posedge clk) begin
    button_sync_0 <= button_in;
    button_sync_1 <= button_sync_0;

    if (button_sync_1 == button_out) begin
        counter <= 0;
    end else begin
        counter <= counter + 1;
        if (counter == 16'hFFFF) begin
            button_out <= button_sync_1;
        end
    end
end

endmodule
OutputSuccess
Important Notes

Debouncing is important because mechanical buttons do not produce clean signals.

The counter length controls how long the input must be stable before changing output.

Synchronizing inputs to the clock prevents timing errors in digital circuits.

Summary

A debouncer cleans noisy button signals into one stable output.

Use counters and synchronization to detect stable button presses.

Debouncing helps avoid multiple unwanted signals from one press.

Practice

(1/5)
1.

What is the main purpose of a debouncer circuit in Verilog?

easy
A. To convert analog signals to digital
B. To increase the clock speed of the circuit
C. To generate random signals for testing
D. To clean noisy button signals and produce a stable output

Solution

  1. Step 1: Understand the problem of noisy signals

    Mechanical buttons often produce multiple quick on/off signals (noise) when pressed.
  2. Step 2: Role of debouncer

    A debouncer waits for the input to be stable for some time before changing the output, thus cleaning the noise.
  3. Final Answer:

    To clean noisy button signals and produce a stable output -> Option D
  4. Quick Check:

    Debouncer = Clean noisy signals [OK]
Hint: Debouncer = stable output from noisy input [OK]
Common Mistakes:
  • Thinking debouncer speeds up the clock
  • Confusing debouncer with analog to digital converter
  • Assuming debouncer generates signals
2.

Which of the following is the correct way to declare a 16-bit counter register in Verilog?

?
easy
A. wire [16:0] counter;
B. reg [15:0] counter;
C. reg counter[15:0];
D. integer counter[16];

Solution

  1. Step 1: Understand Verilog register declaration

    Registers use 'reg' keyword and bit width is declared as [MSB:LSB].
  2. Step 2: Check each option

    reg [15:0] counter; correctly declares a 16-bit register from bit 15 down to 0.
  3. Final Answer:

    reg [15:0] counter; -> Option B
  4. Quick Check:

    16-bit reg = reg [15:0] name; [OK]
Hint: Use reg [15:0] for 16-bit registers [OK]
Common Mistakes:
  • Using wire instead of reg for counters
  • Incorrect bit range syntax
  • Declaring arrays instead of bit vectors
3.

Given this Verilog snippet for a debouncer counter:

always @(posedge clk) begin
  if (button == last_button) begin
    if (counter < 3) counter <= counter + 1;
  end else counter <= 0;
  last_button <= button;
end

What is the value of counter after 5 clock cycles if button stays stable at 1?

medium
A. 5
B. 0
C. 3
D. 1

Solution

  1. Step 1: Analyze counter increment condition

    Counter increments only if button equals last_button and counter is less than 3.
  2. Step 2: Trace counter over 5 cycles

    Initially counter=0. It increments each cycle until it reaches 3, then stops incrementing.
  3. Final Answer:

    3 -> Option C
  4. Quick Check:

    Counter maxes at 3 despite 5 cycles [OK]
Hint: Counter stops incrementing at max value 3 [OK]
Common Mistakes:
  • Assuming counter increments beyond 3
  • Ignoring last_button update
  • Resetting counter incorrectly
4.

Identify the error in this debouncer code snippet:

reg [3:0] counter;
reg last_button;
always @(posedge clk) begin
  if (button == last_button) begin
    counter = counter + 1;
  end else begin
    counter = 0;
  end
  last_button = button;
end
medium
A. Using blocking assignments (=) inside always block for sequential logic
B. Missing sensitivity list for asynchronous reset
C. Counter width too small for debounce time
D. No initial value for last_button

Solution

  1. Step 1: Check assignment types in sequential always block

    Sequential logic should use non-blocking assignments (<=) to avoid race conditions.
  2. Step 2: Identify the error

    The code uses blocking assignments (=) inside a clocked always block, which is incorrect.
  3. Final Answer:

    Using blocking assignments (=) inside always block for sequential logic -> Option A
  4. Quick Check:

    Use <= for sequential logic assignments [OK]
Hint: Use <= in clocked always blocks [OK]
Common Mistakes:
  • Using = instead of <=
  • Ignoring sensitivity list importance
  • Assuming initial values fix assignment errors
5.

You want to design a debouncer that waits for 10ms of stable input before changing output. The clock frequency is 1MHz. How many bits should the counter have at minimum?

hard
A. 14 bits
B. 10 bits
C. 20 bits
D. 8 bits

Solution

  1. Step 1: Calculate required count for 10ms at 1MHz clock

    10ms = 0.01 seconds. Clock period = 1us (1/1MHz). Number of counts = 0.01 / 0.000001 = 10,000 counts.
  2. Step 2: Find minimum bits to count 10,000

    2^13 = 8192 (too small), 2^14 = 16384 (enough). So minimum 14 bits needed.
  3. Final Answer:

    14 bits -> Option A
  4. Quick Check:

    10,000 < 2^14 = 16384 [OK]
Hint: Count = time * clock freq; bits = ceil(log2(count)) [OK]
Common Mistakes:
  • Using clock frequency as count directly
  • Choosing too few bits to cover count
  • Confusing ms and us units
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard