Part 8 · Checking & Coverage · Intermediate
UVM Reporting Architecture
Report handler, report server, catcher chain, and message flow to PASS/FAIL.
The three-layer pipeline
Every UVM message passes through three layers before affecting simulation outcome. The uvm_report_handler filters by verbosity and sets action flags. The uvm_report_catcher chain optionally intercepts and modifies messages. The uvm_report_server maintains global severity counts used for PASS/FAIL.
Legend: [UVM]
COMPLETE REPORT PIPELINE
Component code:
`uvm_error("SCB_MISMATCH", "addr 0x1000 exp=FF act=00")
│
▼
┌─────────────────────────────────────────────────────────┐
│ LAYER 1: uvm_report_handler (per-component) │
│ │
│ • Checks verbosity threshold (uvm_info only) │
│ • Checks ID-specific verbosity override │
│ • Sets action flags: DISPLAY | LOG | COUNT | EXIT │
│ • uvm_error: always passes (not verbosity-gated) │
└─────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────┐
│ LAYER 2: uvm_report_catcher chain (optional) │
│ │
│ • catch() called for each registered catcher │
│ • Can change severity, text, ID │
│ • return THROW → message continues to server │
│ • return CAUGHT → message swallowed, no server update │
└─────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────┐
│ LAYER 3: uvm_report_server (global singleton) │
│ │
│ • Formats message with timestamp, component path │
│ • Writes to log file and/or stdout per action flags │
│ • Increments severity counter (UVM_COUNT action) │
│ • UVM_FATAL + UVM_EXIT → stops simulation │
└─────────────────────────────────────────────────────────┘
│
▼
Log output + severity count → report_phase PASS/FAILHandler, server, and catcher roles
uvm_report_handler — per-component filter
One handler per component (auto-created); accessible via get_report_handler().
set_report_verbosity_level(UVM_MEDIUM) — default threshold for uvm_info on this component.
set_report_id_verbosity("SCB", UVM_HIGH) — override for specific message ID.
set_report_severity_action(UVM_ERROR, UVM_DISPLAY|UVM_LOG|UVM_COUNT) — action mask.
uvm_error and uvm_fatal always pass the handler — never verbosity-gated.
uvm_report_server — global counter
Singleton: uvm_report_server::get_server().
get_severity_count(UVM_ERROR) — primary PASS/FAIL input.
get_severity_count(UVM_FATAL) — also counts toward FAIL.
get_id_count("SCB_MISMATCH") — per-ID count for triage.
summarize() — prints full report at end of simulation.
uvm_report_catcher — intercept layer
Registered via uvm_report_cb::add(null, catcher) — null = global catcher.
catch() can call set_severity(), set_message(), set_id() before returning.
THROW — modified message continues to server.
CAUGHT — message never reaches server; counter not incremented.
Key takeaways
All UVM messages flow through handler → catcher (optional) → server pipeline.
Handler controls verbosity filtering; server controls counting and PASS/FAIL.
Catchers sit between handler and server — use for known benign VIP messages.
Common pitfalls
Assuming uvm_info always prints — gated by verbosity threshold.
Multiple catchers with conflicting demotions — audit catcher chain regularly.
Custom log without report server — PASS/FAIL counts bypassed.