Practice
Fertigation Frame Guard
Vela Growers runs a fertigation system: a computer doses fertilizer and acid into the greenhouse irrigation water. Recipe frames travel to the dosing engine over 300 m of noisy serial cable, past 200 lamp igniters. Last April a corrupted frame told the acid pump to run 9 times longer than intended. The dosing hardware obeyed, and the acid overdose killed three rows of seedlings. The corrective action lands on your desk.
Two habits of the sending computer matter. Its watchdog restarts transmissions in the middle of anything. And every few seconds it sends a heartbeat: a frame with LEN of 0. The old guard prototype locked up on the first heartbeat of the season. That is why the greenhouse still runs unguarded.
Your task: build a guard block between the line decoder and the dosing engine, so that no frame reaches the engine without the guard's approval. The decoder hands you the framing: sof_i pulses at the start of a frame, and dv_i pulses once for each received byte on d_i. Check each frame's checksum as the bytes stream past. Pulse one verdict per frame: ok_o when the sum matches, bad_o when it does not.
Interface
| Port | Direction | Type | Description |
|---|---|---|---|
clk_i | in | 1 bit | Clock |
rst_i | in | 1 bit | Synchronous reset (active high) |
sof_i | in | 1 bit | Start-of-frame marker, 1 cycle wide |
dv_i | in | 1 bit | Byte strobe, 1 cycle wide per byte |
d_i | in | 8-bit vector | Decoded byte from the line |
ok_o | out | 1 bit | Frame verdict good, 1-cycle pulse (registered) |
bad_o | out | 1 bit | Frame verdict corrupt, 1-cycle pulse (registered) |
Behavior
- After
sof_i, the firstdv_ibyte isLEN, the nextLENdv_ibytes are payload, and the followingdv_ibyte is the checksum - The checksum is valid when it equals
(LEN + sum of payload bytes) mod 256; the length byte is inside the sum - The cycle after the checksum byte is sampled, exactly one of
ok_oorbad_opulses for exactly one cycle; both are 0 at all other times LEN = 0is legal (heartbeat): the checksum byte follows the length byte directly and must equalLEN- An
sof_iat any point abandons the frame in progress with no verdict and starts a fresh frame - Nothing from the abandoned frame may leak into the new frame's sum
- A
dv_icoinciding withsof_iis ignored: the byte belongs to the marker, and the nextdv_ibyte is the new frame'sLEN dv_ibytes outside any frame are ignored; gaps of any length between bytes are legal- A new
sof_imay arrive on the very cycle a verdict pulses rst_i = 1at a rising edge returns the guard to idle, verdict pulses low, frame in progress forgotten
What the bench checks
- The testbench checks
ok_oandbad_oon every cycle - Good and bad frames verify that the checksum includes
LENand that each verdict lasts one cycle - Valid frames cover arbitrary gaps, zero-length heartbeats, and an eight-byte payload
- Wrapped checksum sums are accepted modulo 256, while an off-by-one checksum after the wrap is rejected
- A new
sof_imid-payload or where a checksum was expected must abandon the old frame without a verdict - A byte arriving with
sof_iand stray bytes outside a frame must be ignored - Reset mid-frame must cancel it, and a new
sof_iduring a verdict pulse must start the next frame cleanly
Constraints
TIMING: everything is synchronous to
clk_i;ok_oandbad_oare registered one-cycle pulses.
SCOPE: this models the checksum guard between decoder and dosing engine. The line decoder, the noisy cable, and the dosing hardware are out of scope; framing arrives ready-made on
sof_ianddv_i.
STREAMING: do not buffer whole frames.
LENcan be up to 255, and the guard must judge the stream as it flows.
Do not add ports.
Click Run to execute your code. Output will appear here.