← Design Verification Interviews
Interview Question · Code Writing
Covering a Stall with Transition Bins
The Question
The interviewer asks
A sink can hold ready low for one or two cycles. Write coverage that proves both stall lengths were seen, not just that a stall happened.
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
First reduce the handshake to one state per clock: IDLE when valid is 0, WAIT when ready is 0, and XFER when both are 1. Then write transition bins on that state. Use (IDLE, XFER => WAIT => XFER) for a one-cycle stall and (IDLE, XFER => WAIT => WAIT => XFER) for two. Anchoring the start stops a longer stall from also matching the shorter bin. A value bin on WAIT only says some stall happened.
One column per rising edge. A two-cycle stall is the order IDLE, WAIT, WAIT, XFER. A value bin on WAIT cannot tell it from a one-cycle stall.
Self-Check
Tick each key point you covered in your answer.
What Interviewers Listen For (Junior)
A good junior answer first builds one state per clock from valid and ready. It then writes transitions that start from the state before the stall.
What Interviewers Listen For (Mid-Level)
A good mid-level answer notices that (WAIT => XFER) alone also matches the end of a long stall. For long stalls it switches to a counter of stall cycles.
Cross-Questions
Where the interviewer goes next. Open a node to practise that follow-up.
WhyBreak ItCompareScale It
- Covering a Stall with Transition Bins
-
WhyWhy Reduce the Handshake to One StateL1 Junior
Why convert
validandreadyinto one state before writing transitions? Why not cross them?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
A transition bin follows one coverpoint's value from one sample to the next. A cross only pairs values within the same sample and has no memory of earlier ones. So
validcrossed withreadyshows that a stalled cycle happened, but not how long the stall lasted. One state per clock gives the transition something to follow.Four phases, five transition bins Every state value appears early. Only the order of the samples decides which transition bins fill.
Self-Check
Tick each key point you covered in your answer.
Half-Truth
"A cross of valid and ready already shows the stall."
It shows the stalled combination appeared at least once. It cannot tell a one-cycle stall from a five-cycle one.
Source IEEE 1800-2017 §19.6
-
CompareTransition Bins vs a Stall-Length CounterL2 Mid-Level
Compare transition bins with a counter of stall cycles, sampled at each transfer. What does this print?
systemverilog module tb; logic clk = 0; always #5 clk = ~clk; bit valid, ready; int stall_len = 0; covergroup cg with function sample(int n); len: coverpoint n { bins none = {0}; bins one = {1}; bins two = {2}; bins long_ = {[3:16]}; } endgroup cg c = new(); // valid/ready per clock: stalls of 0, 1 and 5 cycles. bit [1:0] vr[$] = '{2'b11, 2'b10, 2'b11, 2'b10, 2'b10, 2'b10, 2'b10, 2'b10, 2'b11, 2'b00}; initial begin foreach (vr[i]) begin {valid, ready} = vr[i]; @(posedge clk); if (valid && !ready) stall_len++; if (valid && ready) begin c.sample(stall_len); $display("transfer after %0d stall cycles", stall_len); stall_len = 0; end end $display("stall-length coverage=%0.2f", c.get_coverage()); $finish; end endmodule2: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
It prints three transfers, after 0, 1 and 5 stall cycles, then 75% coverage, because no two-cycle stall happened. A counter handles any stall length with one coverpoint, and a range bin like
[3:16]covers long stalls. Transition bins grow one bin per length and get unreadable past three or four cycles. Use transitions for short, exact patterns and a counter for lengths.RUNVerilator (coverage build) · simulator serviceExpected:transfer after 0 stall cyclestransfer after 1 stall cyclestransfer after 5 stall cyclesstall-length coverage=75.00Self-Check
Tick each key point you covered in your answer.
Missed Corner
"A counter needs no care; just sample it every clock."
Sampled every clock it counts the stall growing, so a five-cycle stall also covers 1, 2, 3 and 4. Sample it once, at the transfer.
Source Mehta, SystemVerilog Assertions and Functional Coverage (3rd ed.), §26.19 guidelines (PDF p476)
-
Scale ItStall Coverage on Twelve PortsL2 Mid-LevelL3 Senior
An interconnect has 12 ports with the same handshake. How do you cover stalls on all of them without 12 copies of the code?
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
Write the covergroup once, in the interface or in a coverage class, and create one instance per port. Set
option.per_instance = 1so the report shows each port. Remember that the type total averages the instances. Eleven busy ports and one dead port still look like 92%, so review the per-port numbers, not just the total.Self-Check
Tick each key point you covered in your answer.
What Interviewers Listen For (Senior)
A good senior answer asks for a report per port before trusting a combined number. It also asks which ports carry real traffic.
Missed Corner
"One shared instance for all ports is simpler."
A shared instance merges the ports. A port that never stalls is hidden by the others, which is the hole you wanted to find.
Source Spear & Tumbush, SystemVerilog for Verification (3rd ed.), §9.10.1 (PDF p392)
-
WhyWhy the Type Figure Is an AverageL2 Mid-Level
Why does the type figure read 50% when the instances together hit every bin?
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
With merging off, each instance is scored against its own bins, and the type is the weighted average of those scores. Port A scores 50 and port B scores 50, so the type is 50. The rule asks "how well was each instance covered", not "was each bin hit somewhere". One idle instance therefore pulls the type figure down.
Figure Bins hit Score Instance A b[0], b[1] 50% Instance B b[2], b[3] 50% Type, default (average) each instance scored on its own 50% Type, merge_instances = 1(union)all four, from either instance 100% The same samples as the root question. Only the rule for combining instances changes.
Self-Check
Tick each key point you covered in your answer.
Tool as Truth
"The average rule is a tool bug."
It is the standard's default. Tools that show the union have
merge_instancesset, or show a merged database view.Source Mehta, Introduction to SystemVerilog, Table 15.2 (PDF p613)
-
Break ItTransition Bins Sampled on the Wrong ClockL2 Mid-Level
How could these transition bins still mislead you? Suppose the covergroup samples on a core clock twice as fast as the bus.
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
Every bus cycle is sampled twice, so each state appears twice in a row. A one-cycle stall then looks like
WAIT => WAIT, and it covers the two-cycle bin instead. Transition bins count samples, not bus cycles. Sample on the bus clock, or callsample()once per bus cycle.Self-Check
Tick each key point you covered in your answer.
Misconception
"Sampling more often only makes coverage more accurate."
Transitions are counted between consecutive samples. Extra samples insert repeated states, which changes which sequences appear. The twin covers the wrong bin.
Run It
A one-cycle stall, sampled twice per bus cycle.
RUNVerilator (coverage build) · simulator serviceExpected:one_stall=0.00 two_stall=100.00FAIL: two samples per bus cycle turned the one-cycle stall into a two-cycle oneSee the Fix
module tb; typedef enum bit [1:0] {IDLE, WAIT, XFER} st_t; st_t st; st_t bus[$] = '{IDLE, WAIT, XFER, IDLE}; // one entry per bus cycle: a one-cycle stall covergroup one_cg; cp: coverpoint st { bins one_stall = (IDLE, XFER => WAIT => XFER); } endgroup covergroup two_cg; cp: coverpoint st { bins two_stall = (IDLE, XFER => WAIT => WAIT => XFER); } endgroup one_cg one = new(); two_cg two = new(); initial begin foreach (bus[i]) begin st = bus[i]; repeat (1) begin one.sample(); two.sample(); end // the fix: one sample per bus cycle end $display("one_stall=%0.2f two_stall=%0.2f", one.get_coverage(), two.get_coverage()); if (two.get_coverage() > 0) $display("FAIL: two samples per bus cycle turned the one-cycle stall into a two-cycle one"); else $display("PASS: one sample per bus cycle covers the one-cycle stall only"); end endmodulePrints:
one_stall=100.00 two_stall=0.00PASS: one sample per bus cycle covers the one-cycle stall only
What People Get Wrong
Common wrong answers and why they fail. Run It shows the wrong belief failing on a real simulator.
Misconception
"A bin on WAIT proves the stall cases were covered."
A value bin counts cycles, not sequences. The twin has only a one-cycle stall and the value bins still read 100%.
Run It
A one-cycle stall, then back-to-back transfers.
coverage=100.00 FAIL: the value bins read 100% but a two-cycle stall never happenedSee the Fix
module tb;
typedef enum bit [1:0] {IDLE, WAIT, XFER} st_t;
st_t st;
bit valid, ready;
// valid/ready per clock: a one-cycle stall, then back-to-back transfers.
bit [1:0] vr[$] = '{2'b00, 2'b10, 2'b11, 2'b11, 2'b11, 2'b00};
covergroup cg;
cp: coverpoint st {
bins one_stall = (IDLE, XFER => WAIT => XFER);
bins two_stall = (IDLE, XFER => WAIT => WAIT => XFER);
bins back2back = (XFER => XFER);
}
endgroup
cg c = new();
initial begin
foreach (vr[i]) begin
{valid, ready} = vr[i];
st = !valid ? IDLE : (!ready ? WAIT : XFER);
c.sample();
end
$display("coverage=%0.2f", c.get_coverage());
if (c.get_coverage() == 100.0) $display("FAIL: the value bins read 100%% but a two-cycle stall never happened");
else $display("PASS: the transition bins show the two-cycle stall is still missing");
end
endmodule
Prints: coverage=66.67 PASS: the transition bins show the two-cycle stall is still missing
Missed Corner
"(WAIT => XFER) counts only one-cycle stalls."
It matches the last two samples of any stall. The twin has only a two-cycle stall, and the one-cycle bin is covered anyway.
Run It
Only a two-cycle stall happens.
coverage=100.00 with only a two-cycle stall FAIL: (WAIT => XFER) also matched the end of the two-cycle stall, so one_stall looks coveredSee the Fix
module tb;
typedef enum bit [1:0] {IDLE, WAIT, XFER} st_t;
st_t st;
st_t trace_[$] = '{IDLE, WAIT, WAIT, XFER, IDLE}; // only a two-cycle stall happens
covergroup cg;
cp: coverpoint st {
bins one_stall = (IDLE, XFER => WAIT => XFER); // the fix: anchor the start
bins two_stall = (IDLE, XFER => WAIT => WAIT => XFER);
}
endgroup
cg c = new();
initial begin
foreach (trace_[i]) begin st = trace_[i]; c.sample(); end
$display("coverage=%0.2f with only a two-cycle stall", c.get_coverage());
if (c.get_coverage() == 100.0) $display("FAIL: (WAIT => XFER) also matched the end of the two-cycle stall, so one_stall looks covered");
else $display("PASS: anchored bins report the one-cycle stall as missing");
end
endmodule
Prints: coverage=50.00 with only a two-cycle stall PASS: anchored bins report the one-cycle stall as missing
Tool as Truth
"Repetition like WAIT [*2] is not legal in transition bins; my simulator rejects it."
The standard allows repetition in transitions. Some tools, including this site's coverage build, reject it, so spell the sequence out.
Source IEEE 1800-2017 §19.5.2; ASIC Point engine notes (Verilator master b8e7f1e coverage build)