Last Updated: September 24, 2013
One of the benefits of using the standard verification methodology such as OVM, is unified message formatting. Pre-defined format would ease the automatic search and post-processing of the messages. Although the default format is sufficient most of the time, customization of the format may be sometimes required to meet project-wide need, etc. A series of articles will be provided to show you the step-by-step instructions to customize the message formatting, namely for OVM, UVM and VMM.
Let’s start with OVM. I used the OVM version 2.1.1 for this article.
Step 0 – Default Format
Before changing the message format, let’s look at how the default output looks using `ovm_info
macro:
# OVM_INFO my_ovm_report.sv(84) @ 0: reporter [top] This is a message from top. # OVM_INFO my_ovm_report.sv(69) @ 0: ovm_test_top [my_test] This is a message from my_test. # OVM_INFO my_ovm_report.sv(39) @ 0: ovm_test_top.my_env_h [my_env] This is a message from my_env. |
Step 1 – Define Your Format
The first step is defining your custom format. This is done by overriding the compose_message
function of ovm_report_server
class. I created my_report_server
class to define the compose_message
function. The compose_message
function constructs a string from severity, component name, report id, and message itself. Lines 9 and 10 define the actual formatting. Note that I casted severity
from ovm_severity
, which is nothing but bit [1:0]
, to ovm_severity_type
, which is an enum
, in order to show a severity string (line 8). FYI, the ovm_severity
and ovm_severity_type
are defined in ovm-2.1.1/src/base/ovm_object_globals.svh
.
1 2 3 4 5 6 7 8 9 10 11 12 | class my_report_server extends ovm_report_server; virtual function string compose_message( ovm_severity severity, string name, string id, string message, string filename, int line ); ovm_severity_type severity_type = ovm_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 |
Step 2 – Use Your Format
The second step is replacing the ovm_report_server
with my_report_server
. The ovm_report_server
is a global server that processes all the reports generated by an ovm_report_handler
, which in turn is the class to which most methods in ovm_report_object
delegate. I could not find a method to set the global server in the OVM documents, so I did a source code search and found the following way. If you know a better way to do it, please leave me a comment. By the way, UVM has a method to do the job (see my another article, Customizing UVM Message Format if you are interested).
Here are my procedures to replace the server for OVM. Firstly, get the underlying report handler to which reporting tasks are delegated (line 4). Secondly, instantiate my_report_server
(line 5). Finally, set my server as the global report server (line 6). Note that the m_glob
is not documented, but it looks working. I used the start_of_simulation()
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 | class my_test extends ovm_test; // ... function void start_of_simulation(); ovm_report_handler report_handler = get_report_handler(); my_report_server my_server = new; report_handler.m_glob.set_server( my_server ); endfunction: start_of_simulation endclass: my_test |
Step 3 – See Your New Format
Let’s see how the new output looks:
# OVM_INFO my_ovm_report.sv(84) @ 0: reporter [top] This is a message from top. # OVM_INFO | my_ovm_report.sv | 69 | 0 | ovm_test_top | my_test | This is a message from my_test. # OVM_INFO | my_ovm_report.sv | 39 | 0 | ovm_test_top.my_env_h | my_env | This is a message from my_env. |
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 article helps.