Answer each question out loud before opening it. If you miss more than three in the checkpoint, revisit the lessons linked at the end.
When the consumer can accept a word every cycle at the producer's peak rate, or a FIFO sized for the worst burst sits in front of a consumer whose average rate is higher, or when data may be dropped. Otherwise words are lost silently.
Valid rises with word A; ready low for two cycles while valid and A hold; ready high: A moves on that edge. A transfer is an edge with both high; the producer holds valid and data until it happens.
Ready may depend on valid; valid must not depend on ready. Otherwise two compliant blocks can deadlock, and both paths together would form a combinational loop.
Each handshake step waits for a synchroniser; two-phase needs one round trip per word instead of four-phase's two, roughly doubling the rate. Only req and ack are synchronised; data is held stable.
A global stall must reach every register within one cycle; its fan-out and reach grow with depth and width until it is the critical path. Elastic handshakes keep each decision local.
A slice that registers ready with a spare entry, a skid buffer. A bare flip-flop on ready loses one word per stall.
With ready registered, exactly one extra word arrives after a stall begins; the spare entry catches it, and the output never empties, so throughput stays full.
A one-entry stage with in_ready = !full refuses while emptying; valid and ready toggle in opposite phase. Fix: in_ready = !full || out_ready, or a skid buffer.
Task. A 2 mm on-chip route between two blocks needs three register stages to close timing on both the data and the ready paths. The channel must run at one word per cycle. Draw the design, say what each stage is, and give its total storage and latency.
Both paths fail, so each stage must cut valid, data and ready: three full slices, that is three skid buffers in a row. Each has an output register and a spare entry, so six entries of storage, and each adds one cycle of data latency: three cycles. Each skid buffer accepts while emptying, so throughput stays at one word per cycle. If only the data path failed, three forward slices (one entry each, combinational ready) would do with half the storage, but the ready path would then run combinationally through all three.
Data arriving faster than a receiver with no back-pressure can accept it; the excess is lost silently.
One transfer at a time: while a target holds its transfer open, nothing else can start.
On a rising edge where valid and ready are both high.
valid && !ready |=> valid && $stable(data): a stalled word must stay unchanged.
Four: req up, ack up, req down, ack down.
Pull in disguise: the consumer grants permission for each slot in advance.
It cuts valid and data; ready still passes through combinationally.
Three.
Its valid and ready toggle in opposite phase every cycle with no stall downstream.
Throughput is at most items in flight divided by loop latency; added stages raise the latency.