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.

diagram
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/FAIL

Handler, 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.