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

PortDirectionTypeDescription
clk_iin1 bitPixel clock
rst_iin1 bitSynchronous reset (active high)
s_valid_iin1 bitCamera side: word offered
s_data_iin8-bit vectorCamera side: pixel word
s_ready_oout1 bitCamera side: word will be accepted (registered)
m_valid_oout1 bitGrader side: word available (registered)
m_data_oout8-bit vectorGrader side: pixel word (registered)
m_ready_iin1 bitGrader 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_o during a cycle reflects the occupancy after the previous edge: high exactly when fewer than two words are held
  • With the buffer empty, s_ready_o is high regardless of m_ready_i
  • m_valid_o is high exactly when at least one word is held; m_data_o presents 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_i and m_ready_i both 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_o returns high on the cycle after a word drains
  • rst_i = 1 at a rising edge empties the buffer: m_valid_o low, s_ready_o high from the next cycle; words in flight are discarded

What the bench checks

  • The testbench checks s_ready_o, m_valid_o, and m_data_o against 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 from m_ready_i or s_valid_i to 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.

Loading editor...

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