Part 11 · Senior Prep · Intermediate
Mismatch Triage: First-Failing-Transaction Protocol
Checking-bucket playbook for scoreboard and checker failures — isolate the first mismatch, compare at transaction granularity, and avoid waveform noise.
Checking bucket first moves
For UVM_ERROR mismatch failures , the senior move is: print the first failing transaction at UVM_MEDIUM, compare fields systematically, then decide if the bug is TB, RTL, or spec.
[DEBUG][SENIOR][UVM] mismatch triage flow
1) grep first UVM_ERROR (not last)
2) print expected vs actual txn at MEDIUM
3) identify which field diverged first
4) trace that field to source (monitor / ref model / RTL)
5) only then open targeted waveform windowfunction void compare_txn(my_item exp, my_item act, output bit match);
match = 1;
if (exp.addr !== act.addr) begin
`uvm_error("SB", $sformatf("addr exp=%0h act=%0h", exp.addr, act.addr))
match = 0; return;
end
if (exp.data !== act.data) begin
`uvm_error("SB", $sformatf("data exp=%0h act=%0h", exp.data, act.data))
match = 0; return;
end
endfunctionKey takeaways
Always debug the first mismatch — later errors are often cascades.
Compare at transaction field granularity before signal-level waves.
Separate TB bug, RTL bug, and spec ambiguity before filing.
Common pitfalls
Scrolling to the last UVM_ERROR instead of the first.
Opening full-chip waves for a single-field mismatch.
Fixing the scoreboard compare without checking monitor packing.
Scoreboard debug toolkit
Instrument scoreboards for senior triage: transaction counters, queue depth, and first-mismatch capture.
First-mismatch capture
class my_scoreboard extends uvm_scoreboard;
my_item exp_q[$], act_q[$];
bit first_mismatch_seen;
my_item first_exp, first_act;
function void write_exp(my_item t);
if (!first_mismatch_seen) exp_q.push_back(t);
endfunction
function void write_act(my_item t);
my_item exp;
if (first_mismatch_seen) return;
if (exp_q.size() == 0) begin
`uvm_error("SB", "unexpected actual before expected")
return;
end
exp = exp_q.pop_front();
if (!exp.compare(act)) begin
first_mismatch_seen = 1;
first_exp = exp; first_act = t;
`uvm_error("SB", "FIRST MISMATCH — stopping compare flood")
exp.print(); act.print();
end
endfunction
endclass[DEBUG][SENIOR][UVM] mismatch root-cause matrix
field wrong on first txn:
monitor packing bug OR ref model init
field wrong after N txns:
reorder / queue / pipelining issue
intermittent same seed:
race in scoreboard OR clock domain
passes with SB disabled:
compare logic bug (not RTL)Log analysis commands
# find first scoreboard error
grep -n "UVM_ERROR.*SB\|MISMATCH" sim.log | head -1
# extract transaction context around first error
LINE=$(grep -n "FIRST MISMATCH" sim.log | head -1 | cut -d: -f1)
sed -n "$((LINE-5)),$((LINE+15))p" sim.logDisable compare after first mismatch to keep logs readable.
Log transaction ID / timestamp for waveform correlation.
Check expected queue vs actual queue ordering separately.
Verify both analysis ports are connected in connect_phase.
Common pitfalls
Compare flooding — thousands of identical errors hide the first divergence.
Scoreboard comparing before both streams have matching handshake.
Assuming RTL bug when monitor and ref model disagree on byte order.