Whenever two blocks exchange data, each side must know when the other is ready. A handshake is the small protocol that settles this: the sender says "here is data", the receiver says "I have it". Every bus in this tutorial is built on one of three handshakes: four-phase request/acknowledge, two-phase request/acknowledge, and valid/ready. This article simulates all three side by side and shows why modern buses use valid/ready.
9 min read | Beginner
What You'll Learn
- Describe four-phase and two-phase request/acknowledge handshakes
- Describe the valid/ready handshake and its two rules
- Compare the throughput of the three handshakes
- Implement each handshake in Verilog
Four-Phase Request/Acknowledge
The oldest and most robust handshake has four steps, called phases:
- The sender puts the data on the bus and raises
req. - The receiver takes the data and raises
ack. - The sender sees
ackand lowersreq. - The receiver sees
reqlow and lowersack. Both are back at zero, ready for the next word.
module hs4_sender (
input clk,
input rst,
input go,
input [7:0] din,
input ack,
output reg req,
output reg [7:0] data
);
always @(posedge clk) begin
if (rst) begin
req <= 1'b0;
end
else if (go && !req && !ack) begin // phase 1: request, with the data
req <= 1'b1;
data <= din;
end
else if (req && ack) begin // phase 3: drop the request
req <= 1'b0;
end
end
endmodule
module hs4_receiver (
input clk,
input rst,
input req,
input [7:0] data,
output reg ack,
output reg [7:0] got
);
always @(posedge clk) begin
if (rst) begin
ack <= 1'b0;
end
else if (req && !ack) begin // phase 2: take the data, acknowledge
ack <= 1'b1;
got <= data;
end
else if (!req && ack) begin // phase 4: drop the acknowledge
ack <= 1'b0;
end
end
endmodule
The four-phase handshake works even when the two sides run on unrelated clocks, because each step waits for a level, not an edge. That makes it the standard way to pass a word across a clock domain boundary, as the bridges and clock domain crossing article shows. Its cost is speed: four signal changes per word.
Two-Phase Request/Acknowledge
The two-phase handshake, also called toggle signaling, halves the work. Every change of req, up or down, announces a new word, and every change of ack acknowledges it. The sender may send when req equals ack:
always @(posedge clk) begin
if (rst) begin
req <= 1'b0;
end
else if (go && req == ack) begin // idle when req equals ack
req <= ~req;
data <= din;
end
end
The receiver copies req into ack whenever they differ, taking the data at the same time.
Valid/Ready
Inside a synchronous design, there is a faster option. The sender drives valid when it has data; the receiver drives ready when it can accept data. A word moves in every clock cycle in which both are high. There are no return-to-zero phases at all. Two rules keep it safe:
- Once the sender raises
valid, it keepsvalidhigh and the data unchanged until the word is taken. - The sender must not wait for
readybefore raisingvalid; the receiver may wait forvalidbefore raisingready. This prevents both sides from waiting for each other forever.
always @(posedge clk) begin
if (rst) begin
valid <= 1'b0;
data <= 8'h01;
end
else begin
if (valid && ready) // the word was taken: offer the next one
data <= data + 8'h01;
if (!valid || ready) // never withdraw a word that is waiting
valid <= go;
end
end
AXI uses valid/ready on all five of its channels, and AXI-Stream is nothing but valid/ready plus data.
Quick Check
Q: valid is high and ready is low. May the sender change the data in the next cycle?
Show Answer
No. The word has not been taken yet, so the sender must keep valid high and the data unchanged until a cycle in which ready is also high.
All Three Side by Side
The testbench runs all three handshakes on the same clock for the same ten cycles. The valid/ready receiver stalls for two of them.
| Handshake | Cycles per word | Words in the 10 cycles | Typical use |
|---|---|---|---|
| Four-phase req/ack | 4 | 3 | clock domain crossing, asynchronous logic |
| Two-phase req/ack | 2 | 5 | clock domain crossing with fewer transitions |
| Valid/ready | 1 | 8 (2 stall cycles) | on-chip buses and streams: AXI, AXI-Stream |
Valid/ready reaches one word per cycle because the next word can follow immediately; the request/acknowledge handshakes spend cycles returning to an idle state or waiting for the other side to see each change.
Quick Check
Q: Why can a four-phase handshake cross between two unrelated clocks safely, while valid/ready in its simple form cannot?
Show Answer
Each four-phase step waits until the other side's level has changed and stayed changed, so a signal sampled a cycle late is still correct. Valid/ready assumes both sides see the same clock edge, so a word can be taken in one domain while the other has not seen it yet.
Running It in ChipVerify Lab
The example contains the three sender and receiver pairs and the testbench that drives them. Run it and compare the three handshakes in the waveform.
Common Mistakes
Mistake #1: Dropping valid before the word is taken
A sender that lowers valid while ready is still low loses the word. The receiver never saw a cycle with both high.
Mistake #2: Making valid depend on ready
If the sender waits for ready and the receiver waits for valid, nothing ever moves. The sender raises valid on its own.
Mistake #3: Skipping the return-to-zero phases
A four-phase receiver that raises ack but never lowers it blocks the next word forever. Each side must return to zero.
Practice Exercise
Challenge: A Busy Receiver
Open the example. Change the testbench so that the valid/ready receiver stalls in every second cycle while govr is high, instead of for two cycles in a row. Predict how many words are transferred, then run it.
Hint
A word moves only in cycles where ready is high. How many of the ten cycles are those?
Solution
repeat (5) begin // the receiver stalls in every second cycle
@(negedge clk);
stall = 1;
@(negedge clk);
stall = 0;
end
Five words are transferred instead of eight: one in every cycle where ready is high. The receiver now limits the throughput to half of the bus rate. The sender keeps valid high and the data steady through every stall cycle, so no word is lost.
Open the ready-made example in the lab and run the simulation.
Summary
- Four-phase req/ack: request, acknowledge, release, release. Robust across clocks, four cycles per word here.
- Two-phase req/ack: every toggle is a word. Half the transitions of four-phase.
- Valid/ready: a word moves in every cycle with both high. One word per cycle, used by AXI and AXI-Stream.
- Valid/ready rules: hold valid and data until taken; never make valid wait for ready.