Customizing Message Format in UVM 1.2

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 the uvm_default_report_server, which is a sub-class of the uvm_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.
How `uvm_info macro works
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.

EDA Playground

You can view and run the code on EDA Playground.

7 thoughts on “Customizing Message Format in UVM 1.2”

  1. 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.

    1. 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:

      function automatic string uppercase( int i );
         string s = $sformatf( "%0h", i );
         return s.toupper();
      endfunction: uppercase
       
      initial begin
         $display( uppercase( 'habcdef ) ); // ABCDEF
      end
  2. Shimizu-san, thank you for sharing this. I’m having some trouble, get_filename() is returning null, any clue?

    Thanks again.

    1. If you use the uvm_report_[info|warning|error|fatal] function to print a message, make sure you specify the filename 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 define UVM_REPORT_DISABLE_FILE or UVM_REPORT_DISABLE_FILE_LINE.

  3. 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

Leave a Reply