Practice

Loft Clock Wire

A pigeon racing club times every returning bird with an electronic loft clock. When a bird lands, the clock stamps its ring number and arrival time. It sends each stamp, one byte at a time, over a serial wire to the logger in the clubhouse.

The old clock's transmitter board was built wrong. It sent every byte highest bit first. UART receivers expect the lowest bit first, so the logger recorded garbage ring numbers. Two race results were voided before anyone traced the fault.

Your task: build the clock's UART transmitter. When send pulses while the line is idle, capture the byte on data. Then drive tx with a start bit, the 8 data bits lowest bit first, and a stop bit, each lasting 8 clock cycles. Hold busy high while the frame is on the wire, and ignore send until the frame is done.

Interface

PortDirectionTypeDescription
clkin1 bitSystem clock
rstin1 bitSynchronous reset (active high)
sendin1 bitTransmit request (one-cycle pulse)
datain8-bit vectorByte to transmit
txout1 bitSerial line to the logger (idle high)
busyout1 bitHigh while a frame is on the wire

Behavior

  • When idle, tx is high and busy is low
  • While idle, send high at a rising clock edge accepts the byte on data: busy rises and the start bit begins on that same edge
  • Cycle numbering: cycle 0 is the first full cycle with busy high
  • A frame is 10 bits: a start bit 0, the 8 data bits LSB first (bit 0 of the byte first), and a stop bit 1
  • Each bit lasts exactly 8 clock cycles: the baud divisor is fixed, not a parameter
  • tx drives the start bit during cycles 0 to 7 and the stop bit during cycles 72 to 79
  • Data bit 0 is on the wire during cycles 8 to 15
  • Each next data bit takes the next 8 cycles, ending with data bit 7 during cycles 64 to 71
  • At cycle 80 the frame is over: busy returns low and tx stays high
  • busy is high during cycles 0 through 79 and low at every other time
  • The byte is captured when send is accepted; later changes on data do not affect the frame
  • A send pulse while busy is high is ignored: nothing is queued and nothing extra is sent later
  • send high during the first idle cycle after a frame begins a new frame on the next cycle
  • rst = 1 at a rising clock edge cancels any frame: tx returns high and busy low on the next cycle

What the bench checks

  • The testbench checks tx and busy against the fixed timeline on every cycle of every frame
  • The testbench decodes the wire like a receiver: it samples each data bit mid-slot and compares the rebuilt byte
  • The testbench sends byte values that expose reversed bit order, a missing start bit, and a broken stop bit
  • The testbench changes data right after acceptance and checks the wire still carries the captured byte
  • The testbench pulses send with a decoy byte in the middle of one frame and checks that no extra frame follows
  • The testbench pulses send with a decoy byte on the last busy cycle of one frame and checks the line stays idle after it
  • The testbench starts one frame with send high during the first idle cycle after the previous frame
  • The testbench asserts rst in the middle of one frame and checks tx and busy are idle on the next cycle

Constraints

TIMING

everything is synchronous to clk; all outputs are registered.

SCOPE

this models the transmitter side of the wire at a fixed 8-cycle bit time. The ring reading, the time stamping, and the logger's receiver are out of scope.

Do not add ports.

Loading editor...

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