This is an update of the article, Customizing UVM Message Format, I wrote five years ago using UVM 1.0p1. This article shows how to customize message format using UVM 1.2.
Step 0 – Default Format
Before changing the message format, let’s look at how the default output looks when `uvm_info
macros are used:
UVM_INFO testbench.sv(86) @ 0: reporter [top] This is a message from top. UVM_INFO testbench.sv(41) @ 0: uvm_test_top.my_env_h [my_env] This is a message from my_env. UVM_INFO testbench.sv(71) @ 0: uvm_test_top [my_test] This is a message from my_test. |
Step 1 – Define Your Format
Prior to UVM 1.2
Prior to UVM 1.2, we overrode the compose_message
function of the uvm_report_server
class to customize the message format. For those of you who still uses older version of UVM such as UVM 1.1d, please see Customizing UVM Message Format for more detail.
1 2 3 4 5 6 7 8 9 10 11 12 | class my_report_server extends uvm_report_server; // prior to UVM 1.2 virtual function string compose_message( uvm_severity severity, string name, string id, string message, string filename, int line ); uvm_severity_type severity_type = uvm_severity_type'( severity ); return $psprintf( "%-8s | %16s | %2d | %0t | %-21s | %-7s | %s", severity_type.name(), filename, line, $time, name, id, message ); endfunction: compose_message endclass: my_report_server |
UVM 1.2
UVM 1.2 introduced a new class called uvm_report_message
which provides the common fields to all messages.
The first step is defining your custom format. This is done by overriding the compose_report_message
function of the uvm_default_report_server
class.
In UVM 1.2,
uvm_report_server
became a virtual class. We use theuvm_default_report_server
, which is a sub-class of theuvm_report_server
and provides the default implementation of the report server, as the base class.
I created my_report_server
class to define the compose_report_message
function. This function constructs a message string from a uvm_report_message
object. Lines 11 and 12 define the actual formatting. Note that uvm_severity
is an enum
in UVM 1.2, so the casting we did prior to UVM 1.2 (the line 8 above) is no longer required.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | class my_report_server extends uvm_default_report_server; virtual function string compose_report_message( uvm_report_message report_message, string report_object_name = "" ); uvm_severity severity = report_message.get_severity(); string name = report_message.get_report_object().get_full_name(); string id = report_message.get_id(); string message = report_message.get_message(); string filename = report_message.get_filename(); int line = report_message.get_line(); return $sformatf( "%-8s | %16s | %2d | %0t | %-21s | %-7s | %s", severity.name(), filename, line, $time, name, id, message ); endfunction: compose_report_message endclass: my_report_server |
Step 2 – Use Your Format
The second step is replacing the uvm_default_report_server
with my_report_server
. The uvm_default_report_server
is a global server that processes all the reports generated by a uvm_report_handler
, which in turn is the class to which most methods in uvm_report_object
delegate.
Here are my procedures to replace the server. Firstly, instantiate the my_report_server
(line 4). Secondly, set my_server
as the global report server using a static function of uvm_report_server
(line 7). That’s it. I used the start_of_simulation_phase
function of my_test
class to change the formatting, but it is up to you where you do it.
1 2 3 4 5 6 7 8 9 | class my_test extends uvm_test; // ... function void start_of_simulation_phase( uvm_phase phase ); my_report_server my_server = new; super.start_of_simulation_phase( phase ); uvm_report_server::set_server( my_server ); endfunction: start_of_simulation_phase endclass: my_test |
Step 3 – See Your New Format
Let’s see how the new output looks:
UVM_INFO testbench.sv(86) @ 0: reporter [top] This is a message from top. UVM_INFO | testbench.sv | 41 | 0 | uvm_test_top.my_env_h | my_env | This is a message from my_env. UVM_INFO | testbench.sv | 71 | 0 | uvm_test_top | my_test | This is a message from my_test. |
The first line still used the default format. This was because the message was displayed before the report server was replaced. This also demonstrates that a message format can be changed on the fly.
I hope this helps.
You can view and run the code on EDA Playground.
Hi Keisuke,
When printing an integer value in hexadecimal format, is there a way to print the alphabets (A through F) in Upper Case.
I tried using %H, however, it still printed values of A through F in lower case, just like when we use %h.
Does it depend on the simulator, or can UVM control it?
Thank you.
I think you always get hex numbers in lowercase regardless of using
%h
or%H
. You might want to define a function like this to display them in uppercase:Shimizu-san, thank you for sharing this. I’m having some trouble, get_filename() is returning null, any clue?
Thanks again.
If you use the
uvm_report_[info|warning|error|fatal]
function to print a message, make sure you specify thefilename
when you call it because the default is an empty string. If you use the`uvm_[info|warning|error|fatal]
macro, make sure you do not defineUVM_REPORT_DISABLE_FILE
orUVM_REPORT_DISABLE_FILE_LINE
.It worked, thanks
Hi Keisuke
I want to redirect the logs from certain uvm_components into their own files. Can you please help provide an example to show how this can be done?
Thanks
Rajdeep
Found it http://cluelogic.com/2015/05/uvm-tutorial-for-candy-lovers-message-logging/
sorry for the trouble.