UVM Report Catcher - Filtering and Modifying Messages
During verification, you often encounter expected errors or warnings that shouldn't cause test failures. The uvm_report_catcher class provides a powerful mechanism to intercept, filter, and modify UVM messages before they're processed - enabling you to demote expected errors, promote warnings, or completely suppress known issues.
What is uvm_report_catcher?
uvm_report_catcher is a callback mechanism that intercepts messages from the UVM reporting system. When a component calls `uvm_error, `uvm_warning, or other report macros, registered catchers can:
- Modify severity: Demote errors to warnings/info, or promote warnings to errors
- Change message content: Alter the message text, ID, or verbosity
- Drop messages: Completely suppress specific reports
- Pass through: Let messages continue to other catchers or handlers
Report Catcher Flow
flowchart LR
A[uvm_error] --> B[Report Server]
B --> C{Catchers Registered?}
C -->|Yes| D[Call catch]
D --> E{Action?}
E -->|THROW| F[Next Catcher or Handler]
E -->|CAUGHT| G[Message Dropped]
C -->|No| F
F --> H[Display/Log]
Implementation Example
Let's build a report catcher that demotes specific error messages based on regex patterns.
Custom Report Catcher Class
class report_catcher extends uvm_report_catcher;
// Queue of message patterns to demote from ERROR to INFO
local string demoted_messages[$];
function new(string name);
super.new(name);
endfunction
// Called for every report message
function action_e catch();
if(get_severity() == UVM_ERROR) begin
string my_message = get_message();
// Check if message matches any demoted pattern
foreach(demoted_messages[msg]) begin
if(uvm_re_match(demoted_messages[msg], my_message) == 0) begin
$display("Demoting message: [%s]", my_message);
set_severity(UVM_INFO);
end
end
end
return THROW; // Pass to next catcher or handler
endfunction
// Register a message pattern for demotion (supports regex)
function void demote_message(string d_message);
demoted_messages.push_back(d_message);
endfunction
endclass
Test Using the Report Catcher
class test extends uvm_test;
`uvm_component_utils(test)
env m_env;
report_catcher m_report_catcher;
function new(string name, uvm_component parent);
super.new(name, parent);
endfunction
function void build_phase(uvm_phase phase);
m_env = env::type_id::create("m_env", this);
endfunction
task run_phase(uvm_phase phase);
phase.raise_objection(this);
// Create and configure report catcher
m_report_catcher = new("m_report_catcher");
// Demote errors matching this regex pattern
m_report_catcher.demote_message("error message 2) from e.*");
// Register catcher for specific component
uvm_report_cb::add(m_env, m_report_catcher);
#100;
// Remove catcher when no longer needed
uvm_report_cb::delete(m_env, m_report_catcher);
#100;
phase.drop_objection(this);
endtask
endclass
Environment Generating Errors
class env extends uvm_env;
`uvm_component_utils(env)
function new(string name, uvm_component parent);
super.new(name, parent);
endfunction
task run_phase(uvm_phase phase);
#1;
`uvm_error("MYENV", "error message 1) from env..") // Not caught
#50;
`uvm_error("MYENV", "error message 2) from env..") // Demoted to INFO
#50;
`uvm_error("MYENV", "error message 3) from env..") // After catcher removed
endtask
endclass
Return Actions
The catch() function returns an action_e value that controls message flow:
| Action | Behavior | Use Case |
|---|---|---|
THROW | Pass message to next handler | After modifying severity or content |
CAUGHT | Suppress message completely | Expected errors you don't want logged |
Accessor Methods
Inside catch(), use these methods to inspect and modify the current message:
Getters
| Method | Returns |
|---|---|
get_severity() | UVM_INFO, UVM_WARNING, UVM_ERROR, UVM_FATAL |
get_id() | Message ID string (e.g., "MYENV") |
get_message() | Message text |
get_verbosity() | Verbosity level (UVM_NONE, UVM_LOW, etc.) |
get_fname() | Source filename |
get_line() | Source line number |
get_client() | Reporting component handle |
Setters
| Method | Purpose |
|---|---|
set_severity() | Change message severity |
set_id() | Change message ID |
set_message() | Change message text |
set_verbosity() | Change verbosity level |
Common Use Cases
1. Demote Expected Errors
function action_e catch();
// Demote known timing violation during reset
if(get_id() == "TIMING" && get_message().match("during reset"))
set_severity(UVM_INFO);
return THROW;
endfunction
2. Promote Warnings to Errors
function action_e catch();
// Treat protocol warnings as errors in strict mode
if(strict_mode && get_severity() == UVM_WARNING)
if(get_id() == "PROTOCOL")
set_severity(UVM_ERROR);
return THROW;
endfunction
3. Count and Limit Messages
class limit_catcher extends uvm_report_catcher;
int msg_count[string];
int max_per_id = 10;
function action_e catch();
string id = get_id();
msg_count[id]++;
if(msg_count[id] > max_per_id) begin
if(msg_count[id] == max_per_id + 1)
`uvm_info("LIMIT", $sformatf("Suppressing further '%s' messages", id), UVM_NONE)
return CAUGHT; // Suppress after limit
end
return THROW;
endfunction
endclass
4. Log to Separate File
class file_logger_catcher extends uvm_report_catcher;
int log_file;
function new(string name, string filename);
super.new(name);
log_file = $fopen(filename, "w");
endfunction
function action_e catch();
if(get_severity() >= UVM_ERROR)
$fdisplay(log_file, "[%0t] %s: %s", $time, get_id(), get_message());
return THROW;
endfunction
endclass
Registration Methods
Per-Component Registration
// Add catcher to specific component
uvm_report_cb::add(m_env, m_report_catcher);
// Remove when done
uvm_report_cb::delete(m_env, m_report_catcher);
Global Registration
// Catch messages from all components
uvm_report_cb::add(null, m_report_catcher);
Temporary Disable
// Disable without removing
void'(m_report_catcher.callback_mode(0));
// Re-enable
void'(m_report_catcher.callback_mode(1));
Best Practices
- Be specific: Match exact IDs and message patterns to avoid suppressing real issues
- Document demotions: Comment why each message is being demoted
- Use regex carefully:
uvm_re_match()uses DPI regex - test patterns thoroughly - Scope appropriately: Register catchers on specific components, not globally, when possible
- Remove when done: Delete catchers after the expected error window passes
- Log demotions: Print when messages are demoted for debug visibility
Key Takeaways
uvm_report_catcherintercepts messages before they reach the report handler- Override
catch()to inspect and modify message attributes - Return
THROWto pass messages on,CAUGHTto suppress them - Register catchers per-component with
uvm_report_cb::add() - Use regex patterns for flexible message matching
- Essential for handling expected errors in negative tests and known issues
Report catchers are essential for robust testbenches - they let you handle expected errors gracefully while ensuring unexpected issues still cause test failures.
Part of the UVM Examples series. See also: UVM Barrier | UVM Heartbeat
Comments (0)
Leave a Comment