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 through 2 flip-flops first, because the contact is not lined up with clk. Then filter it: clean may take a new value only after the contact has held that value for 8 samples in a row. Pulse pressed high for 1 cycle when clean rises. Pulse released high for 1 cycle when clean falls.

Interface

PortDirectionTypeDescription
clkin1 bitSystem clock
rstin1 bitSynchronous reset (active high)
rawin1 bitRaw contact from the button, bouncy
cleanout1 bitDebounced button level
pressedout1 bitOne-cycle pulse when clean rises
releasedout1 bitOne-cycle pulse when clean falls

Behavior

  • After reset, clean is low: the block treats the button as not pressed
  • The block samples raw at every rising edge of clk
  • raw passes 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
  • When a run reaches 8 samples, clean takes the run's value at the 2nd rising edge after the edge with the 8th sample
  • One sample equal to clean ends the run; the count starts over at 0
  • A run of 7 or fewer samples never changes clean, no matter how many such runs arrive
  • pressed is high for exactly the 1 cycle on which clean rises, and low at all other times
  • released is high for exactly the 1 cycle on which clean falls, and low at all other times
  • rst high at a rising clock edge forces clean, pressed, and released low from that edge
  • Reset fires no pulse: released stays low even when reset drops a high clean
  • 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, pressed, and released on every cycle of every scenario
  • The testbench drives a press as a bounce burst that settles high, and checks the exact edge where clean rises
  • The testbench drives a release as a bounce burst that settles low, and checks the exact edge where clean falls
  • 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 does 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 and released return low exactly 1 cycle after they rise
  • The testbench asserts rst mid-rattle while clean is high and checks all three outputs drop with no released pulse
  • The testbench keeps raw high through that reset and checks pressed fires on the 10th edge after rst goes low
  • The testbench asserts rst on the exact edge where clean would rise and checks that no rise and no pulse happen

Constraints

TIMING

everything is synchronous to clk; 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 must 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.

Loading editor...

Click Run to execute your code. Output will appear here.