The default behavior of `uvm_error is to continue the simulation once the message is reported. Although one can argue over Accelera’s default choice, there are ways to stop the simulation on `uvm_error. I’ve tested them with UVM 1.1d and UVM 1.2 releases.
Using Simulator Arguments
Major simulators support the +uvm_set_action command-line argument to set a custom action for report messages:
For example, to stop the simulation on `uvm_error(“MY_ERROR”, “message”), use the following argument when invoking the simulator:
You can use _ALL_ instead of MY_ERROR to set the action for all errors, regardless of their id.
Using the uvm_component API
Call uvm_component.set_report_id_action_hier (string id,uvm_action action), for example after elaboration:
class basic_test extends uvm_test; function void end_of_elaboration_phase(uvm_phase phase); super.end_of_elaboration_phase(phase); set_report_id_action_hier("MY_ERROR", UVM_STOP); endfunction endclass
Pay Attention: objects vs. components vs. sequence items
To my surprise, the above configuration does not apply to `uvm_error calls from within an uvm_object, for example for config objects, even if created under the “uvm_test_top.*” or “basic_test” hierarchy…
For `uvm_error calls from within an uvm_sequence_item, the message is delegated to the enclosing sequencer, hence it is not behaving like an uvm_object. The component path is enhanced with the enclosing sequencer and the sequence hierarchy path.
My recommendation is to use a generous star path pattern (“*”) when working with simulator arguments:
or use the uvm_root component when working with the uvm_component API:
class basic_test extends uvm_test; function void end_of_elaboration_phase(uvm_phase phase); uvm_root top = uvm_root::get(); super.end_of_elaboration_phase(phase); top.set_report_id_action_hier("MY_ERROR", UVM_STOP); endfunction endclass
Underground Details for the Curious
The `uvm_error macro is defined as:
`define uvm_error(ID,MSG) \ begin \ if (uvm_report_enabled(UVM_NONE,UVM_ERROR,ID)) \ uvm_report_error (ID, MSG, UVM_NONE, `uvm_file, `uvm_line); \ end
That is the macro call is delegated to a uvm_report_error() function call. The function that is actually called depends on the context where the macro is used.
There are three relevant uvm_report_error() function definitions in the UVM library:
- uvm_report_object.uvm_report_error(). An uvm_component inherits from uvm_report_object.
- Global uvm_report_error() which delegates the call to uvm_root.uvm_report_error()
- uvm_sequence_item.uvm_report_error() which delegates the call to its sequencer, if it exists or to uvm_root.