Part 8 · Checking & Coverage · Intermediate
Scoreboard Architecture: Expected vs Actual
Hub — self-checking scoreboards, dual analysis imps, FIFO vs ID matching, env wiring, and check_phase drain.
Overview
A scoreboard is the centerpiece of self-checking verification. Without it, a testbench can drive thousands of transactions and still pass with a broken DUT — because nobody compared what happened against what should have happened. The scoreboard automates that comparison: it receives two transaction streams (expected and actual), pairs them, and raises UVM_ERROR on mismatch.
This topic breaks scoreboard architecture into six focused lessons. Each lesson answers a different why question: why two streams instead of one, why dual analysis imps instead of one write(), why connect_phase wiring matters, why FIFO vs ID matching depends on protocol ordering, and why check_phase drain catches silent failures.
Keep the full pipeline diagram below as your map. Every sub-lesson expands one box or arrow in that diagram.
Lessons in this topic
Expected vs Actual Model — the two-stream checking paradigm, three expected sources, driver vs monitor.
Dual Analysis Imps — uvm_analysis_imp_decl, write_exp/write_act, clone before queue.
Env Wiring — connect_phase patterns for DUT agent, golden agent, and ref model paths.
FIFO In-Order Matching — queue-based compare for APB and strictly ordered protocols.
ID Out-of-Order Matching — associative arrays for AXI, PCIe, and reordering buses.
check_phase Drain & Debug — leftovers, summaries, drain scenarios, triage checklist.
Full self-checking pipeline
[UVM] TEST / ENV
│
│ stimulus sequences → driver → DUT pins
▼
┌──────────────┐ ┌──────────────┐
│ DUT MONITOR │ │ GOLDEN MON │
│ (actual) │ │ or REF MODEL │
└──────┬───────┘ └──────┬───────┘
│ act txn │ exp txn
│ │
▼ ▼
┌─────────────────────────────────────────┐
│ [CHECK] SCOREBOARD │
│ act_imp.write_act(act) │
│ exp_imp.write_exp(exp) │
│ │ │
│ ▼ │
│ match engine (FIFO or ID map) │
│ │ │
│ ▼ │
│ MATCH → match_count++ │
│ MISMATCH → UVM_ERROR │
└─────────────────────────────────────────┘
│
▼
[COVER] functional coverage samples (parallel path — not scoreboard)The scoreboard sits in the check path only. Coverage collectors may tap the same monitor streams, but they answer a different question ( was this scenario exercised? ) rather than was the DUT correct? .
[CHECK] scoreboard hub — data ownership
EXPECTED stream (what spec says should happen)
◄── ref_model.predict(req) → exp response
◄── golden-path monitor (known-good VIP / C-model DUT)
◄── second bus monitor on reference interconnect
ACTUAL stream (what DUT pins really did)
◄── DUT-facing monitor — ALWAYS ground truth
NEVER compare driver items to monitor items
driver = intent (what we tried to send)
monitor = reality (what the bus actually carried)Key takeaways
Two streams: expected (spec intent) vs actual (DUT-visible monitor sample).
Use named analysis imps — one write_suffix() per stream on one scoreboard class.
Match strategy depends on protocol ordering — FIFO for in-order, ID map for OOO.
check_phase drain catches unmatched expected — silent pass without it.
Common pitfalls
Single-stream counter scoreboard — counts transactions, does not self-check.
Driver connected to scoreboard — validates stimulus intent, not DUT behavior.
Skipping check_phase — green test with pending expected in queue or ID map.