A producer holds the offered item during a stall and transfers it only when the consumer votes ready.
A producer holds the offered item during a stall and transfers it only when the consumer votes ready.
Getting two stages to agree
Imagine an assembly line. A producer might have a part ready, but the next guy in line is busy. If they don't communicate, parts drop on the floor. Hardware solves this with a simple two-wire contract:
The producer controls the valid wire and the data payload itself.
The consumer controls the ready wire.
A transfer occurs only on a clock edge where valid and ready are both one.
Worked example
Surviving a two-cycle stall
Let's say the producer is holding a part (valid = 1), but the consumer drops ready = 0 for clock cycles 2 and 3. No transfer happens. The producer is stuck holding the bag. It absolutely must keep valid = 1 and keep the payload steady. When the consumer finally asserts ready = 1 in cycle 4, the part transfers successfully, and the pipeline starts moving again.
Wait, can ready be high even if valid is low?
Absolutely. It just means the consumer is sitting there saying, "I have space, send me something!" It doesn't mean data is actually moving. Keeping the signals completely independent lets both sides report their true status without accidentally triggering a ghost transfer.
Check your understanding
If you are the producer, what is your job while valid = 1 and ready = 0?
Section summary
- A transfer is a handshake: it only happens when both valid and ready are high.
- ready is how the consumer applies backpressure to slow things down.
- If you get stalled, you have to hold your data stable until the stall clears.
Change downstream stalls and latency while watching offers, transfers, accepted order, and completion order.
Runs entirely in this browser. Python executes in Pyodide WebAssembly with no remote kernel. The construction code stays visible while reactive dependents recompute whenever you change an input.
Repository layer · second pass
What promise does valid/ready make under backpressure?
A transfer occurs on an edge only when valid and ready are both high. The producer owns valid and payload; once it offers an item, it must keep both stable until accepted. The consumer owns ready and may stall without losing or duplicating the offered item.
The protocol is local, but pipelines compose only when every stage preserves it. Stall tests must hold ready low for unpredictable durations while checking payload stability, ordering, and exactly-once transfer.
Reasoning chain
- 1
Identify producer and consumer.
- 2
Define transfer=valid∧ready.
- 3
Hold offered payload while stalled.
- 4
Advance producer state only on transfer.
- 5
Propagate backpressure without combinational cycles.
- 6
Use a scoreboard under randomized stalls.
Worked trace
A two-cycle stall
- Cycle 1: valid=1,ready=0,payload=A.
- Cycle 2 remains stalled; A must remain.
- Cycle 3 ready rises; A transfers at the edge.
- Only afterward may producer present B.
Result. A is neither dropped nor counted twice.
Executable lens · Python
Make the hidden state visible
def transfers(valid, ready):
return [cycle for cycle,(v,r) in enumerate(zip(valid,ready)) if v and r]
assert transfers([0,1,1,1,1],[1,0,0,1,1]) == [3,4]Retype this example, predict each intermediate value, and then change one input that touches a boundary.
Misconception clinic
Tempting mistakes
- Pulsing valid for one cycle regardless of ready.
- Changing payload while valid remains high and ready is low.
Retrieval and transfer
Close the book first
- Write protocol assertions for stability and transfer count.
- Trace simultaneous dequeue and enqueue.
- Explain how an elastic buffer breaks a ready critical path.