← Protocols Interviews

Interview Question · Design

Registering Ready Without Losing Beats

L2 Mid-LevelL3 Seniorhandshakepipeliningtiming

The Question

The interviewer asks

Timing fails on the ready path through a chain of pipeline stages. A colleague registers ready in each stage. What breaks, and what do you build instead?

Reveal the Model Answer

A registered ready tells the stage about a stall one edge late. So the stage accepts a beat it has nowhere to put, and overwrites one. A slice that accepts only when empty is safe but halves throughput. The fix is a skid buffer: a second register that catches the one beat in flight when the stall arrives. It gives registered ready at full rate, for roughly twice the flops.

A Registered Ready and No Room for the Extra BeatThe producer offers beats 1 to 6. The consumer drops out_ready for edge 5 only. Each column shows the values just before an edge, which decide what moves at it.
012345678910clkin_validin_data01234567in_readyout_validout_datax123456out_ready
  1. Cycle 4

    Steady flow: beat 3 enters while beat 2 leaves. One beat per edge.

  2. Cycle 5

    The consumer stops, so beat 3 must stay. But in_ready is still 1, copied from the edge before, and beat 4 comes in.

  3. Cycle 6

    Beat 4 sits where beat 3 was. Beat 3 is gone. Only now does in_ready show the stall.

  4. Cycle 9

    Beats 1, 2, 4, 5 and 6 came out: six in, five out.

Measured on the lab bench. The consumer stopped for one edge; the stage heard about it one edge later.

A Stage with a Skid RegisterArrows carry beats, except in_ready and out_ready, which carry the ready flags. in_ready is !skid_valid, a flop output.
A stage with a skid registerArrows carry beats, except `in_ready` and `out_ready`, which carry the ready flags. `in_ready` is `!skid_valid`, a flop output. source producer offers a beat until itis taken flop skid register skid_valid, skid_data flop main register out_valid, out_data sink consumer drops out_ready tostall beat, normal flowbeat during a stalldrainbeat outout_readyin_ready = !skid_valid
  1. Normal flow

    With the skid empty, a beat goes straight into the main register while the previous beat leaves.

    Follow the calls, values and waits
    1. data beat 3: producer → main register
  2. The stall

    The consumer drops out_ready, so beat 3 stays in the main register. in_ready is still 1, and beat 4 arrives.

    Follow the calls, values and waits
    1. call out_ready 0: consumer → main register
    2. data beat 4: producer → skid register
  3. Ready falls

    The skid is full, so in_ready is 0 from the next edge. The producer holds beat 5.

    Follow the calls, values and waits
    1. call in_ready 0: skid register → producer
  4. Drain

    The consumer takes beat 3. At the same edge beat 4 moves from the skid into the main register, so order is kept, and in_ready returns.

    Follow the calls, values and waits
    1. data beat 3: main register → consumer
    2. data beat 4: skid register → main register
Read the diagram as text
  • producer: offers a beat until it is taken
  • skid register: skid_valid, skid_data
  • main register: out_valid, out_data
  • consumer: drops out_ready to stall
  • producer → main register: beat, normal flow
  • producer → skid register: beat during a stall
  • skid register → main register: drain
  • main register → consumer: beat out
  • consumer → main register: out_ready
  • skid register → producer: in_ready = !skid_valid

The stage holds up to two beats, and no combinational path runs through it from out_ready to in_ready.

Stage styleBeats out of 8Last beat at cycleready path
Registered ready, one register6 (2 overwritten)-from a flop
Accept only when empty818from a flop
Skid buffer (two registers)813from a flop

Measured by the run on this question: the consumer stalls one cycle in every four.

RUNIcarus Verilog · in your browser
Edit the code, then run it
Expected: registered ready: in 8, out 6, mismatched 4 half-rate slice: in 8, out 8, mismatched 0, last beat at cycle 18 skid buffer: in 8, out 8, mismatched 0, last beat at cycle 13 FAIL: registering ready lost 2 of 8 beats

Self-Check

Tick each key point you covered in your answer.

What Interviewers Listen For (Mid-Level)

A good mid-level answer explains that a registered ready reports the stall one edge late. It draws the skid buffer with its two registers.

Cross-Questions

Where the interviewer goes next. Open a node to practise that follow-up.

WhyProve ItBreak ItCompareScale It

  1. Registering Ready Without Losing Beats
  2. WhyReady as a Function of ValidL2 Mid-LevelL3 Senior

    If the sink may wait for valid, may it compute ready combinationally from valid in the same cycle?

    Reveal the Model Answer

    Inside one block, a same-cycle ready = f(valid) works logically. But on an AXI interface, the spec forbids combinational paths from inputs to outputs. So the wait goes through a register, and ready rises the cycle after valid is seen. The rule stops timing paths from chaining across blocks. A combinational ready path would grow with every stage.

    Self-Check

    Tick each key point you covered in your answer.

    What Interviewers Listen For (Mid-Level)

    A good mid-level answer knows that AXI bans a combinational path from an input to an output on an interface.

    Spec Misquote

    "Waiting for valid means ready can be assign ready = valid && !full; at the port."

    That is an input-to-output combinational path at the interface, which AXI forbids. Register it, or decouple it with a slice.

    Source AMBA AXI Protocol Specification IHI 0022L §A2.1.1 Clock

  3. Prove ItSolve R4.4.1: A Skid BufferSimulator-graded

    Show it, don't just say it: this Silicon Lab problem is graded by the simulator.

    Open Problem R4.4.1

  4. Break ItTwo Blocks That Close a Combinational LoopL2 Mid-LevelL3 Senior

    Break it: one block makes valid from ready, and its neighbour makes ready from valid, both in the same cycle. What happens?

    Reveal the Model Answer

    The two paths close a combinational loop through both blocks. Simulation can oscillate or hang in zero time, and timing tools cut the loop at a random point. AXI rules both halves out. A transmitter must not wait for READY before it asserts VALID, and no input may reach an output combinationally.

    Self-Check

    Tick each key point you covered in your answer.

    Missed Corner

    "Each block is fine on its own, so the pair is fine."

    The loop exists only when they connect. Check each interface rule at the block, or the loop appears at integration.

    Source AMBA AXI Protocol Specification IHI 0022L §A2.1.1 Clock

  5. CompareSkid Buffer or Two-Entry FIFOL2 Mid-Level

    Isn't a skid buffer just a two-entry FIFO? Why not drop in the FIFO from the library?

    Reveal the Model Answer

    Functionally, it is a two-entry FIFO with registered ready. The library FIFO is a fine choice if two things hold. Its ready (not-full) must come from a flop. It must also pass data through without an extra cycle when empty. FIFO designs differ on both, so check them: a not-full computed from the pop brings back the combinational path.

    Self-Check

    Tick each key point you covered in your answer.

    What Interviewers Listen For (Mid-Level)

    A good mid-level answer names the two things to check in a library FIFO. Its not-full must come from a flop, and an empty FIFO must not add a cycle.

  6. Scale ItSlices, Latency and Outstanding RequestsL3 Senior

    You add four register slices on the request and response paths of a memory link. What else must change to keep bandwidth?

    Reveal the Model Answer

    Each slice adds a cycle to the round trip, so the requester must keep more requests outstanding. Throughput is roughly outstanding requests divided by round-trip latency. Re-check the initiator's outstanding limit, ID or tag count, and response buffering. Otherwise the link that met timing now runs slower. Slices on one AXI channel need not match those on another.

    Self-Check

    Tick each key point you covered in your answer.

    What Interviewers Listen For (Senior)

    A good senior answer links the number of slices to how many requests must be in flight and to buffer sizes. It does not treat slices as only a timing fix.

  7. Prove ItSolve R4.4.1: A Skid BufferSimulator-graded

    Show it, don't just say it: this Silicon Lab problem is graded by the simulator.

    Open Problem R4.4.1

What People Get Wrong

Common wrong answers and why they fail. Run It shows the wrong belief failing on a real simulator.

Misconception

"Registering ready just adds a cycle of latency."

It changes behaviour. The stage takes one beat after the stall begins, with no room for it. The run loses 2 of 8 beats.

Run It
RUNIcarus Verilog · in your browser
Edit the code, then run it
Expected: registered ready: in 8, out 6, mismatched 4 half-rate slice: in 8, out 8, mismatched 0, last beat at cycle 18 skid buffer: in 8, out 8, mismatched 0, last beat at cycle 13 FAIL: registering ready lost 2 of 8 beats

Half-Truth

"Use in_ready = !out_valid and you are done."

Safe, but a stage that accepts only when empty moves at most one beat every two cycles. In the run, 8 beats take 18 cycles instead of 13.

Learn It, Then Prove It