UVM Reporting

Standardized messaging using macros like `uvm_info, `uvm_error, and `uvm_fatal.

Foundation: The Reporting Macros

UVM gives you a smart way to print messages. Instead of using the basic Verilog $display (which is just dumb text), UVM provides powerful Macros. These let you tag messages with importance levels, filter them loops (like "only show errors"), and even change them on the fly without rewriting code.

New to these terms?
  • Macro: A shortcut (starts with `) that expands into more complex code.
  • Verbosity: How "chatty" your testbench is. Low verbosity = quiet (errors only), High = noisy (debug info).
  • Simulation Impact: What happens to the simulation (continue, stop, or count error).

1. Severity Levels

Macro Simulation Impact Standard Usage
`uvm_info None. Tracking flow, printing transaction data.
`uvm_warning None (usually). Potential issues that aren't failures (e.g., unusual but legal packet).
`uvm_error Increments Error Count. Data mismatches, protocol violations.
`uvm_fatal Terminates immediately. Hardware reset failures, missing config files.
Syntax Example

// `uvm_info(ID, MESSAGE, VERBOSITY)
`uvm_info("DRV", $sformatf("Driving packet with addr: %h", req.addr), UVM_MEDIUM)
// `uvm_error(ID, MESSAGE) -> No verbosity needed!
`uvm_error("SCOREBOARD", "In-flight queue should be empty at EOF!")
                            

Advanced Verbosity Control

Verbosity prevents "Log Spalling" (excessive debugging output). Only messages with a verbosity less than or equal to the current threshold will print.

Standard Levels:

UVM_NONE (0) | UVM_LOW (100) | UVM_MEDIUM (200) | UVM_HIGH (300) | UVM_FULL (400) | UVM_DEBUG (500)
Changing Levels at Runtime

// 1. Via Command Line (No re-compile!)
// +UVM_VERBOSITY=UVM_HIGH
// 2. Set for a specific component only
env.agent.driver.set_report_verbosity_level(UVM_DEBUG);
// 3. Set for a specific ID only
set_report_id_verbosity("MY_ID", UVM_FULL);
                            

Report Actions & Severities

An Action defines what the UVM Report Server does when a message is triggered. Multiple actions can be XOR-ed together.

Common Actions

UVM_DISPLAY | UVM_LOG   // Print to screen and write to file
UVM_COUNT               // Increment the global error counter
UVM_EXIT                // Stop simulation immediately (default for FATAL)
UVM_NO_ACTION           // Silence the message completely
                            

Why change actions?

Imagine a legacy verification IP (VIP) is throwing UVM_ERROR messages for a protocol check that you know is invalid for your current project. Instead of editing the VIP, you can simply:

my_vip.set_report_id_action("INVALID_CHK", UVM_NO_ACTION);

Expert: The Report Catcher

A uvm_report_catcher is a powerful callback mechanism that allows you to inspect every message before it reaches the server. You can modify its severity, change its string, or "demote" an error.

Example: Demoting a Spurious Error

class error_demoter extends uvm_report_catcher;
    virtual function action_e catch();
        if (get_severity() == UVM_ERROR && get_id() == "KNOWN_BUG_ID") begin
            set_severity(UVM_INFO);
            set_verbosity(UVM_LOW);
            `uvm_info("DEMOTER", "Demoted KNOWN_BUG_ID to INFO", UVM_LOW)
        end
        return THROW; // Ensure message still gets processed
    endfunction
endclass
// In your Test:
error_demoter demoter = new();
uvm_report_cb::add(null, demoter);