Dvcon2017 Uvm Debug Lib Final
Dvcon2017 Uvm Debug Lib Final
Dvcon2017 Uvm Debug Lib Final
net/publication/320935458
CITATIONS READS
0 298
1 author:
Horace Chan
Simon Fraser University
1 PUBLICATION 0 CITATIONS
SEE PROFILE
Some of the authors of this publication are also working on these related projects:
All content following this page was uploaded by Horace Chan on 08 November 2017.
Abstract - Interactive debug in System Verilog simulations is not a natively supported feature, unlike other
Hardware Verification Languages (HVL) such as Specman e. In this paper we are presenting an interactive
debug library for UVM[1] implemented in the SystemVerilog Direct Programming Interface (SV-DPI)[2]. At
a basic level, this enables high level interactive debug at simulation run time. The features of this library
includes: 1) writing or reading a register via the UVM register abstraction layer, 2) creating, randomizing,
initializing, and starting a UVM sequence on any sequencer, and 3) calling a user defined SV function or task
from the interactive debug prompt. We are also presenting a debug and regression methodology outlining
the best practice on how to speed up debug and minimize the regression run time. The preliminary results
show that using interactive debug library significantly reduced the debug turnaround time and regression
run time. Users can retest different scenario in matter of seconds instead of waiting minutes or hours for the
testbench to recompile, elaborate, and rerun the simulation from time zero. The uvm_debug library is
available as an open-source project in github[3].
I. INTRODUCTION
Users of verification frameworks implemented in other programming languages, such as Specman e[4] and
Cocotb/Python[5], have been accustomed to the flexibility of interactive debug during run time. The user can run
the simulation to a certain point in time, pause the simulation, activate the debug prompt, and then call any testbench
functions to change the behavior of the test scenario before resuming the run. In SystemVerilog, due to the
limitation of the language, once a testbench is compiled, the user has little control over the test scenario during the
simulation. Currently, during simulation run time, users are limited to using a difference seed or poking/forcing
signals inside the simulation environment.
Imagine the following scenario: a user has a long simulation that runs for hours. Halfway into the simulation, a
testbench checker reports an error. In order to debug the problem, if the user needs to change the stimulus, then they
have to update the SV code, recompile the testbench and wait a long time to find the error again. With the help of
the interactive debug library, the user can try different debug scenarios without restarting the simulation. They can
query the device status through register reads; they can try new device configurations through register writes; they
can change the stimulus generated by the testbench by executing a new UVM sequence with a higher priority; or
they can call any testbench functions to help diagnosis the problem. They can try out dozens of different scenarios
and pinpoint the bug in a matter of minutes instead of hours. The drastic reduction in debug turnaround time
increases productivity and the time is spent on isolating the bug, rather than waiting for the simulation to
compile/run.
An earlier attempt, cli_seq_pkg [6], was made by M. Peryer to support interactive debug in UVM by introducing
an command line debug interface. The biggest drawback of the cli_seq_pkg is that it requires a wrapper class for
each sequence. Each wrapper class is created manually or generated by a preprocessing scripts in two phases either
solution is tedious and prone to error. Moreover, the author did not provide source code of cli_seq_pkg and the
description in the paper did not contain enough details to allow users to re-implement the package with ease.
Another attempt, RESSL [7], was made by J. McNeal and B. Morris to implement a read, evaluate, start sequence
loop. Its implementation is highly intrusive to an existing testbench. RESSL requires a hacked version of UVM.
All sequences supported in the read, evaluate loop must be derived from a common base class and manually
registered into a sequence registry in the testbench. These requirements make adoption in a large-scale production
project very difficult unless there is a strong mandate from management to drive these changes throughout the
project.
The UVM Interactive Debug Library (uvm_debug), presented in this paper, is developed independently without
prior knowledge of [6][7]. The uvm_debug library supports all the functions of cli_seq_pkg and indirectly supports
all features of RESSL and offers much more. The author wanted to bring the powerful debug features and flexibility
from Specman into SV-UVM so that multiple SV testbench environments can benefit from it. The uvm_debug
library is available as an open source project from github[3]. Setting up the uvm_debug library is easy and non-
intrusive: simply download the code, then compile the .sv and .c file together with the testbench. The user does not
have to go through a complicated testbench hook up process or any patch into the UVM source code. All it takes is
calling a simple function to initialize the uvm_debug object.
In the SV code, the function dpi_read_line() in uvm_debug_pkg prints a prompt to the screen, waits for the user to
enter a line, and then returns the inputted line as a string. In the C code, the simplest implementation is to call the C
built-in getline() function from <stdio.h> to read a line from the standard input. In a case where the simulator is
running in GUI mode, it is quite inconvenient to switch back and forth between the shell and the GUI to enter in
debug commands. Alternatively, the C code can be compiled to read the user input through the Tcl prompt of the
simulator.
SV code
import "DPI-C" function void dpi_read_line(string prompt, inout string line)
function string read_line(string prompt);
dpi_read_line(prompt, sbuffer);
read_line = sbuffer;
endfunction: read_line
C code
char buffer[1000];
void dpi_read_line(char* prompt, char** line) {
#if defined(CADENCE)
*line = cfcReadline(prompt);
#elsif defined(MENTOR)
mti_AskStdin(*line, prompt);
#else
printf(prompt);
fflush(stdou);
*line = &buffer;
int bufsize = sizeof(buffer) / sizeof(char);
getline(&buffer, &bufsize, stdin);
#endif
};
Once the testbench can read a user input in simulation, the rest is fairly straightforward. All objects and
components created in UVM can be accessed by their names, which is a text string. The debug library implements a
command line parser to process the user input, query the object pointer using the full name, and then call the
specified task or function using the parameters supplied by the user. The rest of this section will go over all the
supported features of the command line parser.
SV code
import uvm_debug_pkg::*;
...
uvm_debug_util uvm_debug = uvm_debug_util::get();
uvm_debug.prompt(1);
Tcl commands
ncsim> call debug_prompt
debug prompt (help for all commands)
1000ns: debug >
SV code
uvm_debug.reg_util.set_top(my_top_reg_block);
The debug prompt supports the following built-in uvm_reg related debug commands.
Table 2 Register Debug Commands
Command Description
wr_addr <addr> <value> Write a register by address.
rd_addr <addr> Read a register by address.
wr_reg <reg> <value> Write a register by the uvm_reg full name.
rd_reg <reg> Read a register by the uvm_reg full name.
wr_regfld <field> <value> Write a register field by the uvm_reg_field full name.
rd_regfld <field> Read a register field by the uvm_reg_field full name.
SV code
class custom_debug_command extends uvm_debug_command_cb;
function new(string name = "custom_debug_command");
super.new(name);
// --------------------------------------------------------------
command = "cmd_name";
usage = "<arg1> <arg2>";
description = "description of the command showed in help”;
// --------------------------------------------------------------
endfunction
The input arguments from the debug prompt are passed into the call back object as a list of strings. To help the
user parse the argument list before calling the testbench function/task, the uvm_debug library comes with a built-in
argument parser. The argument parser supports two argument formats, the tcl dash option format (-option value)
and the SV command line plus argument format (+option=value). It also supports converting bin, oct, or hex
values specified in SV ‘b/’o/’h notation from string to integer value. The following table lists the argument parser
text processing functions.
Tcl prompt
ncsim> set read_value [debug_prompt rd_addr 0]
ncsim> echo $read_value
Please note that the Tcl script integration is still highly experimental. The author has only tried running the debug
commands inside simple if-else branches and control loops. The Tcl prompt is essentially running everything under
a single thread. It would be interesting to see how well the uvm_debug library works if there are multiple threads
calling multiple debug commands simultaneously. However, Tcl is never intended to be a serious multi-thread safe
programming language, so why don’t we simply implement those complex scenarios in native SV code?
I. Examples Testbench
The uvm_debug library comes with an example testbench. We chose the uvm_example/integrated/codec
example that comes with every UVM distribution to demonstrate how easy it is to set up the uvm_debug library.
We selected this testbench as our example because it is simple and well understood by the verification community,
yet it provides a skeleton of a full feature testbench. It has an APB register interface and a simple serial VIP
sequence.
The integration is very straightforward. Other than the extra information messages added to the examples, to
highlight which debug commands are currently running, it only takes three lines of code. The users can run the
demo.sh in the uvm_debug library to see the debug prompt in action. The example also has the following simple
debug command file to demonstrate the most commonly used features.
debug.cmd
# register access
rd_addr 0
wr_reg regmodel.IntMask 0
wr_regfld regmodel.TxStatus.TxEn 0
X
DUT error
start of simulation
end of simulatoin
auto_save auto_save
X
checkpoint checkpoint
base testcase
DUT error
The first use model is similar to the traditional debug flow of setting a break point in the testbench in the simulator
or setting a breakpoint in the software in the post-silicon debug environment in the lab. Once an error is detected in
the testbench, it will pause the simulation and trigger the debug prompt. The user can interactively read or write
registers and/or inject simple stimulus to diagnosis the problem. What used to be done by manually peeking and
poking RTL signals is now replaced by executing higher level debug commands, thus saving the verification
engineer from the tedious work of manipulating RTL signals in Tcl.
Sometimes, using waveforms from existing simulation and merely tweaking the design after the point of failure
may not provide enough information to root cause the problem. It may require the engineer to try different corner
case scenarios to triangulate the bug. If the error occurs several hours into the simulation, re-running the simulation
from time zero to reproduce the error could consume an engineer’s entire day. A typical failure takes several
iterations to isolate and correctly identify the bug, re-running the simulation in every iteration would be
unacceptable and extremely inefficient. We need to replicate the failure condition and try different stimuli in a
much shorter time.
The second use model combines the uvm_debug library with the snapshot save/restore functionality of the
simulator. In a simulation run, the testbench will save a checkpoint snapshot periodically, say every 30 minutes.
The goal is whenever a failure occurrs, the user can quickly restore the last saved checkpoint knowing that it would
take at most, 30 minutes to replicate the failing scenario. After rewinding the simulation to the saved checkpoint,
the user can use the uvm_debug library to try various “what if” scenarios interactively by starting new sequences to
modify existing stimuli. The user can also load a command file and run the simulation in batch mode, to test
different scenarios in parallel instead of typing in the debug commands manually in the interactive prompt.
The third use model takes the batch mode debug application and applies it to normal regression runs. We
observed that in our project, most of the testcases spent a significant amount of time configuring the device and
waiting for the device to stabilize before we could start injecting interesting traffic patterns to stress different corner
cases. If we have to test ten different traffic patterns, all using the identical bring up sequence, in the past we would
have had to run the simulation ten times from time zero. With the help of the uvm_debug library and command
files, we can save a checkpoint after the device is stabilized, then load different command files to augment the base
testcase and change the traffic patterns. For example, the initialize sequence in our project consumes at least 25% of
the simulation time on average, and so using the command files would speed up our regression by 25%.
V. FUTURE DEVELOPMENT
We implemented and tested the uvm_debug library primarily on the Cadence IES simulator. The majority of the
code is simulator neutral and is ready to deploy on other simulators, although we have never tried it. However, there
is a small portion of code that relies on function calls to simulator-specific Tcl commands. Those features such as
triggering the debug prompt from the tcl prompt, a tcl procedure to fetch the return value of the debug command,
saving a checkpoint snapshot of the simulation and setting the values of the UVM fields inside a sequence created
by the debug prompt do not work on other simulators in the current release. We have plans to support the big three
simulators in the future. Groundwork for Mentor Modelsim integration is already in place in existing code, the SV
domain can communicate with the Tcl domain in Modelsim through the SV-DPI C code. The remaining work is to
replace the ncsim tcl commands with modelsim tcl commands. However, the author could not access the Tcl
prompt of the Synopsys VCS simulator. It would be much appreciated if VCS experts can share their knowledge of
Tcl integration and contribute to this project.
New developments to UVM are currently on hold due to Accelera working with IEEE to rectify the UVM 1.2 as
the IEEE 1800.2 standard. When the UVM is open to accept new development again, I would like to contribute the
uvm_debug library to Accelera and make it part of the UVM distribution. It would greatly benefit the verification
community if the UVM came with a built-in interactive command line parser and a set of standard SV-Tcl
interfaces. The current implementation of uvm_debug library is focused on being non-intrusive to existing
testbench code, thus it limits the data structure accessible by the library only to the string named objects under the
uvm_root tree hierarchy. If the uvm_debug library is adopted by Accelera as part of the UVM, it will allow a tighter
integration with the UVM base classes with introspection support and opens up many new possibilities, such as
debug commands to control the run phase domains, fine grain sequence threads management, and dynamic function
overloading. Ideally, the user could call any function in a uvm_component or uvm_object from the debug prompt.
VI. CONCLUSIONS
The UVM Interactive Debug Library is easy to set up. It is non-intrusive no changed to the testbench is required
other than loading the package file and calling the initialize function. With the help of the uvm_debug library, our
debug turnaround time for a typical simulation failure has been reduced by 90%. The total simulation time for the
regression run was reduced by 25%. Interactive debug enhances existing verification methodology, results in higher
productivity of the verification engineers, lowers the cost of simulator license usage, and shortens the project
schedule.
ACKNOWLEDGMENT
The author would like to thank his employer, Microsemi Corporation for their support of the uvm_debug library
development and the production of this paper. He would also like to thank open source project cluelib[9] for
providing some of the text string processing code used in the library.
REFERENCES
[1] Accellera Systems Initiative, “Universal Verification Methodology (UVM) 1.2 Class Reference,” 2014.
[2] IEEE Standard for SystemVerilog – Unified Hardware Design, Specification, and Verification Language, IEEE Std. 1800-2012, 2013
[3] UVM Interactive Debug Library, Available: https://github.com/uvmdebug/uvm_debug
[4] IEEE Standard for the Functional Verification Language e, IEEE Std. 1647-2011, 2011.
[5] Cocotb Documentation, PotentialVentura, 2016, Available: http://cocotb.readthedocs.io
[6] M. Peryer, “Command Line Debug Using UVM Sequences”, DVCON2011
[7] J.McNeal and B. Morris, “RESSL UVM Sequences to the Mat”, SNUG2015
[8] H. Chan and B. Vandergriend, “Can You Even Debug a 200M+ Gate Design?”, DVCON2013
[9] K. Shimizu, “Sharing Generic Class Libraries in SystemVerilog Makes Coding Fun Again”, DVCON2014