Every UVM component inherits from uvm_report_object (see UVM Introduction), so it already has functions and macros for printing messages with a severity, an ID and a verbosity level. This article covers the four UVM reporting functions, the reporting macros that wrap them, and how verbosity decides what gets printed.

7 min read | Intermediate Level

What You'll Learn

  • Use uvm_report_info, uvm_report_warning, uvm_report_error and uvm_report_fatal
  • Why the `uvm_info family of macros is preferred over the functions
  • How a message's verbosity is compared with the component's threshold
  • Choose good message IDs and avoid common macro pitfalls

Syntax


// Functions
uvm_report_info    (ID, MESSAGE, VERBOSITY = UVM_MEDIUM, FILENAME = "", LINE = 0);
uvm_report_warning (ID, MESSAGE, VERBOSITY = UVM_NONE,   FILENAME = "", LINE = 0);
uvm_report_error   (ID, MESSAGE, VERBOSITY = UVM_NONE,   FILENAME = "", LINE = 0);
uvm_report_fatal   (ID, MESSAGE, VERBOSITY = UVM_NONE,   FILENAME = "", LINE = 0);

// Macros (preferred) - no trailing semicolon needed
`uvm_info    (ID, MESSAGE, VERBOSITY)
`uvm_warning (ID, MESSAGE)
`uvm_error   (ID, MESSAGE)
`uvm_fatal   (ID, MESSAGE)
  • ID - a short string that names the message type, used for filtering and in the end-of-test summary (required)
  • MESSAGE - the text to print, usually built with $sformatf (required)
  • VERBOSITY - the detail level of the message. It is optional for the functions and required for `uvm_info
  • FILENAME / LINE - source location to print. The macros fill these in automatically (optional)

Calling Functions

There are four basic reporting functions, one per severity. They all take an ID, a message and an optional verbosity level.


	uvm_report_* ("TAG", $sformatf ("[Enter the display message]"), VERBOSITY_LEVEL);

Here * can be info, warning, error or fatal. UVM defines six verbosity levels, each represented by an integer.


typedef enum {
   UVM_NONE    = 0,
   UVM_LOW     = 100,
   UVM_MEDIUM  = 200,
   UVM_HIGH    = 300,
   UVM_FULL    = 400,
   UVM_DEBUG   = 500
} uvm_verbosity;

Verbosity really matters only for uvm_report_info, which defaults to UVM_MEDIUM if you leave it out. Warnings, errors and fatals default to UVM_NONE, so they are always printed. A call to uvm_report_fatal ends the simulation after printing the report summary.


uvm_report_info (get_type_name (), $sformatf ("None level message"), UVM_NONE);
uvm_report_info (get_type_name (), $sformatf ("Low level message"), UVM_LOW);
uvm_report_info (get_type_name (), $sformatf ("Medium level message"), UVM_MEDIUM);
uvm_report_info (get_type_name (), $sformatf ("High level message"), UVM_HIGH);
uvm_report_info (get_type_name (), $sformatf ("Full level message"), UVM_FULL);
uvm_report_info (get_type_name (), $sformatf ("Debug level message"), UVM_DEBUG);

uvm_report_warning (get_type_name (), $sformatf ("Warning level message"));
uvm_report_error (get_type_name (), $sformatf ("Error level message"));
uvm_report_fatal (get_type_name (), $sformatf ("Fatal level message"));

The functions do not know where they were called from. To print the file name and line number, pass the compiler directives `__FILE__ and `__LINE__ as the last two arguments. This helps a lot during debug.


uvm_report_info (get_type_name (), $sformatf ("None level message - Display File/Line"), UVM_NONE, `__FILE__, `__LINE__);

File and line printing can be turned off for the reporting macros by defining UVM_REPORT_DISABLE_FILE_LINE at compile time, for example with +define+UVM_REPORT_DISABLE_FILE_LINE. This is a compile-time define, not a run-time plusarg.

Calling Macros

The UVM reporting macros print the file and line automatically, so there is no need to pass `__FILE__ and `__LINE__.


`uvm_info (get_type_name (), $sformatf ("[Driver] None level message"), UVM_NONE)
`uvm_info (get_type_name (), $sformatf ("[Driver] Low level message"), UVM_LOW)
`uvm_info (get_type_name (), $sformatf ("[Driver] Medium level message"), UVM_MEDIUM)
`uvm_info (get_type_name (), $sformatf ("[Driver] High level message"), UVM_HIGH)
`uvm_info (get_type_name (), $sformatf ("[Driver] Full level message"), UVM_FULL)
`uvm_info (get_type_name (), $sformatf ("[Driver] Debug level message"), UVM_DEBUG)

`uvm_warning (get_type_name (), $sformatf ("[Driver] Warning level message"))
`uvm_error (get_type_name (), $sformatf ("[Driver] Error level message"))
`uvm_fatal (get_type_name (), $sformatf ("[Driver] Fatal level message"))

The macros have a second, less obvious advantage: they check verbosity before building the message. In simplified form, `uvm_info expands to:


begin
  if (uvm_report_enabled (VERBOSITY, UVM_INFO, ID))          // Cheap check first
    uvm_report_info (ID, MESSAGE, VERBOSITY, `uvm_file, `uvm_line);
end

With a function call, the $sformatf string is built every time, even if the message is then filtered out. With the macro, a filtered message costs only the verbosity check. In a driver or monitor that runs millions of transactions, this saves real simulation time.

Prefer the macros in all new code. Use the functions only when you need an argument the macros do not offer, such as passing a different file and line.

Reading a Message Line

Each printed message follows the same format, which makes logs easy to search. For example:

UVM_INFO testbench.sv(41) @ 10: uvm_test_top.m_env.m_drv [DRV] Drive packet with addr=0x0

PartExampleMeaning
SeverityUVM_INFOInfo, warning, error or fatal
File and linetestbench.sv(41)Where the message was issued
Time@ 10Simulation time
Hierarchy pathuvm_test_top.m_env.m_drvThe component that reported it
ID[DRV]The ID passed as the first argument
MessageDrive packet with addr=0x0The text you provided

Where Does the Message Format Help?

Regression scripts rely on this fixed format. They search for lines starting with UVM_ERROR or UVM_FATAL to decide pass or fail, and group failures by ID to spot the same bug across hundreds of seeds.

Verbosity Levels

Verbosity controls whether a uvm_report_* call or `uvm_* macro is printed. Each component has a verbosity threshold, and a message is printed only if its verbosity is less than or equal to that threshold. The default threshold is UVM_MEDIUM.

For the six uvm_report_info calls above, the threshold decides which lines appear:

ThresholdInfo messages printed
UVM_LOWNone, Low
UVM_MEDIUM (default)None, Low, Medium
UVM_HIGHNone, Low, Medium, High
UVM_DEBUGAll six

The warning, error and fatal messages are printed at every threshold.

Change the threshold for the whole testbench without recompiling, using the plusarg +UVM_VERBOSITY=UVM_HIGH. To change it for one part of the hierarchy, see Reporting Classes.

Quick Check

Q: A component calls uvm_report_info("MON", msg) without a verbosity argument. Is the message printed when the simulation runs with +UVM_VERBOSITY=UVM_LOW?

Show Answer

No. The verbosity defaults to UVM_MEDIUM (200), which is above the UVM_LOW threshold (100).

Reporting from Sequences and Modules

The same macros work outside components:

  • Sequences and sequence items: messages are routed through the sequencer the sequence runs on, so they follow that sequencer's verbosity and actions.
  • Modules and interfaces: with uvm_pkg imported and the macros included, the macros call global versions of the reporting functions. These report through the top of the UVM hierarchy.

Where are Verbosity Levels Used?

A typical convention is UVM_LOW for test milestones, UVM_MEDIUM for one line per transaction, and UVM_HIGH or above for field-by-field dumps. Regressions run at UVM_LOW to keep logs small, and engineers raise the level only when rerunning a failing seed.

Common Mistakes

Mistake #1: Using a macro with a semicolon in an if-else without begin-end

Wrong:
if (ok) `uvm_info ("CHK", "pass", UVM_LOW); else `uvm_error ("CHK", "fail")
Right: drop the semicolon after the macro, or wrap each branch in begin ... end

Why? `uvm_info expands to a begin ... end block. With the semicolon, the compiler sees end; else, and the else no longer belongs to the if, which causes a syntax error.

Mistake #2: Putting changing values in the ID

Wrong: `uvm_info ($sformatf ("ADDR_%0h", addr), "write done", UVM_HIGH)
Right: `uvm_info ("WR_DONE", $sformatf ("write done addr=0x%0h", addr), UVM_HIGH)

Why? The ID is meant to identify a message type. If it changes with every transaction, ID-based filtering and actions cannot target it, and the end-of-test summary lists hundreds of one-off IDs.

Mistake #3: Building expensive strings with the function form in hot code

Calling uvm_report_info(..., $sformatf(...), UVM_HIGH) inside a monitor loop builds the string on every transaction, even in regressions where UVM_HIGH messages are filtered out. Use `uvm_info, which skips the formatting when the message would not print.

Practice Exercise

Challenge: Clean Up a Monitor's Messages

The monitor code below works, but its messages are hard to filter and slow in regressions. Rewrite it using macros, a fixed ID, and verbosity UVM_HIGH for the per-transaction dump.


// Original monitor code
uvm_report_info ($sformatf ("PKT_%0d", count), $sformatf ("addr=0x%0h data=0x%0h", pkt.addr, pkt.data));
if (pkt.parity_err)
  uvm_report_error ("MON", "parity error");
Hint

Move count from the ID into the message, pass the verbosity explicitly, and remember that macros need no semicolon.

Solution

// Fixed ID, count moved into the message, string built only when UVM_HIGH is enabled
`uvm_info ("MON_PKT", $sformatf ("pkt %0d: addr=0x%0h data=0x%0h", count, pkt.addr, pkt.data), UVM_HIGH)

if (pkt.parity_err)
  `uvm_error ("MON_PARITY", $sformatf ("parity error on pkt %0d", count))   // Always printed and counted

Using a separate ID for the parity error lets a test that injects parity errors on purpose demote just that ID, while all other errors still fail the test.

Summary

In this tutorial, you learned:

  • The four reporting functions are uvm_report_info, uvm_report_warning, uvm_report_error and uvm_report_fatal
  • Info messages default to UVM_MEDIUM verbosity, while warnings, errors and fatals default to UVM_NONE and always print
  • The `uvm_* macros add file and line automatically and skip building the message when it would be filtered
  • A message prints only if its verbosity is less than or equal to the component's threshold, UVM_MEDIUM by default
  • +UVM_VERBOSITY changes the threshold at run time, while UVM_REPORT_DISABLE_FILE_LINE is a compile-time define
  • Good IDs are short and fixed, and macros should not be followed by a semicolon in an if-else
Did you find what you were looking for?

Quiz

Test Your Knowledge

1 of 5 Score: 0 / 5