The complete UVM message system — the four severity macros, verbosity levels and the filter matrix, setting verbosity per component and globally, report hooks and overrides, message counts and thresholds, ID-based filtering, and best practices for log-friendly testbenches.
UVM provides four severity levels for messages. Each has a default action — what the simulation does when that severity fires. Only `uvm_info messages are filtered by verbosity; the other three always print.
// ── Syntax for all four macros ──────────────────────────── // `uvm_info (id, message, verbosity) // `uvm_warning(id, message) // `uvm_error (id, message) // `uvm_fatal (id, message) `uvm_info ("DRV", $sformatf("Driving addr=0x%03h", addr), UVM_HIGH) `uvm_warning("MON", "PREADY held low for > 16 cycles") `uvm_error ("SB", $sformatf("MISMATCH exp=%0h act=%0h", exp, act)) `uvm_fatal ("CFG", "No virtual interface in config_db!") // ── Equivalent functional form (usable in classes and modules) // When no 'this' context is available (e.g. inside covergroups) uvm_report_info ("ID", "message", UVM_MEDIUM); uvm_report_warning("ID", "message"); uvm_report_error ("ID", "message"); uvm_report_fatal ("ID", "message");
Verbosity controls which `uvm_info messages appear in the transcript. Each component has a verbosity setting; a message is printed only if its verbosity value is ≤ the component’s current verbosity setting. Lower verbosity = more important = always shown first.
| Message verbosity | Shown at UVM_LOW | UVM_MEDIUM (default) | UVM_HIGH | UVM_FULL | UVM_DEBUG |
|---|---|---|---|---|---|
UVM_NONE (0) | ✓ | ✓ | ✓ | ✓ | ✓ |
UVM_LOW (100) | ✓ | ✓ | ✓ | ✓ | ✓ |
UVM_MEDIUM(200) | ✗ | ✓ | ✓ | ✓ | ✓ |
UVM_HIGH (300) | ✗ | ✗ | ✓ | ✓ | ✓ |
UVM_FULL (400) | ✗ | ✗ | ✗ | ✓ | ✓ |
UVM_DEBUG (500) | ✗ | ✗ | ✗ | ✗ | ✓ |
| Verbosity tag | Use for | When you want to see it |
|---|---|---|
UVM_NONE | Critical infrastructure messages — used sparingly. Always visible. | Always. Cannot be filtered. |
UVM_LOW | Test-level summaries, pass/fail results, major milestones | Normal regression runs |
UVM_MEDIUM | Per-transaction progress, scoreboard matches, phase transitions | Default — most debug sessions |
UVM_HIGH | Per-item detail, driver cycle-by-cycle, monitor every sample | When debugging a specific failure |
UVM_FULL | Internal state dumps, sequence internals, full register values | Deep debugging a protocol issue |
UVM_DEBUG | Minute implementation details rarely needed by end users | Infrastructure development only |
Verbosity can be set globally, per component, or per message ID — from inside the testbench code or from the simulator command line without recompilation.
// ── Globally — all components ───────────────────────────── // From start_of_simulation_phase or end_of_elaboration_phase uvm_root::get().set_report_verbosity_level_hier(UVM_HIGH); // ── Per component — just this one ──────────────────────── m_driver.set_report_verbosity_level(UVM_HIGH); // ── Per component + all children ───────────────────────── m_env.m_agent.set_report_verbosity_level_hier(UVM_FULL); // ── Command line: global verbosity (no recompile) ──────── // +UVM_VERBOSITY=UVM_HIGH // ── Command line: specific component ───────────────────── // +uvm_set_verbosity=uvm_test_top.m_env.m_agent.m_drv,_ALL_,UVM_HIGH,run_phase // Format: component_path, id, verbosity, phase (or "") // ── Query current verbosity ─────────────────────────────── int v = get_report_verbosity_level();
+UVM_VERBOSITY=UVM_HIGH for global detail or the per-component plusarg for surgical debugging. This keeps the source clean and allows regression scripts to control output volume.Every UVM message automatically includes the severity, simulation time, component path, and the ID string. Understanding the format helps decode regression log files quickly.
// ── What a typical UVM message looks like in the transcript // UVM_INFO @ 1450ns: uvm_test_top.env.agent.drv [DRV] Driving addr=0x004 // ───────── ────── ────────────────────────── ─── ────────────────── // severity time component path ID message text // // UVM_ERROR @ 1500ns: uvm_test_top.env.sb [SB] MISMATCH exp=0xDEAD act=0xBEEF // ── Good ID naming convention ───────────────────────────── // Use component abbreviation as ID — easy to grep in logs `uvm_info("DRV", "...", UVM_HIGH) // driver `uvm_info("MON", "...", UVM_MEDIUM) // monitor `uvm_info("SB", "...", UVM_LOW) // scoreboard `uvm_info("SEQ", "...", UVM_MEDIUM) // sequence `uvm_info("CFG", "...", UVM_LOW) // config `uvm_info("TEST", "...", UVM_LOW) // test // ── Include class name in ID for precise location ───────── `uvm_info({get_type_name(), "::run_phase"}, "Starting driver", UVM_HIGH) // → [apb_driver::run_phase] Starting driver // ── Filter by ID from command line ─────────────────────── // +uvm_set_verbosity=uvm_test_top.env.agent.drv,DRV,UVM_HIGH,run // Only shows UVM_HIGH DRV messages from the driver component
Some debug operations are expensive — calling item.print(), formatting a long string, or computing a diagnostic value. If these are guarded by a verbosity check, they are skipped unless the current verbosity level would display the result.
// ── Guard expensive operations with verbosity check ─────── task run_phase(uvm_phase phase); apb_seq_item item; forever begin seq_item_port.get_next_item(item); // Only call item.print() if UVM_HIGH would be displayed if (uvm_report_enabled(UVM_HIGH)) item.print(); // skipped if verbosity < UVM_HIGH drive_transfer(item); seq_item_port.item_done(); end endtask // ── Avoid expensive $sformatf when it won't be printed ──── if (uvm_report_enabled(UVM_FULL)) begin string dump = build_register_dump(); // only computed if needed `uvm_info("REG", dump, UVM_FULL) end
By default, UVM stops the simulation when 5 `uvm_error messages fire — the max_quit_count. This prevents a runaway test from generating thousands of error messages and filling log files. The threshold can be configured:
// ── Set max error count before stopping ─────────────────── // Default = 5. Set to 0 for unlimited (never stop on errors) // Call from start_of_simulation_phase or build_phase uvm_root::get().set_report_max_quit_count(20); // stop after 20 errors uvm_root::get().set_report_max_quit_count(0); // never stop on errors // ── Command line ────────────────────────────────────────── // +UVM_MAX_QUIT_COUNT=20,YES // ── Query current error and warning counts ──────────────── int err_count = uvm_report_server::get_server().get_severity_count(UVM_ERROR); int warn_count = uvm_report_server::get_server().get_severity_count(UVM_WARNING); // ── Check counts in check_phase ─────────────────────────── function void check_phase(uvm_phase phase); int errs = uvm_report_server::get_server().get_severity_count(UVM_ERROR); if (errs > 0) `uvm_fatal("CHK", $sformatf("%0d errors during run", errs)) endfunction
The report server allows overriding the default action for specific severity + ID combinations — for example, demoting expected errors to warnings, or promoting certain warnings to errors for a specific test.
// ── Override action for a specific ID ───────────────────── // Actions: UVM_NO_ACTION, UVM_DISPLAY, UVM_COUNT, UVM_STOP, UVM_EXIT, // UVM_LOG (to file), UVM_RM_RECORD // Demote UVM_ERROR for ID "SB" to just display (no count, no stop) set_report_severity_id_override(UVM_ERROR, "SB", UVM_WARNING); // Silence UVM_WARNING from monitor (expected during reset) set_report_id_action(UVM_WARNING, "MON", UVM_NO_ACTION); // Make a specific info message always print regardless of verbosity set_report_severity_action(UVM_INFO, UVM_DISPLAY | UVM_COUNT); // Redirect all errors to a log file AND display int fd = $fopen("errors.log", "w"); set_report_severity_action(UVM_ERROR, UVM_DISPLAY | UVM_LOG); set_report_default_file(fd); // ── Per-component overrides ─────────────────────────────── m_driver.set_report_severity_action(UVM_WARNING, UVM_NO_ACTION); // Silence all warnings from this driver
| Practice | Reason |
|---|---|
Use consistent IDs per component ("DRV", "MON", "SB") | Makes grep-based log filtering fast and reliable in regressions |
| Reserve UVM_LOW for milestones and PASS/FAIL | Default runs produce clean, readable transcripts without detail clutter |
| Put per-cycle detail at UVM_HIGH or UVM_FULL | Zero performance overhead in regression; full detail available on demand |
Guard item.print() and expensive formatting with uvm_report_enabled() | Avoids CPU cost of building strings that will be filtered anyway |
Use `uvm_error for verification failures, not `uvm_fatal | Allows multiple errors to accumulate; complete mismatch picture before stopping |
Use `uvm_fatal only for infrastructure failures (null handle, no vif) | Unrecoverable — stopping immediately is correct; continuing would produce spurious errors |
| Include convert2string() in error messages | Full transaction context visible in the log — no need to add extra debug runs |
| Set max_quit_count in base_test, not hardcoded in components | Tests can override threshold for specific scenarios without recompile |
| Item | Key fact |
|---|---|
| `uvm_info syntax | `uvm_info("ID", message, verbosity) — filtered by verbosity |
| `uvm_warning syntax | `uvm_warning("ID", message) — always printed, never filtered |
| `uvm_error syntax | `uvm_error("ID", message) — always printed, increments error count |
| `uvm_fatal syntax | `uvm_fatal("ID", message) — always printed, stops simulation immediately |
| Default verbosity | UVM_MEDIUM — shows UVM_NONE, UVM_LOW, UVM_MEDIUM messages |
| Verbosity logic | Message shown if message_verbosity ≤ component_verbosity. Lower = more important. |
| Set global verbosity | uvm_root::get().set_report_verbosity_level_hier(UVM_HIGH) |
| Set component verbosity | component.set_report_verbosity_level(UVM_HIGH) |
| Command-line global | +UVM_VERBOSITY=UVM_HIGH |
| Command-line per-component | +uvm_set_verbosity=path,id,level,phase |
| Guard expensive ops | if (uvm_report_enabled(UVM_HIGH)) item.print() |
| Error count threshold | uvm_root::get().set_report_max_quit_count(N) — default 5, 0=unlimited |
| Command-line threshold | +UVM_MAX_QUIT_COUNT=20,YES |
| Query error count | uvm_report_server::get_server().get_severity_count(UVM_ERROR) |
| Override severity action | set_report_severity_id_override(UVM_ERROR, "ID", UVM_WARNING) |