Difficulty: Medium · Puzzle 4 of 6 · Topic: Scoreboard Puzzles: Mismatch or Ordering Bug?
After the first mismatch, every following compare also fails, each with got equal to the expected value of the NEXT item, and the scoreboard ends with one leftover entry. Decide whether the scoreboard policy or the stream is at fault, and what the real root cause is.
if (exp_q.size() && got_q.size()) begin
exp = exp_q.pop_front();
got = got_q.pop_front();
if (!exp.compare(got))
\`uvm_error("SB", $sformatf("mismatch exp id=%0d got id=%0d", exp.id, got.id));
end
// log:
// mismatch exp id=3 got id=4
// mismatch exp id=4 got id=5
// mismatch exp id=5 got id=6
// ... at end: leftover exp id=NCheck whether the pop-both policy loses alignment for a pure data error, or only when the streams differ in length.
1) Read the ids in the log: got is always exp+1. That is a shifted stream, not a corrupted value.
2) Popping both queues on a mismatch keeps alignment for a 1:1 stream: a pure data error gives exactly one error (verified: [1,2,3,4,5] vs [1,2,99,4,5] gives one mismatch).
3) A cascade appears only when one side lost (or duplicated) an item: [1,3,4,5] vs the expected [1,2,3,4,5] gives 3 errors plus a leftover (verified). So the first error id=3 vs 4 is where the DUT (or monitor) dropped id=3.
4) Do not 'peek and pop only on match': that leaves the head stuck, and every later compare fails against the same head.
5) Fix: match by id (associative array / per-id queue) so a missing item is reported once as 'id=3 missing', or do a bounded look-ahead resync, and cap the number of reported errors after the first.Answer: The pop-both policy is fine for a 1:1 stream; the cascade means the streams are shifted because one item is missing or duplicated (here id=3 never arrived). Fix: key matching by id (or bounded resync), report the lost item once, and stop after the first N errors; do not change to peek-and-pop-on-match, which would deadlock the checker on the first mismatch.
Checked by running the code in Verilator 5; the printed output supports the answer above. Plain-SV queue model of the pop-both policy: a data error gives one mismatch, a lost item gives a cascade, id-keyed matching reports it once.
The tempting 'fix' of popping only on a match makes the cascade worse. A burst of shifted mismatches is a count problem, not a pop policy problem.
How would you implement bounded resync without hiding real consecutive DUT bugs? Model answer: On a mismatch, look ahead up to N expected entries for the actual id; if found, report the skipped ids as missing and continue aligned, otherwise report one mismatch and drop only the actual. Keep N small, log every resync, and after M resyncs in a window raise a hard error so a real run of DUT bugs is not absorbed.
First I look at the first mismatch, because a burst of mismatches usually means the two streams are shifted. The root cause is one lost item, here id 3 never arrived, so every later comparison is off by one; the pop-both policy itself is fine for a one-to-one stream. I confirm it by checking the item counts on both sides. The fix is to key matching by id, or use a bounded resync, report the lost item once, and stop after the first few errors.