4 UVM Library Basics
40 function void write_outport2(mytx t);
4.8 UVM Message Facilities
While developing or using environments, users will need to print information or issue error messages. A user may want to get trace messages from a suspect component or filter out undesired errors. Verilog’s $display does not allow nonintrusive filtering and control of messages.
Changing the verbosity on the command line or via Tcl run-time commands does NOT require that you recompile and re-elaborate the design to observe different trace messages. UVM reporting services are built into all components and are derived from a parent uvm_report_object class. The services can also be used in SystemVerilog modules, interfaces and programs. The mechanism provides a simple solution for most requirements and the ability to customize them with flags, parameters and user-defined hooks.
4.8.1 UVM Message APIs
The messages facilities have a routine interface:
uvm_report_info(string id, string message, int verbosity = UVM_MEDIUM, string
uvm_report_info(string id, string message, int verbosity = UVM_MEDIUM, string filename = "", int line = 0);
uvm_report_warning(string id, string message, int verbosity = UVM_MEDIUM, string filename = "", int line = 0);
uvm_report_error(string id, string message, int verbosity = UVM_LOW, string filename = "", int line = 0);
uvm_report_fatal(string id, string message, int verbosity = UVM_NONE, string filename = "", int line = 0);
They also have a macro API:
‘uvm_info(string id, string message, int verbosity)
‘uvm_warning(string id, string message)
‘uvm_error(string id, string message)
‘uvm_fatal(string id, string message)
The macro API is recommended because it checks if a message needs to be printed before executing expensive string manipulation. The macros also automatically add the filename and line numbers.
The string id is a tag that can be used for filtering. The verbosity level is an integer value to indicate the relative importance of the message. If the value is smaller or equal to the current verbosity level, then the report is issued. For example, if the verbosity is set to 100, all messages coded with 101 and higher will not print.
An enumerated type called uvm_verbosity provides several standard verbosity levels including: UVM_NONE=0, UVM_LOW=100, UVM_MEDIUM=200, UVM_HIGH=300, UVM_FULL=400, UVM_DEBUG=500.
Note When using the message macros, verbosity is ignored for warnings, errors and fatal errors. This prevents verbosity modifications from hiding bugs. The verbosity parameter is retained in the routines for backward compatibility purposes. If a warning, error, or fatal error needs to be turned off, this can be done by setting the action to UVM_NOACTION. For example, to turn off a specific message in component mycomp that is an UVM_ERROR with id MYTAG, you might do the following in a test or testbench:
mycomp.set_report_severity_id_action(UVM_ERROR, "MYTAG", UVM_NO_ACTION);
4.8.2 Guidelines for Using UVM Messages
• The run-time differences between using the macro API and the routines has proven to be significant in many testbenches. Use the macros API whenever you can.
• To enable easy message control of a testbench that contains multiple components, use only the enumerated values. Also use this standard interpretation of verbosity levels:
• UVM_NONE—For non-maskable and critical message
• UVM_LOW—For maskable messages that are printed only rarely during simulation (for example, when is reset done)
• UVM_MEDIUM—Short messages that happen once per data item or sequence
• UVM_HIGH—More detailed per-data-item information, including printing the actual value of the packet and printing sub-transaction details
• UVM_FULL—Anything else, including message prints in specific methods (just to follow the algorithm of that method)
• UVM_DEBUG—Debug mode with internal developer debug messages
• For information messages we recommend using the get_type_name() as the id argument. It is easy to see how many messages came from the different components during a simulation run, and it can be a quick sanity check that all components operated properly. This usage also allows filtering by type.
• Sometimes users need to ignore warnings for a particular project needs or a certain test requirements. For malfunction-related reports (warnings, errors, and fatals), use a unique name as the id argument. This allows fine control of ignoring errors.
4.8.3 Modifying Message Verbosity
There are three ways to change the verbosity for debug:
• Command-line argument (simulator-dependent). For example, use:
% irun … +UVM_VERBOSITY=UVM_NONE
• Procedurally in SystemVerilog. For example:
set_report_verbosity_level_hier(UVM_MEDIUM);
• Tcl (run time). For example, use:
uvm_message uvm_test_top.uart_ctrl_tb.apb0 UVM_FULL
Note Changing the verbosity on the command line or by way of Tcl run-time commands does not require that you recompile and re-elaborate the design to see different trace message recording.
You can use the same message macros in the context of non class-based code too. The following example illustrates this in the context of an initial block inside a module:
Example 4–17 Using the Info Message within Modules
1 module test;
2 import uvm_pkg::*;
3 ‘include "uvm_macros.svh"
4 initial begin
5 uvm_report_info("TEST", "I am in the top-level test", UVM_NONE);
6 ‘uvm_info("TEST", "I am in the top-level test", UVM_NONE) 7 end
8 endmodule : test
The output of the previous snippet looks like this:
---UVM_INFO @ 0: reporter [TEST] I am in the top-level test
UVM_INFO ./messages.sv(13) @ 0: reporter [TEST] I am in the top-level test
---4.9 Callbacks
Callbacks, as with the factory, are a way to effect or monitor an environment from the outside. Callbacks are different from the factory in that an object developer must insert calls to specific callback methods/tasks inside of this class at points where he deems it appropriate for the user to take action. The callback users can then create their derived callback class and attach to one or more desired objects.
to take action. The callback users can then create their derived callback class and attach to one or more desired objects.
4.9.1 Using Callbacks
The use model of callbacks is broken into two parts, the developer piece and the user piece.
4.9.1.1 Developer
The first thing the developer must do is decide on an interface to make available. Often the callback function will include a reference to the object that is issuing the callback. And, it will include other information that is necessary for the callback user.
Using our example from “Hierarchy Information Functions”, we may want to add a callback to the city class which gets executed before it prints its parent/child information. To do this we would do something like:
1 typedef class city;