UVM Tutorial for Candy Lovers – 28. Message Logging

In the previous article, we explained how to filter messages using a verbosity threshold. This article explains how to send the messages to a file (or files).

Message Example

As an example, we added several message macros with different severity to the functional coverage subscriber.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class jelly_bean_fc_subscriber extends uvm_subscriber#( jelly_bean_transaction );
  // ...
  function void write( jelly_bean_transaction t );
    jb_tx = t;
    jelly_bean_cg.sample();
 
    //_SEVERITY_  _ID__  ___________________MESSAGE____________________
    `uvm_info   ( "id1", { t.color.name(), " ", t.flavor.name(), " 1" }, UVM_NONE )
    `uvm_info   ( "id2", { t.color.name(), " ", t.flavor.name(), " 2" }, UVM_NONE )
    `uvm_warning( "id1", { t.color.name(), " ", t.flavor.name(), " 3" } )
    `uvm_warning( "id2", { t.color.name(), " ", t.flavor.name(), " 4" } )
    `uvm_error  ( "id1", { t.color.name(), " ", t.flavor.name(), " 5" } )
    `uvm_error  ( "id2", { t.color.name(), " ", t.flavor.name(), " 6" } )
    `uvm_fatal  ( "id1", { t.color.name(), " ", t.flavor.name(), " 7" } )
    `uvm_fatal  ( "id2", { t.color.name(), " ", t.flavor.name(), " 8" } )
  endfunction: write
endclass: jelly_bean_fc_subscriber

The following figure summarizes the messages defined in the subscriber.

Messages Defined in the Scoreboard
Messages Defined in the Subscriber

Preparation

Opening File Descriptors

In this article, we will write to four files (default_file, warning_file, id1_file, and warning_id1_file). We open the file descriptors in the start_of_simulation_phase (lines 8 to 11).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class jelly_bean_test extends uvm_test;
  protected int default_fd; // file descriptor
  protected int warning_fd;
  protected int id1_fd;
  protected int warning_id1_fd;
  // ...
  function void start_of_simulation_phase( uvm_phase phase );
    default_fd     = $fopen( "default_file",     "w" );    warning_fd     = $fopen( "warning_file",     "w" );    id1_fd         = $fopen( "id1_file",         "w" );    warning_id1_fd = $fopen( "warning_id1_file", "w" );    // ...
  endfunction: start_of_simulation_phase
endclass: jelly_bean_test

Setting Reporting Actions

By default, no message is sent to the files because the default actions are defined as follows:

Severity Default Actions Description
UVM_INFO UVM_DISPLAY Sends the message to the standard out
UVM_WARNING UVM_DISPLAY Sends the message to the standard out
UVM_ERROR UVM_DISPLAY | UVM_COUNT Sends the message to the standard out;
Terminates the simulation if the number of messages exceeds the number specified by the +UVM_MAX_QUIT_COUNT (default is 0)
UVM_FATAL UVM_DISPLAY | UVM_EXIT Sends the message to the standard out;
Terminates the simulation immediately

set_report_severity_action

In order to send the messages to a file, we need to add the UVM_LOG action to each severity using the set_report_severity_action function (lines 5 to 8).

1
2
3
4
5
6
7
8
9
10
11
class jelly_bean_test extends uvm_test;
  // ...
  function void start_of_simulation_phase( uvm_phase phase );
    // ...                                   _SEVERITY__  _______ACTIONS_______
    jb_env.jb_fc.set_report_severity_action( UVM_INFO,    UVM_DISPLAY | UVM_LOG );    jb_env.jb_fc.set_report_severity_action( UVM_WARNING, UVM_DISPLAY | UVM_LOG );    jb_env.jb_fc.set_report_severity_action( UVM_ERROR,   UVM_DISPLAY | UVM_LOG );    jb_env.jb_fc.set_report_severity_action( UVM_FATAL,   UVM_DISPLAY | UVM_LOG );    // ...
  endfunction: start_of_simulation_phase
endclass: jelly_bean_test

We removed the UVM_COUNT and UVM_EXIT actions from the UVM_ERROR and UVM_FATAL so that a simulation continues even after hitting an error. You should probably keep them in a real test-bench, though.

You can set ID-specific action using set_report_id_action, and severity-and-ID-specific action using set_report_severity_id_action, too. See the UVM manual for the detail.

Sending Messages to a File

set_report_default_file

If you just want to direct the messages to a file, you can use the set_report_default_file function. The following code sends the messages issued by the functional coverage subscriber to the default_file (line 5).

1
2
3
4
5
6
7
class jelly_bean_test extends uvm_test;
  // ...
  function void start_of_simulation_phase( uvm_phase phase );
    // ...                                FILE_DESCRIPTOR
    jb_env.jb_fc.set_report_default_file( default_fd );  endfunction: start_of_simulation_phase
endclass: jelly_bean_test
Messages Sent to a Default File
Sending Messages to a Default File

When you run a simulation, the default_file will store the messages like this:

UVM_INFO /home/runner/env.svh(40) @ 25: uvm_test_top.jb_env.jb_fc [id1] GREEN BUBBLE_GUM 1
UVM_INFO /home/runner/env.svh(41) @ 25: uvm_test_top.jb_env.jb_fc [id2] GREEN BUBBLE_GUM 2
UVM_WARNING /home/runner/env.svh(42) @ 25: uvm_test_top.jb_env.jb_fc [id1] GREEN BUBBLE_GUM 3
UVM_WARNING /home/runner/env.svh(43) @ 25: uvm_test_top.jb_env.jb_fc [id2] GREEN BUBBLE_GUM 4
UVM_ERROR /home/runner/env.svh(44) @ 25: uvm_test_top.jb_env.jb_fc [id1] GREEN BUBBLE_GUM 5
UVM_ERROR /home/runner/env.svh(45) @ 25: uvm_test_top.jb_env.jb_fc [id2] GREEN BUBBLE_GUM 6
UVM_FATAL /home/runner/env.svh(46) @ 25: uvm_test_top.jb_env.jb_fc [id1] GREEN BUBBLE_GUM 7
UVM_FATAL /home/runner/env.svh(47) @ 25: uvm_test_top.jb_env.jb_fc [id2] GREEN BUBBLE_GUM 8

Setting Severity-specific File

set_report_severity_file

If you want to direct the messages with a specific severity to a separate file, you can do so using the set_report_severity_file function. For example, you can store the messages with UVM_WARNING severity to the warning_file as follows (line 5):

1
2
3
4
5
6
7
class jelly_bean_test extends uvm_test;
  // ...
  function void start_of_simulation_phase( uvm_phase phase );
    // ...                                 _SEVERITY__  FILE_DESCRIPTOR
    jb_env.jb_fc.set_report_severity_file( UVM_WARNING, warning_fd );  endfunction: start_of_simulation_phase
endclass: jelly_bean_test

Note that in our example, we still set the default file as we did in the previous section. Severity-specific file takes precedence over the default file.

Setting Severity-specific File
Directing Severity-specific Messages

When you run a simulation, the default_file will store the messages like this:

UVM_INFO /home/runner/env.svh(40) @ 25: uvm_test_top.jb_env.jb_fc [id1] GREEN BUBBLE_GUM 1
UVM_INFO /home/runner/env.svh(41) @ 25: uvm_test_top.jb_env.jb_fc [id2] GREEN BUBBLE_GUM 2
UVM_ERROR /home/runner/env.svh(44) @ 25: uvm_test_top.jb_env.jb_fc [id1] GREEN BUBBLE_GUM 5
UVM_ERROR /home/runner/env.svh(45) @ 25: uvm_test_top.jb_env.jb_fc [id2] GREEN BUBBLE_GUM 6
UVM_FATAL /home/runner/env.svh(46) @ 25: uvm_test_top.jb_env.jb_fc [id1] GREEN BUBBLE_GUM 7
UVM_FATAL /home/runner/env.svh(47) @ 25: uvm_test_top.jb_env.jb_fc [id2] GREEN BUBBLE_GUM 8

The warning_file will store the messages like this:

UVM_WARNING /home/runner/env.svh(42) @ 25: uvm_test_top.jb_env.jb_fc [id1] GREEN BUBBLE_GUM 3
UVM_WARNING /home/runner/env.svh(43) @ 25: uvm_test_top.jb_env.jb_fc [id2] GREEN BUBBLE_GUM 4

Setting ID-specific File

set_report_id_file

If you want to direct the messages with a specific ID to a separate file, you can do so using the set_report_id_file function. For example, you can store the messages with "id1" to the id1_file as follows (line 5):

1
2
3
4
5
6
7
class jelly_bean_test extends uvm_test;
  // ...
  function void start_of_simulation_phase( uvm_phase phase );
    // ...                           _ID__  FILE_DESCRIPTOR
    jb_env.jb_fc.set_report_id_file( "id1", id1_fd );  endfunction: start_of_simulation_phase
endclass: jelly_bean_test

Note that in our example, we still set the default file and severity-specific file as we did in the previous sections. ID-specific file takes precedence over the severity-specific file (and default file).

Setting ID-specific File
Directing ID-specific Messages

When you run a simulation, the default_file will store the messages like this:

UVM_INFO /home/runner/env.svh(41) @ 25: uvm_test_top.jb_env.jb_fc [id2] GREEN BUBBLE_GUM 2
UVM_ERROR /home/runner/env.svh(45) @ 25: uvm_test_top.jb_env.jb_fc [id2] GREEN BUBBLE_GUM 6
UVM_FATAL /home/runner/env.svh(47) @ 25: uvm_test_top.jb_env.jb_fc [id2] GREEN BUBBLE_GUM 8

The warning_file will store the messages like this:

UVM_WARNING /home/runner/env.svh(43) @ 25: uvm_test_top.jb_env.jb_fc [id2] GREEN BUBBLE_GUM 4

The id1_file will store the messages like this:

UVM_INFO /home/runner/env.svh(40) @ 25: uvm_test_top.jb_env.jb_fc [id1] GREEN BUBBLE_GUM 1
UVM_WARNING /home/runner/env.svh(42) @ 25: uvm_test_top.jb_env.jb_fc [id1] GREEN BUBBLE_GUM 3
UVM_ERROR /home/runner/env.svh(44) @ 25: uvm_test_top.jb_env.jb_fc [id1] GREEN BUBBLE_GUM 5
UVM_FATAL /home/runner/env.svh(46) @ 25: uvm_test_top.jb_env.jb_fc [id1] GREEN BUBBLE_GUM 7

Setting Severity-and-ID-specific File

set_report_severity_id_file

If you really want to direct the messages with a specific severity and a specific ID to a separate file, you can do so using the set_report_severity_id_file function. For example, you can store the messages with UVM_WARNING severity and "id1" to the warning_id1_file as follows (line 5):

1
2
3
4
5
6
7
class jelly_bean_test extends uvm_test;
  // ...
  function void start_of_simulation_phase( uvm_phase phase );
    // ...                                    _SEVERITY__  _ID__  FILE_DESCRIPTOR
    jb_env.jb_fc.set_report_severity_id_file( UVM_WARNING, "id1", warning_id1_fd );  endfunction: start_of_simulation_phase
endclass: jelly_bean_test

Note that in our example, we still set the default file, severity-specific file, and ID-specific file as we did in the previous sections. Severity-and-ID-specific file takes the highest precedence.

Setting Severity-and-ID-specific File
Directing Severity-and-ID-specific Messages

When you run a simulation, the default_file will store the messages like this:

UVM_INFO /home/runner/env.svh(41) @ 25: uvm_test_top.jb_env.jb_fc [id2] GREEN BUBBLE_GUM 2
UVM_ERROR /home/runner/env.svh(45) @ 25: uvm_test_top.jb_env.jb_fc [id2] GREEN BUBBLE_GUM 6
UVM_FATAL /home/runner/env.svh(47) @ 25: uvm_test_top.jb_env.jb_fc [id2] GREEN BUBBLE_GUM 8

The warning_file will store the messages like this:

UVM_WARNING /home/runner/env.svh(43) @ 25: uvm_test_top.jb_env.jb_fc [id2] GREEN BUBBLE_GUM 4

The id1_file will store the messages like this:

UVM_INFO /home/runner/env.svh(40) @ 25: uvm_test_top.jb_env.jb_fc [id1] GREEN BUBBLE_GUM 1
UVM_ERROR /home/runner/env.svh(44) @ 25: uvm_test_top.jb_env.jb_fc [id1] GREEN BUBBLE_GUM 5
UVM_FATAL /home/runner/env.svh(46) @ 25: uvm_test_top.jb_env.jb_fc [id1] GREEN BUBBLE_GUM 7

Finally, the warning_id1_file will store the messages like this:

UVM_WARNING /home/runner/env.svh(42) @ 25: uvm_test_top.jb_env.jb_fc [id1] GREEN BUBBLE_GUM 3

EDA Playground

As always, you can view and run the code on EDA Playground.

2 thoughts on “UVM Tutorial for Candy Lovers – 28. Message Logging”

  1. set_report_severity_id_file etc function are define in “uvm_report_object”. So i can say that these function,we can use in class which is child of “uvm_report_object” (example : All component class) but what if i want to copy/move messages from the sequences. (Because uvm_sequence is not child of “uvm_report_object” they can’t use these function)

    1. A sequence uses the file setting of the sequencer it is running on. If the sequence is a virtual sequence (the sequencer is null), then the file setting of the uvm_top is used. For example:

      1
      2
      3
      4
      5
      6
      7
      
      // The following setting is used for the sequences running on the jb_env.jb_agent.jb_seqr
      jb_env.jb_agent.jb_seqr.set_report_severity_action ( UVM_WARNING, UVM_DISPLAY | UVM_LOG );
      jb_env.jb_agent.jb_seqr.set_report_severity_id_file( UVM_WARNING, "id1", warning_id1_fd );
       
      // The following setting is used for the virtual sequences
      uvm_top.set_report_severity_action ( UVM_WARNING, UVM_DISPLAY | UVM_LOG );
      uvm_top.set_report_severity_id_file( UVM_WARNING, "id1", warning_id1_fd );

Leave a Reply