Debugging Uvm Error
Debugging Uvm Error
Abstract— This paper first outlines current debug capability In this situation, the system messages inside the UVM
embedded within the UVM library and then proposes additions Class Library become very important for users in order to
to this capability that can significantly add visibility and understand or debug the testbench execution. Currently, there
debugability into the execution of the testbench as an integral are some system messages in the UVM library, for example,
part of the entire environment. Ideas for presenting the tracing messages for phasing/objection, and auditing messages
additional acquired debug information to the user are also for config_db/resource_db. However, these are not enough to
introduced. cover all the key UVM functions and important stages of the
testbench execution. Without system messages as tracing
Keywords— UVM; SystemVerilog; testbench; debug;
points, it is virtually impossible to collect any useful dynamic
debugging; tracing message; transaction; recording
testbench data.
I. INTRODUCTION In this paper, we are going to discuss the benefits that can
The Universal Verification Methodology (UVM) has now be derived from inserting some additional system messages
established itself as the standard methodology of choice for inside the UVM Class library. We have experimental data from
improving verification efficiency and data portability, adding system messages on two major aspects of the UVM: the
including reuse and interoperability. The methodology includes testbench structure and transaction flow. The paper will further
a SystemVerilog class library that allows users to efficiently illustrate how to capture the data from UVM system messages
build realistic transaction-based testbenches. directly into a debug database and how to make use of the
database to improve the efficiency of post-simulation analysis
The raw SystemVerilog language does not provide any and debug. Enhanced visualization applications can be built on
standard mechanisms for recording simulation activity for the top of the collected data to better understand and debug the
class-based structures used in UVM as it does for HDL signals UVM testbench simulation.
and nets with the callback-driven Verilog Procedural Interface
(VPI) standard. It can be further argued that even if such an II. CURRENT UVM DEBUGGING CAPABILITIES AND
application programming interface (API) exists, the low-level LIMITATIONS
data returned would be of limited use in today’s high-level
verification environments in which the transaction is the atom The UVM Class Library [1] provides the building blocks
of data. In fact, the library itself is turning out to be the best needed to efficiently develop well-constructed, reusable
candidate for acquiring useful debug data at the appropriate verification components and test environments using the
abstraction level. SystemVerilog language and especially relies on its object-
oriented syntax and semantics. While the UVM is trying to
Ideally, a debugging system should be able to be attached to strike a balance on reuse, portability, and encapsulation of the
the UVM Class Library as a library extension, so that it can verification components for testbenches, the issues of
dynamically access and process the internal testbench data extensibility and debug have yet to be fully addressed.
during simulation. Unfortunately, the UVM Class Library does
not provide an open mechanism to allow the development of Extensibility, in this case, means the UVM should provide
reusable extensions. It does provide so-called callback open interfaces so that library extensions can be developed by
functions, but these are actually virtual functions of a base vendors or CAD groups and attached to the UVM library.
class. The virtual function-based callbacks are restricted and During simulation, all the library extensions could be closely
only the extended class can make use of these callbacks. In combined with the UVM library and passively join the UVM
other words, the implementations of the callbacks can be only execution. These extensions could transparently collect and
developed inside a specific testbench. They are not library process the dynamic data and monitor the flow in UVM-based
extensions and, therefore, cannot be reused in other testbenches, without modifying the testbench behavior. The
testbenches. library extension should be separate from the original UVM
library, and there should be no need to modify any original
code inside the UVM library. The library extension should also Tracing messages are another mechanism provided by the
be separate from the user’s UVM-based testbench, such that it UVM library to dump debug information, similar to debugging
is attached to the UVM library and can be reused by any UVM- messages that can be output from any software system. These
based testbenches. The testbench developers do not need to messages are embedded inside the UVM library at the major
have any knowledge about the library extensions. Note that points of the execution, enabling important runtime data to be
fundamentally, extensibility is one aspect of reusability. Here observed, collected and printed to the screen or a log file. Users
we are focusing on library extensible and reusable capabilities. can turn on each portion of the tracing messages by activating
them from the command line options. The following lists the
One analogy of such extensibility is the Verilog PLI command line arguments provided by UVM to turn on these
(Programming Language Interface) as an open simulation tracing messages:
interface. The PLI allows users to extend Verilog by creating
user-defined system tasks and registering user-defined hook
functions, such that the hook functions are called when a signal
value or any other simulation state changes. The hook functions +UVM_PHASE_TRACE turns on tracing of phase
can collect many current-state values from the simulation and executions
can return values back to simulation. The Verilog PLI has been +UVM_OBJECTION_TRACE turns on tracing of
the key technology to facilitate the post-simulation debugging objection activities
for HDL designs, without which we would be stuck in the
stone age of interactive simulation debugging. The waveform +UVM_RESOURCE_DB_TRACE turns on tracing of
of value changes for each signal in the HDL design can be resource DB access (read
recorded into a database for further processing and & write)
visualization using the Verilog PLI technology. Unfortunately, +UVM_CONFIG_DB_TRACE turns on tracing of
this technology does not work well for the object-oriented part configuration DB access
of the SystemVerilog language, which is more like a software
language. The SystemVerilog Testbench (SVTB) class
variables are dynamic data and therefore cannot be dumped.
These tracing messages turn out to be a very convenient
However, library extensions as previously discussed would and efficient mechanism for debugging. Nevertheless, there are
greatly facilitate a proper debugging system for the UVM two major drawbacks: 1) it does not cover all the functionalities
library and UVM-based testbenches. For example, testbench of the UVM; 2) it can only be output to a text format log file,
developers or users may want to log or record the important which is difficult for post processing. We will address these
details of UVM execution to help with testbench two issues in the following two sections.
comprehension or post-simulation debugging. Currently, they
have to manually instrument debugging code within the III. ADDING NEW TRACING MESSAGES INTO THE UVM
testbench code or inside the library which is generic to all CLASS LIBRARY
UVM-based testbenches. They are forced to duplicate these For the first issue of limited tracing messages being
debug instrumentation in all the testbenches, or alternatively, recorded, the resolution is quite simple: add new tracing
modify the UVM library and put the code inside the library. messages into the UVM library. We propose that tracing
The modified UVM library will, however, have the portability messages be added at least in the following categories of UVM
issue. functionalities:
In fact, the current UVM library does include a minimal set • Trace how the component hierarchy is built and how
of useful features for debugging purpose. For example, a the ports/sockets are connected;
transaction recording scheme [2] is provided to record UVM
sequence behavior and contents into preferred database via • Trace the UVM factory registration and override
uvm_recorder. The uvm_recorder maintains a set of virtual configuration;
functions that are originally empty but can be re-implemented • Trace the traffic at the TLM1 port interface and
by extending the uvm_recorder and replacing the capture the pass-through transactions, requests and
uvm_default_recorder. These so-called “hook” functions in responses, etc.;
uvm_default_recorder are automatically called at the key stages
of sequence generation, and the transaction timing, payload and • Trace the TLM2 socket interface and capture the pass-
layering information can be recorded through the “hook” through transaction (the generic payload), sync, phase,
functions. It is up to the user’s implementation of “hook” and basic protocol, etc.; and
functions how, where and what information is recorded, which • Trace the register access (read and write, mirror, etc)
leaves space for extensibility. While it is a good utility for and how the register hierarchy has been built.
debug, the transaction recording only covers one part (sequence
generation) of the UVM at a fairly high level. It is of no help In this paper, we will discuss how to add new tracing
when the user wants to look at the transaction transitions across messages in order to observe testbench structure generation
the UVM component hierarchy or between two verification (including component creation and port connection) and
components. monitor the transaction flow at the port level.
A. Tracing Component Creation and Port Connection // Add a message whenever a new component has been
The testbench structure includes the component hierarchy // created. The port component will be reported when
and the TLM (transaction layered modeling) port connections.
By adding system messages at the build phase, users are able to // creating the uvm_port_base, so won’t be reported here.
trace how the components (including ports, which are also begin
components) are created and record the parent-child
relationship between the components. Further, by inserting uvm_port_component_base port_component;
system messages at the connect phase, users can also trace how if (!$cast(port_component,this))
the TLM ports (including TLM2 sockets) are connected and
record the producer-consumer relationship between the `uvm_info ("COMP_TRACE",
connected ports.
{"Creating component ",
The following methods are the points at which tracing
(parent==top?"":
messages are added for component and port creation:
{parent.get_full_name(),"."}),name,
"(type=",get_type_name(),")"},
function uvm_component::new (string name,
uvm_component parent); UVM_LOW)
function uvm_port_base::new (string name, end
uvm_component parent,
endfunction
uvm_port_type_e port_type,
int min_size=0,
int max_size=1);
function uvm_port_base::new (string name, …);
…
The following information is collected and passed as // Add a message whenever a new base port component
additional fields for the message:
// has been created.
• The parent full name
`uvm_info ("PORT_TRACE", {"Creating port ",
• The component/port name
m_comp.get_full_name(),
• The type name, e.g., “ubus_pkg::class
ubus_master_driver” " (type=",get_type_name(),")"}, UVM_LOW)
• Other component/port info (e.g., is_port, is_export, endfunction
is_imp, etc.)
The following methods add the tracing messages for TLM1 • The times entering and leaving the method
port and TLM2 socket interface: • The port info (full name, type, configurations, etc.)
TLM1 Ports: • The generic payload, phase/sync, and delay for TLM2
task put (TYPE arg);
function bit try_put (TYPE arg); Example 2 shows how tracing messages for transaction
flow are added at the sequence item pull port level. The
function bit can_put(); methods used in this example are get_next_item() and
task get (output TYPE arg); item_done(). The uvm_report_record() is a function created to
print out the messages. Later in this paper we will demonstrate
function bit try_get (output TYPE arg); how this function can also be used to dump data into a
function bit can_get(); database.
task peek (output TYPE arg);
function bit try_peek (output TYPE arg); // A container class that wraps the data to be recorded.
function bit can_peek(); class uvm_port_recording_object extend uvm_object;
task transport (REQ req_arg, output RSP rsp_arg); uvm_port_component_base port_comp;
function bit nb_transport (REQ req_arg, // The base port component handle
output RSP rsp_arg); string func_name; // The port interface method name
uvm_object req; // The transaction payload
Sequence Item Pull Ports: time begin_time; // The begin time of the method call
task get_next_item(output REQ req_arg); time end_time; // The end time of the method call
task get(output REQ req_arg); // interface method. It initiates the container object and records
function uvm_tlm_sync_e nb_transport_bw(T t, ref P // transaction recording hook functions and record the data
p, input uvm_tlm_time delay); // into database.
function task b_transport (T t, uvm_tlm_time delay); `define UVM_IF_METHOD_END(req_arg,method_name) \
port_value.func_name = method_name; \
The following information is collected and passed as port_value.port_comp = m_comp; \
additional fields for the message:
port_value.end_time = $time; \
• The request and/or response transactions
if ($cast(port_value.req,req_arg)) \ recommended report API or macros (e.g., `uvm_info(), etc.).
Using this uvm_report_catcher facility, we implemented an
uvm_report_record (“PortIF”, extension to intercept the UVM tracing messages, and then
“Port level recording …”, port_value); redirect the messages into the database by using the
corresponding PLI tasks. This extension does not need any user
involvement except for the initialization, nor does it require any
// Add the macros to each TLM or sequence port method modification to the UVM library.
`define UVM_SEQ_ITEM_PULL_IMP(imp, REQ, RSP, Saving the UVM message data into a database enables post-
req_arg, rsp_arg) \ processing of the recorded message data and helps users to
analyze and comprehend the data. Post-processing procedures
task get_next_item(output REQ req_arg); \ include visualization, filtering, searching, ordering, and
`UVM_IF_METHOD_BEGIN \ merging, etc. For example, by turning on
UVM_PHASE_TRACE and UVM_OBJECTION_TRACE,
imp.get_next_item(req_arg); \ the following tracing messages about phase executions and
objection activities are printed out to the output screen or log
`UVM_IF_METHOD_END(req_arg,"get_next_item") \
file:
endtask \
…
function void item_done(input RSP rsp_arg = null); \
UVM_INFO ../../../../src/base/uvm_phase.svh(1410) @ 0:
`UVM_IF_METHOD_BEGIN \ reporter [PH/TRC/SCHEDULED] Phase
'uvm.uvm_sched.pre_main' (id=378) Scheduled from phase
imp.item_done(rsp_arg); \
uvm.uvm_sched.post_configure
`UVM_IF_METHOD_END(rsp_arg,"item_done") \
UVM_INFO ../../../../src/base/uvm_phase.svh(1158) @ 0:
endfunction \ reporter [PH/TRC/STRT] Phase 'uvm.uvm_sched.pre_main'
(id=378) Starting phase
Example 2
UVM_INFO ../../../../src/base/uvm_phase.svh(1235) @ 0:
reporter [PH/TRC/SKIP] Phase 'uvm.uvm_sched.pre_main'
(id=378) No objections raised, skipping phase
IV. SAVING UVM MESSAGE DATA INTO A DATABASE
The second issue with tracing messages as mentioned UVM_INFO ../../../../src/base/uvm_phase.svh(1387) @ 0:
earlier is that they are only output to a text format log file. reporter [PH/TRC/DONE] Phase 'uvm.uvm_sched.pre_main'
Since there can be a huge number of messages, the log file can (id=378) Completed phase
be extraordinarily large and very unwieldy in terms of UVM_INFO ../../../../src/base/uvm_phase.svh(1410) @ 0:
organizing and processing the data, or even locating useful reporter [PH/TRC/SCHEDULED] Phase
data. For debug and analysis purposes, users typically want to 'uvm.uvm_sched.main' (id=390) Scheduled from phase
record as much data as possible to narrow down problems. The uvm.uvm_sched.pre_main
solution is to save the messages into a well-organized database
and build a good user interface on top of the database to UVM_INFO ../../../../src/base/uvm_phase.svh(1158) @ 0:
retrieve and visualize the data. This requires a database format reporter [PH/TRC/STRT] Phase 'uvm.uvm_sched.main'
that can easily save message data with predefined properties (id=390) Starting phase
(e.g., verbosity, severity, etc.). The message data should also be UVM_INFO @ 0: main [OBJTN_TRC] Object
associated with any user-defined properties and their values in uvm_test_top.ubus_example_tb0.ubus0.masters[0].sequencer.l
different data types, which will help record transactions and oop_read_modify_write_seq raised 1 objection(s): count=1
their payloads. A set of PLI tasks that help record the data total=1
during simulation and UVM execution can be embedded into
UVM testbenches or the UVM library. UVM_INFO @ 0: main [OBJTN_TRC] Object
uvm_test_top.ubus_example_tb0.ubus0.masters[0].sequencer
PLI tasks to record the information into a database can be added 1 objection(s) to its total (raised from source object ):
placed wherever the previously-discussed tracing messages count=0 total=1
have been inserted in the UVM library. However, this is not
scalable and extendable, nor is it suitable for reuse. We found UVM_INFO @ 0: main [OBJTN_TRC] Object
that the UVM Report Catcher utility can be used to hook the uvm_test_top.ubus_example_tb0.ubus0.masters[0] added 1
PLI tasks with UVM messaging without even modifying the objection(s) to its total (raised from source object ): count=0
UVM library. The uvm_report_catcher is a callback total=1
mechanism and can be used to catch messages issued by the UVM_INFO @ 0: main [OBJTN_TRC] Object
UVM Report Server. User extensions of uvm_report_catcher uvm_test_top.ubus_example_tb0.ubus0 added 1 objection(s) to
(in which the action to be taken on catching the report is its total (raised from source object ): count=0 total=1
specified) can be registered as callbacks to capture the
messages as long as the messages are issued using the UVM …
For the purposes of this paper, we’ve displayed only a very V. POST-PROCESSING UVM MESSAGE DATA AND
short snippet of the messages in the log file. In contrast, if the ENHANCED VISUALIZATIONS
messages are recorded into a specialized debug database,
As illustrated in the previous section, the visualization of
visualization applications can be used to illustrate in one single
phase execution and objection activities after tracing messages
snapshot window the temporal flow or transition of UVM
for UVM_PHASE_TRACE and UVM_OBJECTION_TRACE
phasing and to display the raising/dropping/holding of UVM
is recorded into the database. Visualization tools can be used to
objections and the components that are
display the message data (currently converted from a long
raising/dropping/holding the objections (as shown in Figure 1).
string into a label and list of properties or attributes) in a
This goes far beyond text messages by showing the time
waveform view, which better illustrates the temporal relations
waveform of the relevant dynamic data to further improve
between the messages. Temporal relations are more important
debug.
to tracing messages, because these messages usually happen
The UVM Report Catcher is not the only method for across the simulation period. Messages for different tracing
recording message data into a database. Modifying and purpose are put in different streams.
replacing the report server is an alternative mechanism that can
For example, in Figure 1, the tracing messages for UVM
serve a similar function. However, the drawback with both
runtime phases are put in the stream of “\PH_TRC_[uvm]” and
these methods is that the data is transferred as a long string that
the tracing messages for UVM objections affecting the main
must be parsed and processed before saving into the database.
phase are put in the stream of “\OBJ_TRC_[main]”. Operations
In Example 2 the UVM messaging facility is not used to
like search, filter and highlight are provided at the application
implement uvm_report_record() function. Instead, because
level as these are common operations required by users. As
what we want to record transaction data, it takes advantage of
shown in Figure 1, the messages related to the main phase are
the UVM transaction recording mechanism and directly records
highlighted in yellow color. More advanced post process and
the port-level transaction data through the UVM recorder.
visualization are also available. In Figure 1, a signal waveform
Ideally, the UVM messaging system should be enhanced to
(below the stream “\PH_TRC_[uvm]”) is created based on the
allow users to create messages that can contain additional fields
value of the phase attribute from all messages in the stream of
and also work like transaction recording. In this way, a user-
“\PH_TRC_[uvm]”. This phase waveform provides a clear and
defined recorder could be hooked to the UVM library and all
intuitive visual indication of the phase transitions along the
messages recorded into a database along with their fields.
simulation and the time periods of each UVM phase. Similarly,
Figure 2: Illustration of UVM Component Hierarchy Tree and Source Code Synchronization
Figure 4: Illustration of Port Level Transaction Flow in Contrast with UVM Transaction Recording Waveform
This is in sync with the sequence timing shown in the bottom paper, should be included in the default standard UVM Class
row and further explains the beginning and ending of the Library, so that the dynamic data at each important stage of
sequence. When comparing the sequence waveform at the UVM execution can be captured into a log . Furthermore, the
bottom and the port level transaction flow waveform at the top, UVM Class Library should be enhanced such that the messages
users can get a much better understanding about the transaction can be easily captured and diverted into a debug database,
flow which in turn makes it easier to find and fix bugs in the which can then be used to drive a specialized UVM debug tool.
design or the testbench itself. This example depicts a simple Each system message would become a recording point with
testbench. For complex testbenches, users can first analyze the which internal runtime data can be actively collected and
higher-level sequencer transactions along with waveform recorded into a database by reusable UVM library extensions,
techniques like zooming, filtering, highlighting, etc. to first thereby minimizing or eliminating the burden on users to
narrow down the region of interest and then look at the detailed instrument directly into their testbenches or modify the UVM
port-level transactions as needed. libraries. Further processing of the database can enable more
efficient post-simulation analysis and greater understanding of
The visualization applications for testbench structure and UVM testbenches. It is clear that just as the Verilog PLI
transaction flow can be interrelated and synchronized to further allowed debug to advance to a level in keeping with design
ease and streamline debug and analysis. For example, users can
complexity, so too is the critical requirement for a mechanism
select a port in the hierarchy viewer and display the relevant to record data from modern object-oriented testbenches. The
transaction waveform. In addition, since the stack trace can be mechanisms proposed in this paper make it feasible for users
recorded through the PLI tasks as part of the message data into and vendors alike to stay in lock-step with the ever-increasing
the debug database, the event (component creation, port complexity that is part and parcel of any modern verification
connection, or transaction-level interfacing) depicted by the environment.
message can be correlated to other representations, such as
source code using drag-and-drop techniques. For example, REFERENCES
users can drag the get_next_item() box from the waveform
viewer in Figure 4 and drop it into the source code pane in
[1] UVM User Guide and Reference Manual,
Figure 3 to show the source code where get_next_time() is http://www.accellera.org/activities/vip
called. [2] R. Chen, B. Patel, and J. Zhao, “UVM Transaction Recording
Enhancements”, DVCon Proceedings, 2011
VI. CONCLUSION
Based on our experience, we strongly advocate that
additional system messages, such as those described in the