The scoreboard is the checker. Monitors publish transactions; the scoreboard predicts and compare()s. Failures are uvm_error, not $display.
flowchart LR mon_in[monitor_in] --> pred[predict] pred --> exp[expected] mon_out[monitor_out] --> act[actual] exp --> cmp[compare] act --> cmp cmp --> err[uvm_error]
function void write_actual(fifo_item act);
fifo_item exp;
if (!exp_q.size()) `uvm_error("SCB", "unexpected txn")
else begin
exp = exp_q.pop_front();
if (!exp.compare(act))
`uvm_error("SCB", "mismatch")
end
endfunction
Connect monitors with analysis exports / TLM FIFOs so samples are not dropped when the scoreboard is busy.
Wrong vs right
Wrong — $display("got %0h", data) and a human staring at the log.
Right — stored expected queue + compare() + uvm_error with a message id.