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

  1. Expected vs Actual Model — the two-stream checking paradigm, three expected sources, driver vs monitor.

  2. Dual Analysis Imps — uvm_analysis_imp_decl, write_exp/write_act, clone before queue.

  3. Env Wiring — connect_phase patterns for DUT agent, golden agent, and ref model paths.

  4. FIFO In-Order Matching — queue-based compare for APB and strictly ordered protocols.

  5. ID Out-of-Order Matching — associative arrays for AXI, PCIe, and reordering buses.

  6. check_phase Drain & Debug — leftovers, summaries, drain scenarios, triage checklist.

Full self-checking pipeline

diagram
[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? .

diagram
[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.