uvm_report_catcher/uvm_error demoter Example

  • Sometimes user will face a situation where you need some of the components from environment to demote error message means user want to disable error from a specific component.
  • Of course user don’t want to change every uvm_error message to uvm_info..
  • It will take care of one of the amazing features from UVM i.e.  uvm_report_catcher class.
  • The uvm_report_catcher is used to catch messages issued by the uvm report server.
  • It means all four severity/message of `uvm_info , `uvm_error , `uvm_warning , `uvm_fatal can be registered and controlled by this UVM_REPORT_CATCHER.
  • It will catch messages using callbacks.
  • The uvm_callbacks#(<uvm_report_object>,uvm_report_catcher) class is aliased to “uvm_report_cb” to make it easier to use.

Let’s understand deeply through example


class my_err_demoter extends uvm_report_catcher;
  bit err_demoted;
  function new(string name="my_err_demoter");
  endfunction : new
  function action_e catch();
	if((get_severity() == UVM_ERROR) && 
        (get_message() == "CRC error generated."))begin
  	err_demoted = 1;
    return THROW;
  endfunction : catch
endclass : my_err_demoter
//Take a Instance of above class
my_error_demoter demote;
function void build_phase(uvm_phase phase);
// create a instance of this class
demote = my_error_demoter::type_id::create(“demote”,this);
// Now you need to add this class by simple callback to the component that you want to demote errors..
// To affect all reporters, use null for the object
uvm_report_cb::add(null, demoter);
// To affect some specific object use the specific reporter
uvm_report_cb::add(mytest.myenv.myagent.mydriver, demoter);
// To affect some set of components using the component name
uvm_report_cb::add_by_name(“*.*driver”, demoter);
endfunction : build_phase
  • You can add any component that you like from top and change severity to UVM_ERROR to UVM_INFO

There are four things in a message:

Message Id: The Id used to print message. Usually we prefer some key string representing class or get_type_name() function.

Message string: Actual message string.

Message Verbosity: Defines how much verbose a message is. UVM_NONE is most verbose message and must be printed/displayed each time. While the verbosity decreases going towards UVM_DEBUG (generally debug messages).

Message severity: Describes how severe action can it cause on the simulation. UVM_INFO is just for users information. UVM_ERROR for unexpected behavior and so on.

set_report_severity_id_override(<some_verbosity>,”<some_id>”,<some_other_verbosity>) replaces any verbosity messages with the given id to some other verbosity message. This means a UVM_ERROR can be converted to UVM_INFO. This works similar as the one shown above.

But, here the user would not get any freedom to control ALL the messages simultaneously. For example, you want to demote error to info for multiple; let’s say 50  components. Or, each time the user demotes an error, user needs to display some string. In this scenario, callback method is suitable.

One major difference is CATCH and THROW. By using callbacks, you can either CATCH the message (catch message, don’t display it) or THROW it (make necessary changes and display message).

So, overall I guess both the methods are suitable. Simply use set_report_severity_id_override to override message, use callback method when you want dynamic control over a large and dynamic environment.