Practice

Market Sign LED Chain

St Jude's covered market hung a two-lamp smart sign above its fish entrance. Each lamp held one chip, and data passed through both on one wire.

The colors looked right for one frame. Then each update slid them one lamp farther down the chain. The controller left too little low time between frames.

The chips never latched, so each new frame pushed the old bits farther along. Soon the red and green lamps traded places after every update.

Your task: build a sender with exact pulse widths and a real latch gap. Send both lamp colors in order, then hold the wire low long enough.

Interface

PortDirectionTypeDescription
clkin1 bit20 MHz clock, 50 ns per clock
rstin1 bitSynchronous reset (active high)
startin1 bitSend one frame
rgb0in24-bit vectorFirst lamp color, red in bits 23..16, green in 15..8, and blue in 7..0
rgb1in24-bit vectorSecond lamp color, red in bits 23..16, green in 15..8, and blue in 7..0
dinout1 bitChain data wire, idle low, registered
busyout1 bitHigh while a frame runs, registered
doneout1 bitOne-clock pulse on the frame's final gap clock, registered

Behavior

  • start is honored only while the sender sits idle, and the accepted frame begins on the following clock
  • Acceptance takes a snapshot of both color inputs
  • A running frame keeps that snapshot even if rgb0 or rgb1 change beneath it
  • A busy sender pays no attention to new start assertions
  • busy goes high at acceptance and remains high through the final latch-gap clock
  • Each lamp contributes 24 bits in green, red, then blue byte order
  • Within every byte, the most significant bit is sent first
  • The 24 bits from rgb0 are sent first, followed by the 24 bits from rgb1
  • Every bit occupies exactly 25 clocks
  • A zero bit drives din high for exactly 8 clocks, then low for exactly 17 clocks
  • A one bit drives din high for exactly 16 clocks, then low for exactly 9 clocks
  • All 48 bits are sent back to back with no extra clocks between them
  • After the 48th bit, din remains low for exactly 1000 clocks, which is 50 us
  • done pulses exactly once, on the final clock of the 1000-clock latch gap
  • busy remains high during the done pulse
  • On the next clock, busy and done fall together, and the unit becomes idle
  • While idle, din, busy, and done are low
  • rst high at any rising edge drives all outputs low, returns the unit to idle, and cancels all frame progress
  • No cancelled frame resumes after reset

What the bench checks

  • A decoder plays the two chips: it measures every high run in clocks, classifies all 48 bits, and maps them back to each lamp's color
  • Pulse widths are exact: a high run of anything but 8 or 16 clocks fails, as does a low remainder of anything but 17 or 9
  • The latch gap is counted to the clock: a frame that ends before 1000 low clocks is called out as the colors sliding down the chain
  • Both color inputs switch to decoys one clock after acceptance, so a frame built from live inputs decodes wrong
  • Extra start pulses land mid-bit, deep in the gap, and on the final gap clock, and none may leave a mark
  • It asserts reset during a high pulse, a low remainder, and the latch gap
  • After every reset it expects the wire low on the very next clock and no cancelled frame resuming

Constraints

TIMING

everything is synchronous to the 20 MHz clk; inputs are sampled on rising edges, and all outputs are registered.

SCOPE

this models the data wire's digital pulse train at exact clock counts; the chips' analog thresholds, supply, and color mixing are out of scope.

Do not add ports.

Loading editor...

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