Practice
Board Scanner Skid
The grading scanner at the Hallberg sawmill photographs every board coming off the saws. A camera sits over the conveyor, and the grading PC sits 15 m away. A link between them carries one pixel word per clock, using a valid/ready handshake: a word moves only on a cycle where valid and ready are both high. Then the mill sped up the pixel clock. The ready signal could no longer make the 15 m trip back in one cycle, so it now passes through a register on the way. The camera therefore sees ready one cycle late.
That one late cycle got patched twice. On every stall the camera pushes one word into a closed door. The vendor's temporary firmware simply drops that word, and the graders have been chasing phantom knots (defects that are not there) for a month. The second patch held ready low every other cycle; at half throughput the scanner fell behind the saws.
Your task: both patches come out, and your block goes in at the camera side. It is a 2-word buffer, the classic skid buffer. Accept a word whenever there is room, deliver words to the grader in order, and never drop or duplicate one.
Interface
| Port | Direction | Type | Description |
|---|---|---|---|
clk_i | in | 1 bit | Pixel clock |
rst_i | in | 1 bit | Synchronous reset (active high) |
s_valid_i | in | 1 bit | Camera side: word offered |
s_data_i | in | 8-bit vector | Camera side: pixel word |
s_ready_o | out | 1 bit | Camera side: word will be accepted (registered) |
m_valid_o | out | 1 bit | Grader side: word available (registered) |
m_data_o | out | 8-bit vector | Grader side: pixel word (registered) |
m_ready_i | in | 1 bit | Grader side: word taken this cycle |
Behavior
- A transfer happens on each side on any rising edge where that side's valid and ready are both high
- The buffer holds at most two words: an output word (presented on
m_valid_o/m_data_o) and one skid word behind it s_ready_oduring a cycle reflects the occupancy after the previous edge: high exactly when fewer than two words are held- With the buffer empty,
s_ready_ois high regardless ofm_ready_i m_valid_ois high exactly when at least one word is held;m_data_opresents the oldest word and holds it steady until the grader takes it- Accepted words come out in order, exactly once each: no drops, no duplicates
- Zero bubble: with
s_valid_iandm_ready_iboth held high, a word is accepted and a word is delivered on every edge - A word arriving into an empty buffer is presented on the very next cycle
- After a full stall (both slots occupied),
s_ready_oreturns high on the cycle after a word drains rst_i = 1at a rising edge empties the buffer:m_valid_olow,s_ready_ohigh from the next cycle; words in flight are discarded
What the bench checks
- The testbench checks
s_ready_o,m_valid_o, andm_data_oagainst a reference model on every cycle - It verifies that an empty buffer stays ready even while the downstream side is stalled
- Single words and a ten-word full-rate burst must pass in order without bubbles
- Directed stalls fill both slots, refuse a third word, hold data steady, and exercise simultaneous input and output transfers
- A 150-cycle request and stall storm is compared with the same two-slot queue model
- Reset with both slots full must discard the stored words, restore ready, and allow traffic to resume
Constraints
TIMING: everything is synchronous to
clk_i, and all three outputs are registered. There is no combinational path fromm_ready_iors_valid_ito any output.
SCOPE: this models the camera-side skid buffer alone. The camera, the grading PC, and the 15 m link's electrical behavior are out of scope.
CAPACITY: two storage slots is the whole buffer. The point of the exercise is full throughput with a registered
s_ready_o, not a deeper FIFO.
Do not add ports.
Click Run to execute your code. Output will appear here.