Draft preview. Lessons are being written and reviewed.

Digital Design / Module 7: Memories and FIFOs

43. Valid/ready handshakes

Build backpressure that doesn't lose data.

Lecture coming soon

See it move

The idea

When two blocks exchange data, each may need to pause. A valid/ready handshake handles this with two signals:

  • valid from the sender means "the data is good".
  • ready from the receiver means "I can take it".

A transfer happens on a clock edge if and only if both are high. If either is low, nothing moves.

The rules

  • Once valid goes high, it must stay high, with data unchanged, until the transfer happens.
  • Valid must not depend combinationally on ready. Ready may depend on valid, but avoiding that too is cleaner.
  • Ready may rise and fall freely if no transfer is pending.

Breaking the first rule can lose or corrupt data. Breaking the second can create a combinational loop if both sides make the same assumption. AXI uses this handshake on all its channels.

A one-stage pipeline register

assign in_ready = !out_valid || out_ready;

always_ff @(posedge clk)
  if (rst)
    out_valid <= 1'b0;
  else if (in_ready) begin
    out_valid <= in_valid;
    if (in_valid) out_data <= in_data;
  end

The stage accepts new data if it is empty, or if its current word is leaving in this very cycle.

Throughput and timing

This design runs at full , but in_ready depends combinationally on out_ready. Chain many stages, and a long ready path forms all the way back through the . The lesson cuts that path.

Common mistake

Asserting ready only after seeing valid, and asserting valid only after seeing ready. Each waits for the other, so nothing ever happens. Make sure the rules allow at least one side to act first. Look at the animation above: if ready is seen a cycle late with no spare storage, words vanish.

Key ideas

  • Transfer happens only when both valid and ready are high.
  • Don't make valid depend combinationally on ready.
  • Hold data stable until the transfer.

Your exercise

Write a one-stage valid/ready pipeline register.

Find the bug

This code has one deliberate bug. Read the symptom, then click the line you think is wrong.

What goes wrong: With no stalls everything works. If out_ready goes low, words disappear.

Interview questions

coreMay valid drop before a transfer?

basicIn a valid/ready handshake, when exactly does a word transfer?

basicA sender has three words and holds valid high from cycle 1. The receiver's ready over cycles 1 to 6 is 0, 1, 0, 1, 1, 1. In which cycles do the words transfer?

coreThis sender keeps valid high and steps its data every cycle. What goes wrong when the receiver applies backpressure?

always @(posedge clk)
  if (rst) begin valid <= 0; data <= 0; end
  else begin
    valid <= 1'b1;
    data  <= data + 1;  // ignores ready
  end

coreWhy must valid not depend combinationally on ready?

coreA receiver raises ready only after it sees valid. A sender raises valid only after it sees ready. What happens?

coreThis one-stage pipeline register should pass one word per cycle when out_ready is always 1. What does it actually do?

assign in_ready = !out_valid;
always @(posedge clk)
  if (rst) out_valid <= 1'b0;
  else if (in_ready) begin
    out_valid <= in_valid;
    if (in_valid) out_data <= in_data;
  end

advancedWrite a plain Verilog-2005 testbench check that flags a sender that changes its data, or drops valid, before the transfer.

always @(posedge clk) begin
  if (!rst && pv && !pr && (!valid || data != pd))
    $display("ERROR %0t: word changed before transfer", $time);
  pv <= valid; pr <= ready; pd <= data;
end

advancedIs a receiver allowed to raise ready before valid arrives, and to lower it again without a transfer?

Practise these 9 questions with animations