Practice
Lane Rack Button
Star Lanes is a small bowling alley with pinsetter machines from the 1970s. Each lane has one reset button on the ball return. A press tells the pinsetter to clear the fallen pins and set a fresh rack.
The button is a bare mechanical contact, and its metal leaf bounces on every press. One press reaches the controller as a burst of pulses. The old controller counted each pulse as a new press, so the machine cycled 2 or 3 times and jammed. League nights stalled while staff climbed into the machine to free the pins. Rolling balls shake the contact too, so short rattles arrive with no press behind them.
Your task: build the debouncer that sits between the button and the controller. Pass raw_i through 2 flip-flops first, because the contact is not lined up with clk_i. Then filter it: clean_o may take a new value only after the contact has held that value for 8 samples in a row. Pulse pressed_o high for 1 cycle when clean_o rises. Pulse released_o high for 1 cycle when clean_o falls.
Interface
| Port | Direction | Type | Description |
|---|---|---|---|
clk_i | in | 1 bit | System clock |
rst_i | in | 1 bit | Synchronous reset (active high) |
raw_i | in | 1 bit | Raw contact from the button, bouncy |
clean_o | out | 1 bit | Debounced button level |
pressed_o | out | 1 bit | One-cycle pulse when clean_o rises |
released_o | out | 1 bit | One-cycle pulse when clean_o falls |
Behavior
- After reset,
clean_ois low: the block treats the button as not pressed - The block samples
raw_iat every rising edge ofclk_i raw_ipasses through a 2-flop synchronizer: the filter sees each sample 2 cycles after the edge that took it- A qualifying run is an unbroken row of samples with the same value, and that value differs from
clean_o - When a run reaches 8 samples,
clean_otakes the run's value at the 2nd rising edge after the edge with the 8th sample - One sample equal to
clean_oends the run; the count starts over at 0 - A run of 7 or fewer samples never changes
clean_o, no matter how many such runs arrive pressed_ois high for exactly the 1 cycle on whichclean_orises, and low at all other timesreleased_ois high for exactly the 1 cycle on whichclean_ofalls, and low at all other timesrst_ihigh at a rising clock edge forcesclean_o,pressed_o, andreleased_olow from that edge- Reset fires no pulse:
released_ostays low even when reset drops a highclean_o - Reset also clears the synchronizer and the count, so a contact still closed after reset must qualify again with a fresh 8-sample run
What the bench checks
- The testbench checks
clean_o,pressed_o, andreleased_oon every cycle of every scenario - The testbench drives a press as a bounce burst that settles high, and checks the exact edge where
clean_orises - The testbench drives a release as a bounce burst that settles low, and checks the exact edge where
clean_ofalls - The testbench drives a long rattle in which no value holds for 8 samples, and checks that no output moves
- The testbench holds the opposite value for exactly 7 samples, on both sides, and checks
clean_odoes not move - The testbench holds the contact closed for exactly 8 samples, then opens it, and checks the rise and the fall both land on schedule
- The testbench checks
pressed_oandreleased_oreturn low exactly 1 cycle after they rise - The testbench asserts
rst_imid-rattle whileclean_ois high and checks all three outputs drop with noreleased_opulse - The testbench keeps
raw_ihigh through that reset and checkspressed_ofires on the 10th edge afterrst_igoes low - The testbench asserts
rst_ion the exact edge whereclean_owould rise and checks that no rise and no pulse happen
Constraints
TIMING: everything is synchronous to
clk_i; all outputs are registered.
SCOPE: this models the debouncer between the bouncy contact and the pinsetter controller. The button's mechanics and the pinsetter machine are out of scope.
SYNCHRONIZER:
raw_imust pass through 2 flip-flops before any other logic reads it. The bench's edge counts include this 2-cycle lag, so a skipped stage fails the timing checks.
Do not add ports.
Click Run to execute your code. Output will appear here.