Interview Question · Code Writing
A Four-Phase Request and Acknowledge Handshake
The Question
The interviewer asks
Write a request and acknowledge handshake that carries an 8-bit word from one clock domain to an unrelated one.
You have two and a half minutes. Speak or type, then press Get Feedback under your answer. No credits needed.
Speech-to-text runs in your browser. Chrome and Edge may send audio to their own speech service.
You can edit your answer before you send it. Feedback uses AI and checks your answer only against our written answer. No credits are used and your answer is not saved.
Reveal the Model Answer
The sender puts the word on data, holds it, and raises req. The receiver synchronizes req, takes data when the synchronized req rises, and raises ack. The sender synchronizes ack, then drops req. The receiver sees req low and drops ack. The data needs no synchronizer, because it is stable long before the receiver reads it.
- 1. req rises
The sender raises
reqwith the data ondata_x, and holds both.Follow the calls, values and waits
- data rise: hs_tx → r1, r2
- data rise: r1, r2 → hs_rx
- 2. ack rises
The receiver sees r2, takes
data_x, which has been still for two clk edges, and raisesack.Follow the calls, values and waits
- data rise: hs_rx → a1, a2
- data rise: a1, a2 → hs_tx
- 3. req falls
The sender sees a2 and drops
req.Follow the calls, values and waits
- data fall: hs_tx → r1, r2
- data fall: r1, r2 → hs_rx
- 4. ack falls
The receiver drops
ack. When a2 falls, the sender is free for the next transfer.Follow the calls, values and waits
- data fall: hs_rx → a1, a2
- data fall: a1, a2 → hs_tx
Read the diagram as text
- hs_tx: clk_f; holds data_x
- r1, r2: req into clk
- hs_rx: clk; takes data_x
- a1, a2: ack into clk_f
- hs_tx → r1, r2: req
- r1, r2 → hs_rx: r2
- hs_rx → a1, a2: ack
- a1, a2 → hs_tx: a2
Every phase waits for the other side, so no clock ratio can lose an event. The cost is four synchronizer crossings per transfer.
- Cycle 1
Edge 5:
reqhas risen in clk_f. - Cycle 3
Edge 7: r2 was 1 at this edge, so the receiver took 5a and raised
ack. - Cycle 4
Edge 8: the sender saw
ackthrough a1 and a2, and droppedreq. - Cycle 6
Edge 10:
ackis down.busyfalls in clk_f at 109.75 ns, after a2 drops; the nextreqshows at edge 11.
Measured: req rose at clk_f edge 16 and the sender was free at clk_f edge 36, 20 fast cycles. The three transfers started 22 and 23 fast cycles apart, and all three arrived.
Send
The sender drives
dataand raisesreq, then holds both.Take
Two flops later, the receiver sees
req, registersdataand raisesack.Release
Two flops later, the sender sees
ackand dropsreq.Reset
The receiver sees
reqlow and dropsack. When the sender seesacklow, the next word may start.
A 10 ns sender and a 14 ns receiver move three words.
receiver took a1 b2 c3 by t=329 ns PASS: data held until ack, three words in orderSelf-Check
Tick each key point you covered in your answer.
What Interviewers Listen For (Mid-Level)
A good mid-level answer lists the four phases in order and says which signal each side synchronizes. It keeps data stable until ack comes back.
What Interviewers Listen For (Senior)
A good senior answer counts the synchronizer delays in one round trip and turns that into words per microsecond. It also says when a FIFO must replace the handshake.
Cross-Questions
Where the interviewer goes next. Open a node to practise that follow-up.
Prove ItBreak ItCompareScale It
- A Four-Phase Request and Acknowledge Handshake
-
CompareTwo-Phase vs Four-Phase HandshakesL2 Mid-LevelL3 Senior
Compare a two-phase handshake, where each change of
reqis a request, with the four-phase one.2:30You have two and a half minutes. Speak or type, then press Get Feedback under your answer. No credits needed.
Speech-to-text runs in your browser. Chrome and Edge may send audio to their own speech service.
You can edit your answer before you send it. Feedback uses AI and checks your answer only against our written answer. No credits are used and your answer is not saved.
Reveal the Model Answer
In a two-phase handshake, every toggle of
reqis a new request and every toggle ofackanswers it. So each word needs one round trip instead of two. The cost is edge detection on both sides, an XOR of two flops. Four-phase uses plain levels and is easier to read and check.Self-Check
Tick each key point you covered in your answer.
Half-Truth
"Two-phase is twice as fast in every case."
It removes the return-to-zero trip, but each word still waits for synchronizer delays in both directions. The data must also stay held for that whole trip.
Source Cummings, Clock Domain Crossing (CDC) Design & Verification Techniques Using SystemVerilog (SNUG Boston 2008) §5.6.1-5.6.3
-
Scale ItWhen a Handshake Is Too SlowL3 Senior
Scale it: the link must now move a word on every destination cycle. Does the handshake still work?
2:30You have two and a half minutes. Speak or type, then press Get Feedback under your answer. No credits needed.
Speech-to-text runs in your browser. Chrome and Edge may send audio to their own speech service.
You can edit your answer before you send it. Feedback uses AI and checks your answer only against our written answer. No credits are used and your answer is not saved.
Reveal the Model Answer
No. Each word waits for two synchronizer delays in each direction, several cycles of each clock. In the run, three words took about 330 ns with 10 ns and 14 ns clocks. A stream needs an asynchronous FIFO. It crosses only the Gray-coded pointers, and words flow every cycle while it is neither full nor empty.
Self-Check
Tick each key point you covered in your answer.
Half-Truth
"Pipeline the handshake: start the next request before the last acknowledge."
Then several words are in flight across the boundary at once, which is what a FIFO does properly with storage and pointers.
Source Mehta, ASIC/SoC Functional Design Verification (2018) ch. 8.3.5 Design of an asynchronous FIFO using Gray code counters
-
Break ItA Handshake Where Only One Side ResetsL2 Mid-LevelL3 Senior
Break it: what goes wrong if the receiver resets while the sender is in the middle of a transfer?
2:30You have two and a half minutes. Speak or type, then press Get Feedback under your answer. No credits needed.
Speech-to-text runs in your browser. Chrome and Edge may send audio to their own speech service.
You can edit your answer before you send it. Feedback uses AI and checks your answer only against our written answer. No credits are used and your answer is not saved.
Reveal the Model Answer
The receiver clears
ackand forgets the word, while the sender still holdsreqhigh. When the receiver leaves reset, it seesreqhigh again and may take the same word twice. It may also miss the edge entirely. Each domain needs its own reset synchronizer, and a crossing needs a rule for what happens when one side is in reset.Two Events Sent into a Sleeping DomainThe lab design. Every value is sampled 1 ns after an edge of the sender's clock clk, edges 2 to 24.t2is the receiver's synchronized copy of the toggle;gotcounts the events it has received.All cycles- Cycle 1
Edge 3: the sender's domain is out of reset, so
ready_ais 1. - Cycle 2
Edge 4: event 1. The toggle goes to 1 while the receiver is still in reset.
- Cycle 10
Edge 12: event 2. The toggle goes back to 0, still before the receiver wakes.
- Cycle 14
Edge 16: the receiver is out of reset, and its flops read a toggle of 0, the same as their reset value. Events 1 and 2 left no trace.
- Cycle 22
Edge 24: event 3, sent at edge 20, arrives. Three sent, one received.
Measured in lesson R6.5 with a toggle crossing, not this handshake. Events sent while the receiver is in reset leave no trace.
Self-Check
Tick each key point you covered in your answer.
Missed Corner
"Both domains share one reset, so this cannot happen."
Each domain releases reset on its own clock. For a few cycles one side is out of reset and the other is not. R6.5 measured an event lost that way.
Source Lesson R6.5, measured on its lab bench: a receiver still in reset swallowed an event, and a ready flag from the receiver fixed it (3 sent, 3 received)
- Cycle 1
-
Prove ItSolve R6.3.1: One Event, One ByteSimulator-graded
Show it, don't just say it: this Silicon Lab problem is graded by the simulator.
What People Get Wrong
Common wrong answers and why they fail. Run It shows the wrong belief failing on a real simulator.
Misconception
"Once req is up, the receiver has the word, so the sender can load the next one."
req takes two receiver flops to arrive, and the receiver reads data only then. The twin changes data early, and the receiver takes the wrong words.
Run It
The same handshake, but the sender loads the next word one cycle after raising req.
FAIL: the sender changed data before the acknowledge, so the receiver took the next wordSee the Fix
`timescale 1ns/1ps
module hs_tx (input logic clk, rst_n, ack, output logic req, output logic [7:0] data);
function automatic logic [7:0] word(input int i);
case (i) 0: return 8'ha1; 1: return 8'hb2; 2: return 8'hc3; default: return 8'h00; endcase
endfunction
logic a1, ack_s; // ack synchronized into the sending domain
int i;
logic [1:0] st; // 0 idle, 1 wait for ack high, 2 wait for ack low
always_ff @(posedge clk or negedge rst_n)
if (!rst_n) begin a1 <= 0; ack_s <= 0; i <= 0; st <= 0; req <= 0; data <= 0; end
else begin
a1 <= ack; ack_s <= a1;
case (st)
0: if (i < 3) begin data <= word(i); req <= 1; st <= 1; end
1: begin
// hold data until the acknowledge comes back
if (ack_s) begin req <= 0; st <= 2; end
end
2: if (!ack_s) begin i <= i + 1; st <= 0; end
endcase
end
endmodule
module hs_rx (input logic clk, rst_n, req, input logic [7:0] data, output logic ack, output logic took, output logic [7:0] word_q);
logic r1, r2, r3; // req synchronized, plus one flop for the edge
always_ff @(posedge clk or negedge rst_n)
if (!rst_n) begin r1 <= 0; r2 <= 0; r3 <= 0; ack <= 0; took <= 0; word_q <= 0; end
else begin
r1 <= req; r2 <= r1; r3 <= r2;
took <= 0;
if (r2 && !r3) begin word_q <= data; took <= 1; ack <= 1; end // data is stable by now
if (!r2 && r3) ack <= 0;
end
endmodule
module tb;
logic tclk = 0, rclk = 0, rst_n = 0, req, ack, took;
logic [7:0] data, word_q;
string log = "";
int n = 0, good = 0;
always #5 tclk = ~tclk; // 10 ns sender
always #7 rclk = ~rclk; // 14 ns receiver
hs_tx tx (.clk(tclk), .rst_n(rst_n), .ack(ack), .req(req), .data(data));
hs_rx rx (.clk(rclk), .rst_n(rst_n), .req(req), .data(data), .ack(ack), .took(took), .word_q(word_q));
always @(posedge rclk) if (took) begin
log = {log, $sformatf(" %h", word_q)};
if (word_q == (n == 0 ? 8'ha1 : n == 1 ? 8'hb2 : 8'hc3)) good++;
n++;
if (n == 3) $display("receiver took%s by t=%0d ns", log, $time);
end
initial begin
#23 rst_n = 1; // flops reset at the clock edges before this
#600;
if (good == 3) $display("PASS: data held until ack, three words in order");
$finish;
end
endmodule
Prints: PASS: data held until ack, three words in order
Misconception
"Each data bit needs its own synchronizer as well."
The data is held stable from before req rises until ack returns. By the time the receiver reads it, it has settled.
Source Sutherland, RTL Modeling with SystemVerilog (2017) ch. 8.1.6 Multiple clocks and clock domain crossing
Delivery
Starts writing code before asking about the rate.
A handshake moves one word per round trip. If the source makes a word every cycle, the right answer is a FIFO, not a handshake.