Practice

Storage Gate Scan

The entry gate at the BoxBarn self-storage yard reads a 16-key pad wired as a 4-by-4 matrix: 4 row wires, 4 column wires, a key at each crossing. A pressed key connects its row to its column. The scanner finds keys by driving one row at a time and reading which columns answer.

It is the cheapest pad on the market, and that brings two problems. First, the pad connects through 15 m of ribbon cable. After the scanner drives a new row, the column lines need a full cycle to settle before they mean anything. Second, the pad has no diodes behind the keys. When 3 pressed keys form an L shape in the matrix, current sneaks around the corner. A 4th crossing appears: a phantom key that no finger is on.

The old scanner card ignored both problems. It sampled the columns in the same cycle it moved the row, so it read the previous row's echo. And it trusted phantoms: a customer in winter gloves once pressed 3 keys at once, and a digit nobody entered went into the gate code. Entering 3 wrong codes locks the account until morning.

Your task: build the replacement. Scan on the fixed schedule below, count every crossing a sweep sees, and report a key only when the total is exactly 1. A phantom is electrically identical to a real key, so a sweep that sees more than one crossing reports nothing.

Interface

PortDirectionTypeDescription
clkin1 bitClock
rstin1 bitSynchronous reset (active high)
colsin4-bit vectorColumn returns, valid one cycle after a row settles
rowsout4-bit vectorRow drive, one-hot active high, registered decode
keyout4-bit vectorLast reported key code, row * 4 + column, registered
validout1 bitOne-cycle pulse: the finished sweep saw exactly one key

Behavior

  • After a reset edge the scan starts at row 0: rows = 0001 for two cycles, then 0010 for two, then 0100, then 1000, then back to row 0
  • The sweep is 8 cycles long and repeats forever
  • For each row, the first cycle is settle time. cols is sampled only at the rising edge that ends the row's second cycle
  • Whatever cols bits are high at that sample count as crossings on that row
  • Crossings accumulate across the sweep's four samples
  • At the edge that ends the sweep (the same edge as row 3's sample), a total of exactly one crossing sets valid high for the following cycle
  • That same edge loads key with the crossing's code, row * 4 + column
  • A sweep totaling zero crossings, or two or more (real or phantom), produces no pulse and leaves key unchanged
  • key holds its last reported code between pulses (0 after reset); downstream reads it with valid, but the hold is part of the contract
  • A key held down reports once per sweep, every sweep
  • Three pressed keys forming an L produce a fourth phantom crossing in the matrix model, exactly as the diode-less pad does. Such sweeps see four crossings and must report nothing
  • rst = 1 at any rising edge abandons the sweep in progress: the count clears, valid drops, key clears to 0, and scanning restarts at row 0

What the bench checks

  • The testbench's matrix is registered: cols during any cycle reflects the row drive of the previous cycle
  • The testbench checks rows, valid, and key on every cycle; key must hold its last reported code between pulses
  • The testbench drives empty sweeps, single keys held across sweeps (including both corner keys), two keys sharing a row, and two sharing a column
  • It also drives the L-shaped phantom trio, a key pressed after its row already went by in the current sweep, and a reset mid-sweep

Constraints

TIMING

everything is synchronous to clk; rows, key and valid change only at clock edges.

SCOPE

this models the scanner against a matrix model with settle delay and diode-less phantoms. The gate lock, the entry codes, and the cable's true analog behavior are out of scope.

SCAN SCHEDULE

the two-cycle row dwell and the sample-on-the-second-edge rule are load-bearing. The matrix model answers late, exactly like the real ribbon cable.

Do not add ports. Do not try to identify which of several keys is real: at the electrical level the phantom is real. That is why multi-key sweeps report nothing.

Loading editor...

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