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_i pulses while the line is idle, capture the byte on data_i. Then drive tx_o with a start bit, the 8 data bits lowest bit first, and a stop bit, each lasting 8 clock cycles. Hold busy_o high while the frame is on the wire, and ignore send_i until the frame is done.
Interface
| Port | Direction | Type | Description |
|---|---|---|---|
clk_i | in | 1 bit | System clock |
rst_i | in | 1 bit | Synchronous reset (active high) |
send_i | in | 1 bit | Transmit request (one-cycle pulse) |
data_i | in | 8-bit vector | Byte to transmit |
tx_o | out | 1 bit | Serial line to the logger (idle high) |
busy_o | out | 1 bit | High while a frame is on the wire |
Behavior
- When idle,
tx_ois high andbusy_ois low - While idle,
send_ihigh at a rising clock edge accepts the byte ondata_i:busy_orises and the start bit begins on that same edge - Cycle numbering: cycle 0 is the first full cycle with
busy_ohigh - A frame is 10 bits: a start bit
0, the 8 data bits LSB first (bit 0 of the byte first), and a stop bit1 - Each bit lasts exactly 8 clock cycles: the baud divisor is fixed, not a parameter
tx_odrives 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_oreturns low andtx_ostays high busy_ois high during cycles 0 through 79 and low at every other time- The byte is captured when
send_iis accepted; later changes ondata_ido not affect the frame - A
send_ipulse whilebusy_ois high is ignored: nothing is queued and nothing extra is sent later send_ihigh during the first idle cycle after a frame begins a new frame on the next cyclerst_i = 1at a rising clock edge cancels any frame:tx_oreturns high andbusy_olow on the next cycle
What the bench checks
- The testbench checks
tx_oandbusy_oagainst 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_iright after acceptance and checks the wire still carries the captured byte - The testbench pulses
send_iwith a decoy byte in the middle of one frame and checks that no extra frame follows - The testbench pulses
send_iwith 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_ihigh during the first idle cycle after the previous frame - The testbench asserts
rst_iin the middle of one frame and checkstx_oandbusy_oare idle on the next cycle
Constraints
TIMING: everything is synchronous to
clk_i; 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.
Click Run to execute your code. Output will appear here.