0% found this document useful (0 votes)
10 views5 pages

command-line-debug-using-uvm-sequences

This document discusses a command line debugging technique using UVM sequences to enhance the interactive debugging of hardware and test bench bugs. It outlines the architecture and implementation details of a command line debug environment that allows users to run targeted tests and check results efficiently, facilitating rapid debugging during hardware integration. The technique is lightweight, leverages existing UVM sequences, and is designed to be user-friendly for hardware designers with minimal UVM knowledge.

Uploaded by

chanikya
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
10 views5 pages

command-line-debug-using-uvm-sequences

This document discusses a command line debugging technique using UVM sequences to enhance the interactive debugging of hardware and test bench bugs. It outlines the architecture and implementation details of a command line debug environment that allows users to run targeted tests and check results efficiently, facilitating rapid debugging during hardware integration. The technique is lightweight, leverages existing UVM sequences, and is designed to be user-friendly for hardware designers with minimal UVM knowledge.

Uploaded by

chanikya
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 5

Command Line Debug Using UVM Sequences

Mark Peryer
Mentor Graphics (UK) Ltd
Rivergate, London Rd., Newbury,
Berkshire, U.K. RG14 2QB
Telephone: +44 1635 811614
[email protected]

ABSTRACT a test class that is responsible for defining the configuration of the
The mainstream use case for the UVM is to create a verification test bench structure, starting the top-down build process and then
environment that supports the running of multiple test cases which starting the execution of the chosen set of sequences.
run sequence based stimulus and use automatic checking and
coverage mechanisms to achieve closure on a verification plan. The typical UVM test bench architecture is orientated around the
However, there is another important use case which is not so well interfaces of the Design under test (DUT), with each hardware
addressed and that is the interactive debug of hardware and test interface having a verification component, or agent, associated with
bench bugs. This paper describes a technique which leverages UVM it. The agent contains a driver which is responsible for converting
sequences to implement a command line debugger which can be used abstract transaction objects called sequence_items into signal level
to facilitate efficient hardware debug, and potentially, the debug of activity. Stimulus is generated for an interface inside sequence
the sequences themselves. In practical terms, the technique is objects which create and shape a series of sequence_item objects and
encapsulated in a command line debug sequence package. send them to the driver via component object called a sequencer. Co-
ordinated stimulus between hardware interfaces is achieved through
Using the package allows a user to debug designs more efficiently by the use of supervisory sequences which execute sequences on
being able to interactively run short, targeted tests and to check the multiple sequencers, these are usually referred to as virtual sequences
result using the debug resources of the simulator. The approach is and they are executed via virtual sequencer component objects which
well suited to the early stages of hardware debug or integration contain handles for the target interface sequencers. This architecture
debug where its interactivity allows users to track down simple, but is illustrated in Figure 1.
blocking issues, very quickly. The technique is lightweight,
leverages existing UVM sequences and is orthogonal to the main
UVM use model of building up regressions of test cases.

Categories and Subject Descriptors


[Hardware Verification]: Functional Simulation and Verification –
Class based SystemVerilog, UVM class library, sequences, register
model, command line debug.

General Terms
Verification, Simulation, Sequences.

Keywords
UVM, Sequences, sequence wrappers, testbench architecture, debug
techniques, Registers

1. INTRODUCTION
The Universal Verification Methodology (UVM) is a SystemVerilog Figure 1 – UVM Test Architecture
base class library which allows users to construct verification
Once the UVM verification architecture has been established, the
environments using verification component objects and to create
verification process centres around the creation of test cases based on
stimulus using sequence objects. The UVM encapsulates a number of
standard building blocks with well-defined APIs which makes it the use of sequences. The emphasis of the verification process is on
straight-forward for users to collaborate or to build testbenches generating volumes of stimulus as efficiently as possible using
which are interoperable with third party verification IP. constrained random techniques; re-running test cases with different
seeds to create conditions which flush out corner case bugs in the
DUT. When aligned with a metric based, coverage driven
1.1 The UVM Verification Process verification process the UVM has proved to be an effective means of
The UVM makes a clear separation between stimulus generation and verifying hardware using simulation techniques.
the structure of the verification environment. The structure of the
UVM test bench is created during the build phase when the various Once a test case has passed its initial debug phase, it is passed into a
components are configured and constructed, these structural regression suite which is run in batch mode. In the regression suite
components stay in place for the lifetime of the simulation. However, the test case is run with different seeds to catch corner cases. The
stimulus generation is by means of a library of sequence classes priority is on simulation throughput to explore as many parts of the
which have a transitory life time, being created, executed and de- design state space in a given time. This use model is efficient once
referenced as required. Each UVM simulation starts by constructing
the test bench architecture has been completed and once the DUT has sequence library packages developed for the DUT. The main
reached a reasonable level of maturity, but there is a considerable infrastructure of the system is generic, but there are parts of the
period of time where a more interactive use model can facilitate implementation which need to be customised to address the specifics
rapid debug. This is where the use of sequences controlled from the of an environment. A script has been developed to reduce the
command line can prove effective. extraction and customization effort.

1.2 Command line debug sequence use model 2.1 Requirements


A simulator converts a hardware description of a DUT into an Before implementing the command line debug system the following
executable model. In the classic UVM use model, the emphasis is on requirements were considered:
wrapping the DUT with a test bench and generating stimulus that
effectively runs in batch mode with minimal interaction from the 2.1.1 Ease of use
user, unless a bug in either the DUT or the verification environment The debug system needed to be straight forward to use, the target
is uncovered. The command line use model takes advantage of the being to provide a hardware designer with no knowledge of UVM a
UVM test bench infrastructure and its stimulus objects, but places useful debug environment.
the user in the driving seat by allowing him to interactively direct
what stimulus is applied to which interface of the executable DUT 2.1.2 Low implementation overhead
model, and in what order. The closest parallel to this is bringing up The time taken to create an implementation of the debug system
real hardware on a lab bench with a software debug monitor, signal needs to be short, and the creation process needs to be agile to cope
generators and instruments. The architecture of the command line with updates to the UVM verification code.
debug environment augments the typical UVM environment as
illustrated in Figure 2. 2.1.3 Capability to run sequences
The command line interface needs to be able to specify and run
In the early stages of bringing up a DUT, there are often simple sequences from the available library.
problems which need to be debugged interactively with the
verification engineer and the designer working through a series of
2.1.4 Capability to pass arguments
directed steps to understand what is wrong with the hardware. The
There needs to be a means of passing arguments from the command
complexity of these steps will range from individual reads and writes
line which configure the sequences to be run. For instance, a
of hardware registers to running a series of complex stimulus
sequence which does a bus write will require an address and a write
patterns.
data argument.

2.1.5 User help system


The user needs to be able to view information on the available
sequences, their purpose and the command line required to execute
them.

2.1.6 Capability to run command files


The command line system needs to be able to read text files which
contain lists of sequence commands. These files can be used to save
the user from having to enter commonly used sequences of
commands at the command line.

2.1.7 Log file generation


Recording the commands submitted via the command line interface
and their result allows the session to be recorded and to be used as a
reference or as the basis of a command file. This facility also needs
Figure 2 – Command Line Debug Using UVM Sequences to have the capability to annotate comments.
A typical scenario would be to run an initialisation routine, then
2.1.8 Capability to run parallel commands
check the state of the DUT registers, followed by a DUT operation,
There are situations where there is a need to run multiple sequences
followed by a dump of the DUT register or memory content.
as parallel threads. An example would be a sequence that sends
Obviously, this can also be done via the mainstream UVM use
serial packets to the DUT on one interface running concurrently with
model, but using the command line allows the user to try out
a sequence that handles the packets on another.
different register programming options without having to rewrite,
recompile and reload the UVM sequence code. With larger scale
verification environments it can take a significant amount of time to 2.1.9 Library of utility commands
iterate round an experimental sequence loop and it can be tricky to The command line package also needs to contain commands which
debug, the command line approach allows the user to try an allow the user to specify behavior not related to sequences. These
experiment several times until the solution is identified without include:
having to change any underlying code or reload the simulation. • wait_for_clock(n) – Wait for n system clocks
• wait_for_interrupt – Wait for an interrupt
• exit – To exit the command line debug
The main purpose of the command line interface is to execute
2. IMPLEMENTATION sequences. This means that the meta-language used does not need to
The implementation of the command line debug infrastructure
have a rich feature set. Complex constructs such as decision loops
leverages the structure of the UVM verification environment and the
and support for specifying randomization constraints are not required The standard DPI calls, i.e., export or import statements, are also
since they can easily be taken care of in a custom sequence, present in the package.
implemented in native SystemVerilog.
The rest of the package is specific to an UVM verification
2.2 Implementation detail environment and is generated by a script based on the content of the
The command line interface package comprises a SystemVerilog target sequence packages. It comprises the following tasks and
package and a library of c functions. The c functions implement the functions:
command line monitor. The SystemVerilog package contains the
command line interpreter and tasks which create and execute the • Sequence wrapper classes – one per target sequence
sequences. The c code and the SystemVerilog code communicate via • Init() – Task that constructs all the sequence wrapper
the SystemVerilog Direct Programming Interface or DPI. objects, assigns sequencer handles and puts them into an
associative array.
2.2.1 Using the SystemVerilog DPI • virtual sequencer – Containing handles for the target
The DPI provides a light-weight way of allowing SystemVerilog sequencers that the sequences will run on.
code to execute c functions in an external shared object and for c • Utility functions – specific to an environment
functions in an external object to call SystemVerilog tasks or
functions. In the SystemVerilog code, SystemVerilog tasks and 2.2.3 The sequence wrapper class
functions are exported, and the c functions are imported. The The sequences used by the command line debugger need to be
SystemVerilog compilation process generates a c header file which created, configured and then started from the cli_seq package. In
has to be included in the c code to allow the SystemVerilog tasks and order to use a generic command dispatcher, the sequences are
functions to be referenced; otherwise the c source code does not encapsulated in a wrapper class, derived from a base class, which
require any special coding techniques. The interface allows c and contains methods to simplify the implementation of the package.
SystemVerilog data types to be passed as arguments. Sequences are wrapped and then placed in an associative array,
indexed by a string. The wrapper classes are generated by a script
The simulator side of the DPI needs to be implemented in the static which parses the sequence packages.
part of the SystemVerilog language so that the shared object can be
loaded and linked with the simulator kernel at the start of the To illustrate how a wrapper class is implemented consider a bus read
simulation. This means that any DPI code has either to be in a static sequence:
SystemVerilog interface or module, or it needs to be in a package. In
this case, a sequence command line package was written and this class apb_read_seq extends ovm_sequence #(apb_seq_item);
`ovm_object_utils(apb_read_seq)
encapsulated the DPI imports and exports as well as the tasks and //------------------------------------------
functions required to implement the interface. The c side of the DPI // Data Members (Outputs rand, inputs non-rand)
was implemented as a series of c function calls. //------------------------------------------
rand logic [31:0] addr;
logic [31:0] data;
Any sequence of DPI calls has to start under the control of the
SystemVerilog code. The command line debugger is started by the // Standard OVM Methods:
extern function new(string name = "apb_read_seq");
OVM test making a call through the DPI to a c function called extern task body;
SV_debugger() which is the command line monitor loop. The endclass:apb_read_seq
simulation is then blocked until the user makes an entry at the
command line, at which point the string entered is passed to the function apb_read_seq::new(string name = "apb_read_seq");
super.new(name);
SystemVerilog code to interpret and dispatch the selected sequence endfunction
wrapper task with the appropriate arguments. Once the command has
been executed on the simulation side, control is passed back to the c task apb_read_seq::body;
apb_seq_item req = apb_seq_item::type_id::create("req");;
code to pick up the next command to be executed. The prompt loop
is terminated when the user types ‘exit’, at which point the begin
SV_debugger() function returns and the OVM test run method can start_item(req);
req.we = 0;
continue. req.addr = addr;
finish_item(req);
2.2.2 The SystemVerilog package (cli_seq_pkg.sv) data = req.data;
end
The SystemVerilog side of the debug package is contained within a
package. The package imports the UVM package (uvm_pkg); the endtask:body
packages containing the sequences which it references; and the This sequence has been coded following the recommended coding
packages for the target agents on which the sequences will be run. style where configuration data members are randomizable (addr) and
Inside the package are a small number of generic tasks and functions that result data members are not (data). This coding convention is
associated with processing the command line: assumed by the generation script.

• process_cmd_line() – Function that is called by the The code for the sequence wrapper base class is as follows:
command dispatcher, it parses a command line string and
returns a data structure // Sequence wrapper class:
//
• process_cmd_file() – Task to open and read a command // Takes a sequence and wraps it with other helper methods
file and pass each line to the command dispatcher class //
• dispatcher() – Task which takes the command line and virtual class sequence_wrapper extends uvm_object;
dispatches the relevant sequence(s) for execution function new(string name = "sequence_wrapper");
• virtual sequencer handle super.new(name);
endfunction
The package contains an initialization function which is responsible
// Handle for the target sequencer
uvm_sequencer_base sqr; for constructing each of the wrapper tasks and putting them into an
associative array indexed by a string which corresponds to the name
// Template for the help messaging: of the sequence. When a command line request is received by the
virtual function string help();
`uvm_error("sequence_wrapper",
command line dispatcher, it looks up the wrapper sequence in the
"Help method not implemented") associative array, calls the spawn() method to create a new deep
endfunction: help copied object and then executes it. The spawning is required to
enable multiple copies of a sequence to be run in parallel.
// Returns the number of arguments used by run_sequence
virtual function int no_args();
return 0; The sequence does not return any data to the command line because
endfunction: no_args it cannot process returned values, however the result of the sequence
// Needed to spawn multiple sequences concurrently execution is displayed and recorded in the log file:
virtual function sequence_wrapper spawn();
sequence_wrapper c = new(); # apb_read_seq: addr: 0 data:0
# apb_write_seq: addr:0 data: aaaaaaaa
c.sqr = this.sqr; # apb_read_seq: addr:0 data:aaaaaaaa
return c;
endfunction: spawn
2.2.3 The package generation script
// Assign the handle for the target sequencer In order to make the package code relatively painless for the user to
virtual function void set_sqr( produce, a generation script has been developed. The script works in
ovm_sequencer_base sequencer);
sqr = sequencer; two phases.
endfunction: set_sqr
The first phase takes a list of sequence library packages, parses the
// Task to start the sequence from the wrapper
// Generated code goes here ...
sequence descriptions and generates a reference file containing a list
virtual task run_sequence(int arg0 = 0, of target sequences and arguments that could be used with those
int arg1 = 0, sequences. The user then takes the reference file and comments out
int arg2 = 0, those sequences that he wishes to omit from the command line debug
int arg3 = 0);
`uvm_error("sequence_wrapper", package. The user can also comment out sequence arguments and
"run_sequence method not implemented") specify the name of the target sequencer.
endtask: run_sequence

endclass: sequence_wrapper The second phase takes the edited list and generates the wrapper
tasks, the help functions, the virtual sequencer and the dispatcher
The resultant wrapper class that is generated for the example tasks. The generated code is written into files which are `included
apb_read_sequence is as follows: into the command line debug package.

// This code is generated Once the reference file is in place, the process can be run again to
class apb_read_seq_wrapper extends seq_wrapper; capture any new sequences developed as the environment develops.
`uvm_object_utils(apb_read_seq_wrapper) This enables a new version of the debug package to be produced very
quickly. The process can be used with ordinary sequences or with
function new(string name = "apb_read_seq_wrapper"); virtual sequences.
super.new(name);
endfunction
3 USING THE PACKAGE
function string help();
return "apb_read_seq addr; - target sequencer: APB";
Once the package is in place, it is compiled and imported into the
endfunction: help SystemVerilog package that contains the test case classes. Inside any
test class that is going to allow the use of the package, four things
function int no_args();
return 1;
need to be done in order to get things up and running:
endfunction: no_args
• The package virtual sequencer needs to be declared and
function sequence_wrapper spawn();
apb_read_seq_wrapper c;
constructed.
• The handles for the various target sequencers in the
c = new(); package virtual sequencer have to be assigned.
c.sqr = sqr;
return c;
• The virtual sequencer handle in the package has to be
endfunction: spawn assigned to the virtual sequencer in the test.
• At some point in the execution of the test run method, the
task run_sequence(int arg0 = 0,
int arg1 = 0,
package sv_debug task has to be called to enable the
int arg2 = 0, debugger.
int arg3 = 0);
apb_read_seq seq = apb_read_seq::type_id::create("seq"); The following pseudo code illustrates how the debug functionality
seq.addr = arg0;
seq.start(sqr); would be integrated into an UVM test:
$display("apb_read: addr:%0h data:%0h", arg0, seq.data);
$fdisplay(log_fh, "apb_read: addr:%0h data:%0h", arg0, // Example leaving out irrelevant code
seq.data); class with_debug extends spi_test_base;
endtask: run_sequence
`uvm_component_utils(with_debug)
endclass: apb_read_seq_wrapper
// Debug package virtual sequencer
seq_cli_v_sqr seq_cli_sqr;
// Build method building debug pkg sequencer 5.1 UVM Registers
function void build(); The UVM register base classes enable the package to provide a
super.build(); generic set of methods which allow the user to examine and change
seq_cli_sqr =
seq_cli_v_sqr::type_id::create("seq_cli_sqr", this); memory and register content. The UVM register model provides a
// Assign handle to package virtual sequencer handle: task based API for register accesses, eliminating the need for the user
seq_cli_pkg::vs = seq_cli_v; to provide read and write sequences specific to the target bus.
endfunction: build

// Virtual sequencer target sequencer handle assignment The UVM register model is structured to align with the hardware
function void connect(); structure of the DUT, therefore the command line allows the
super.connect();
seq_cli_v.APB = m_env.m_apb_agent.m_sequencer;
dumping of register content on a system, sub-system, block, register
seq_cli_v.SPI = m_env.m_spi_agent.m_sequencer; or register field level simply by specifying a path. When looking at
endfunction: connect register content, the user has the option of looking at the content of
the register model database (referred to as the ‘mirror’); performing a
task run;
#100 ns; // Wait for reset to go away front door read() access using a bus agent; or by performing a back
sv_dispatcher(); // Calls the debugger door peek() access using the simulator data-structure. This capability
global_stop_request(); enhances the debug process, since it is often inconvenient to do a
endtask: run
front door read access which disturbs the state of the DUT hardware.
endclass: with_debug
The UVM register classes also allow memories, or regions of
Once the debug mode is entered, the normal operation of the UVM memories to be accessed either using front or back door access
environment comes to a halt, since the simulation will be blocked methods. The command line package has been upgraded with generic
from advancing whilst a command is being entered, and will advance commands to allow users to dump memory content; to change
in time only when a sequence is being executed. However, the debug memory locations; to load memory with the content of a file; or to
facilities of the simulator will remain available to the user, allowing fill it with random data.
waveform traces, single stepping through code etc to still be used.
Finally, the UVM register map class allows users to access registers
4 APPLICATIONS and memories from different interfaces, something which is
Variants of the command line debug package have been used by important when verifying the content of SoCs using complex
different users to great effect at different levels of design integration. interconnect fabrics which have several bus master ports. The
capability to specify alternative access interfaces has also been added
The package has been used with block level environments to do using a command line argument.
basic register read and write mode debug. It has also been used to
prototype driver code or to develop initialization routines. It has also 5.2 UVM Resources
proved extremely useful in debugging specific scenarios where Using the UVM resource data base offers the possibility of
multiple interfaces need to be stimulated using several sequences in manipulating handles to the target sequencers and the sequence
parallel. wrapper objects more elegantly than was possible before.

At cluster and SoC levels of integration, the technique has proven 6. CONCLUSION
useful for unpicking interconnect issues such as incorrect address The command line sequence debug package has proven to be useful
decoding and data path issues. It has also allowed firmware to be to OVM users. With the advent of the UVM, there are a number of
debugged before being encapsulated in sequences or processor based potential upgrades which should enhance the ease of use of the
binaries. package.

5 FURTHER DEVELOPMENTS 7. ACKNOWLEDGMENTS


The current implementation of the command line debug sequence My thanks go to my colleagues, especially Rich Edelman for making the time
package is based on features that were present in the OVM library. to dig my early experiments with the DPI out of the mire and Adam Erickson
These features map directly over to the UVM 1.0 base functionality, for giving me early insight into the UVM register classes.
but with the new features available in the UVM it should be possible
to enhance the package. 8. REFERENCES
[1] Edelman, R., Warmke D. 2005. Using SystemVerilog Now with DPI –
The two most promising areas are UVM registers and the UVM Proceedings DVCon 2005
resources database. Some upgrade work has been recently been done [2] Edelman, R., 2008. Sequences in SystemVerilog – Proceedings DVCon
to the command line debug package to take advantage of the features 2008
of the UVM register model classes. The results of the investigations [3] IEEE 1800 SystemVerilog LRM – IEEE 2009
into the use of the resource database are not available at the time of [4] Meyer, A., 2009. Overview of Sequence Based Stimulus Generation in
OVM 2.0 – Application note. Mentor Graphics Corporation
publication. [5] OVM 2.1.1 Users Guide. Mentor Graphics and Cadence Design Systems
– 2010
[6] UVM 1.0 Users Guide – Accellera, (Awaiting publication)

You might also like