Part 8 · Checking & Coverage · Intermediate

Report Catchers

uvm_report_catcher demote/promote, THROW vs CAUGHT, and VIP noise management.

What catchers do

A uvm_report_catcher intercepts messages between the report handler and the report server. Use catchers to demote known-benign VIP errors to warnings, suppress internal VIP debug noise, or promote warnings to errors for specific IDs you want to fail on.

diagram
Legend: [UVM]

  CATCHER FLOW

  uvm_error("VIP_KNOWN_ERR", "benign timeout in VIP")
       │
       ▼
  report_handler (passes — uvm_error not verbosity-gated)
       │
       ▼
  vip_catcher.catch()
       │
       ├─ get_id() == "VIP_KNOWN_ERR"?
       │     YES  set_severity(UVM_WARNING)  ← demote
       │           return THROW
       │
       ▼
  report_server
       │
       ├─ UVM_WARNING count++ (not UVM_ERROR)
       └─ Test may still PASS 

  If return CAUGHT instead of THROW:
       └─ Message never reaches server  no count at all

Catcher implementation

systemverilog
class vip_catcher extends uvm_report_catcher;
  `uvm_object_utils(vip_catcher)

  function new(string name = "vip_catcher");
    super.new(name);
  endfunction

  function action_e catch();
    // Demote known benign VIP error to warning
    if (get_severity() == UVM_ERROR && get_id() == "VIP_KNOWN_ERR") begin
      set_severity(UVM_WARNING);
      set_message({"[DEMOTED] ", get_message()});
      return THROW;  // modified message continues to server
    end

    // Suppress internal VIP debug entirely
    if (get_id() == "VIP_INTERNAL")
      return CAUGHT;  // swallow — no server update

    return THROW;  // all other messages pass through unchanged
  endfunction
endclass

// Register globally in test build_phase
function void build_phase(uvm_phase phase);
  super.build_phase(phase);
  uvm_report_cb::add(null, vip_catcher::type_id::create("vip_c"));
endfunction

THROW vs CAUGHT and audit discipline

Return value semantics

diagram
Return value    Message reaches server?   Counter updated?
──────────────────────────────────────────────────────────────────
THROW           YES (possibly modified)     YES (at new severity)
CAUGHT          NO                          NO

Use THROW when: demoting errorwarning (still want visibility)
Use CAUGHT when: suppressing known noise entirely (VIP internal debug)

Catcher audit checklist

  1. Document every catcher with the VIP release version and known issue ID.

  2. Review catchers at each VIP upgrade — the known issue may be fixed.

  3. Never catch real DUT bug IDs (SCB_MISMATCH, RAL_MIRROR_FAIL).

  4. Log demoted messages at UVM_LOW so audit trail exists in regression logs.

  5. Count active catchers in report_phase — unexpected catcher count = config bug.

  • THROW — message continues to server (possibly demoted); counter updated at new severity.

  • CAUGHT — swallow message entirely; no counter increment.

  • Register with uvm_report_cb::add(null, catcher) for global effect.

  • Audit catchers at VIP upgrades — demoted bugs hide real failures.

Key takeaways

  • Catchers for known benign VIP errors — not for real DUT bug IDs.

  • THROW for demotion (keep visibility); CAUGHT for suppression (silent).

  • Document and audit catchers — they directly affect PASS/FAIL counts.

Common pitfalls

  • Catcher on SCB_MISMATCH or RAL_MIRROR_FAIL — hides real DUT bugs.

  • CAUGHT on uvm_error — error count never increments, test falsely passes.

  • Stale catcher after VIP fix — real new bug demoted to warning silently.