UVM Basics
UVM Basics
Before we can get into discussing the recipes presented in the UVM Cookbook, we have to make sure that we're all
talking about the same ingredients. This chapter introduces the UVM concepts that the reader should know in order
to understand the recipes presented herein. This section will be incredibly valuable to new UVM users, but
experienced UVM users may be able to just straight to the UVM Testbench chapter.
Testbench Basics
UVM Testbeneh Basies
‘The UVM employs a layered, object-oriented approach 10 testbench development that allows “separation of
concerns” among the various wam members. Each component in a UVM testbench has a specific purpose and a
well-defined interface to the rest of the testbench to enhance productivity and facilitate reuse, When these
components ate assembled into a testbench, the result is a modular reusable verification environment that allows the
test writer to think at the transaction level. focusing on the functionality that must be verified, while the testbench
architect focuses on how the test interacts with the Design Under Test (DUT)
‘The Design Under Test (DUT) is connected 10 a layer of transactors (drivers, monitors, responders). These
transaetors com id sampling DUT signals, and with the rest of the
UVM testbench by passing transaction objects. They convert data between pins and transactions, ie. from/to signal
to'from transaction level. The testbench
wunicate with the DUT at the pin level by dri
ayer above the
tor layer consists of components that interact
exclusively at the transaction level, such as scoreboards, coverage collectors, stimulus generators, ete. All structural
elements in a UVM testbench are extended from the uvm_¢
mponent base class,Sequencer
[==] item] | Driver
seqs || peed]
—L. SS _ ______
‘The lowest level ofa UVM tesbench is interfacespeciie. For eadh interface, the UVM provides a uvm_agent that
includes the diver, monitor, stimulus generator (Sequencer) and (optionally) a coverage collector. The Agent thus
embodies all of the protocol-specitic communication with the DUT. The Agents) and othe, design-specific
COPonents are encapsulated in a wm env Environment component which isin turn instantiated and customane bya
top-level uvm_test component.
‘The uwm_sequenee_item — sometimes refered to asa transation = is a um_objet thal contains the data fields
assay to implement the protocol and communicate withthe DUT. The av. driver i responsi fx converting
the sequence_item() into “pin wiggles” onthe sgna-level inerface to snd and reeeve dais wns ec The
sequence objects that define stimulus atthe tansaction level and
Sequence_items are provided by one or more wvi
execute on the agent's wm sequencer component
arbitrating between them and routing sequence items bet
‘The uwmn_monitor is responsible for passively observing the pin-level behavior on the DUT interface, converting it
into sequence items and providing those sequence jtems to analysis components in the agent or elsewhere in the
testbench such as coverage collectors or scoreboards. UVM Agents also have a configuration objec that allows the
test writer to control aspects ofthe agent asthe testbench is assembled and executed,
By providing a uniform interface tothe tetbench. a UVM Agent isolates the tetbench and the UVM Sequence ffom
ils of the interface implementation. A sequence that provides data packets. for example, can be reused with
/M testbench will ypically have one
The sequencer is responsible for executing the sequences,
tween the driver and the sequence.
UYM Agents that may implement AHB, PCI or other protocols. A UV!
terface.
p, the UVM Agents and other components are encapsulated in a wvm_env environment component,
ign-specific. Like an agent, an environment typically has a configuration object associated with
0 control aspects of the environment as well as to control the agents instantiated in the
environments are themselves UVM components, they can be assembled into a higher-level
level designs are assembled into subsystems and systems, the block-level UVM environment
‘may be reused as a component in the subsystem-level environment, which can itself be
testbench./
/
f
fpssies
the enviros
ment has been defined,
octuding Customizing key
used in the environment
test del
the um.
ASpects OF the overall testber
: “choosing UVM Sequences
lining configurat
‘\ UVM lestbench is composed of component objects eendea from the uvm_component base class. When a
“Rn-somponent derived clas object is ereate, it becomes part ofthe textbereh hierarchy which persists for the
uation of the simulation, This eontasts withthe sequence branch ofthe UVM clan hierarchy which involves
“ranslent objects object that are created, used and destroyed (i. garbage collected) once dereference
Simplified UVM Inheritance Diagram
uvm_report_object uvm_transaction
uvm_component
uvm_sequence_item
uvm_sequence
Component Branch i
‘The (quasi) static uvm_component hierarchy is used by the UV}
Sequence Branch
'M reporting infrastructure to print the scope of a
component issuing a report message, by the configuration process to determine which components can access a
Configuration objec, and by the UVM factory to apply factory ovetdes. This component hierarchy is represented
by a linked list built up incrementally as each component is created, The hierarchical location ofeach component is
‘determined by the name and parent arguments passed to its ereate method at the time of construction,
For instance, in the code fragment below, an apb_agent component is created within the s
pi_env, Assuming the
spi_eny is instantiated in the top-level test component with the name "men"
the hierarchical path name of the
“uvm_test_top.m_env*, the “dot” (".") operator, and the
“hod, resulting in a hierarchical name for the agent of
“uvm_testtopim_env.m_apb_ayent". Any references tothe agent would need to use this string name.
We
U/ Hierarchical ni
“a
class spi_env extends uvn_env;
‘agent is the concatenation af the spi_env component's name,
rname passed as the first argument to the “ereate()" met
waUVM Components
apb_agent mapb_agent; // Declaration of che apb agent hangye
“
function void build _phase(uvm phase phase);
// Create the apb_agent
“
// Name string argument is the
same as the handle nane
// The parent argument is ‘this’ - i.e
wt
// The spi_env has a hierarchical path
this is concatenated
Mi
as the
the spi_env
th the name string to ary
at "uvm_test_top.m_env.m_apb agent
// hierarchical reference sty
ng for the apb agent
MLapb_agent = apb_agent: :type_id::create(*m_apb_agent
Ti
endfunction: build phase
7
endclass: spi_env
‘The wm_component clas inherits from the uvm_report_ object class which lis atthe heat ofthe UVM Messaging
infrastructure. The reporting process uses the component slatic hierarch
hy to add the scope of a component to the
report message string,
‘The uvm_component base class template has a virtual method
implemented by the user as required, A phase level virtual m
effectively not participating in that phase.
for each of the UVM Phases and these are to be
nethod that is not implemented results in the component
Also embedded into the wvm_component base class is support for @ configuration table to store configuration objects
that are relevant forthe components child nodes inthe testbench hierarchy. When the uvm, conf db API is used,
this static hierarchy is employed as part of the path mechanism to control which components May access a given
configuration object.
'm order to provide flexibility in configuration and to allow the UVM testbench hierarch
‘way, uvm_componens are registered with the UVM factory. When a UVM compon
Phas, the factory is used t0 construct the component abject. The UVM factory enabl
for another of a compatible, derived type using a factory override. This is a us.
functionality ofa testbench without changing the tetbench source code diretl, hi
and hinder reuse. There are a numberof coding conventions required forthe factory
the article on the UVM Factory.
¥ to be builtin an intelligent
rent is created during the build
les a component to be swapped
eful technique for altering the
ich would require recompilation
to work and these are outlined in
‘The UVM package contains a number of extensions (ie, derived classes) of the uvim_component base class for
common testbench components, Most ofthese extensions are very "thin", ie they are literally justa small extension
of the uvm_component class to add a new mame space. While these ate non-critical and in principle a
‘wm component clas could be used instead stil, they do help with “self documentation’ as they indicate clearly thepes
fysitable that also use these extraneous base classes as clues to help establish a picture ofthe testbench i
the other hand, some of the pre-built uvm_component extensions are in fact building blocks providing more
profound added value, by instantiate concrete sub-components. The follo
1g table summarizes the available UVM
‘component classes directly derived from the uvm_component base class:
Cas Description Contains
sub-components?
‘wm _driver | Eneapsulatessub-components for sequence comuniction wih the wv sequeneer Wo
‘uvm_sequencer | Encapsulates sub-components for sequence communication wath the uvm_driver No
Sa ubimriber | Ensapaies vn anals_epor and sociated viral wri tod wo implement analysis]
transaction processing
‘mew | Bais for agareeaing venfcation smponens around » DUT, o other envs in case of vera Ye
{subs ppstem iteration
Tract | Basis fora onerte wp Fevel test Ye
Tam_montor | Bass fora conerete monitor tramactor ie
‘vm peoreboud| Bass fora conse scoreboard Ye
pcr Baws To concrete agen mncloding wsequencer-diver pai and a monitor Yes
The UVM Factory
The UVM Factory
“The purpose of the UVM factory isto enable an object of one type to be substituted with an object of a derived type
without changing the testbench structure or even the tesibench code, The mechanism used is referred to as an
override. by either instance or type. This functionality is very handy for changing sequence behavior or replacing one
version of a component by another. Any’ to components to be swapped must be polymorphically compatible. This
includes the requirement that all the same TLM interface handles and TLM objects must be created by the
in order to take advantage of the factory certain coding conventions must be
tory Coding Convention 1: Registration
ert or object must contain factory rexistation code comprised of the following elements:
1_component_registry wrapper, typedefed to type_id
function to get the rype_id
to get the type name‘The UVM Factory
static function type_id get_type();
return type_id::get (Ji
endfunction
// Used to get the type_name as a string
function string get_type_name();
return “my_component",
endfunction
endelass: my_conponent
‘The registration code has regular pattern and canbe safely generated with one ofa set of four factory registration
‘macros:
// For a component
slasn my component extends uvm_component;
// Component factory registration macro
“uvm_component_ut ills (my_component)
“/ For a paramete:
zed component
class my_param_component ¢ (int Ai
DPMIDTH 20, int DATA_WIDTH. 7 5)
uvm_component;
*ypedef my param_ component #(ADD_WiDTH, DATALWIOTH) this_t.
// Parameterized component £
factory registra
Component param utils (this t)
// For a class derived from an object
uym_transaction, uv
class my item extends
uum_obje
Sequence_iten, uvm sequence etc.)
uym_sequence items
uym_object_utils(my_item)
// For a parameterized object cl,
clase my item # (int 2OD wrory
uvn_sequence_item;
acs
S) ane DATA_wIDHT.2
) extends
fypedet my_item #(R0D WIDTH, DATA WIDTH) this_e
“uvm_object.
Paramutils(this t)
extendsgsctory Coding Convention 2: Constructor Defaults
‘he wvm_component and uvm_object constructors are virtual methods with a prototype template that must be
adhered to by users. In order to support deferred construction during the build phase, the factory constructor should
contain defaults for the constructor arguments. This allows a factory registered class to be built inside the factory
using the defaults and then the class properties can be re-assigned to the arguments passed via the create method of |
the uwvm_component_registry wrapper class. The defaults are different for components and objets:
‘or a component
class my component extends uvm component:
function new(string name
ent", uvm_component parent = mull);
super.new(name, parent);
endfunction
class my_item extends uvm_sequence_item
function new(string name = "ry item");
super new (name
endfunction
Factory Coding Convention 3: Component and Object Creation
‘Testbench components are created during the build phase using the create method of the uvm_component_registry.
“This first constructs the class, then assigns the handle 10 the class to its declaration handle in the testbench after the
name and parent arguments are assigned correctly. For components the build process is top-down, which allows
higher level components and configurations to control what actually gets built,
‘Object clases are created as required, again using the create method. The following code snippet illustrates how this
is done
clase eny extends uvm_env:
my_component m_my_component;
my_param_component #(.RDDR |
m_my_p_component;
// Component and parameterized component create examples
function void build phase( uvm_phase phase 7
m_my_component = my_component: :type_id::create("m my component",
this); :
m_my_p component ~ my_param_component #(22, .
12) :stype_id: :ereate(
endfunction: build
mponent", this);
task run_phase( uvm_phase phase );
my_seq test_seq:The UVM Factory
my_param_seq 4(-RODR_MIDTH(32), .DATAWIDTH(32)) p test seq:
( Object and paraneterised object create exanpies
test_seq = my_seq::t: create("test seg);
P_test_seq = my param seq #(32, 32)
“7 :
endtask: run \
fype_td::create("p test_sea");
Phasing
The Standard UVM Phases
| Build phases - where the tstbench is configured and constructed
2. Runtime phases - where time is consume
"in running the testease on the testbench
3. Clean up phases - where the resus ofthe
festease are collected and reported
‘The different phase groups ate illustrated in the Giagram below. The uvim_component base class contains virtual
methods which are called by each of the differen, phase methods and these are populated by the testhench
cect! Stealr secording to which phases the component Participates in. Using the defined phases allows
‘erification components to be developed in isolation, but still be interoperable since there is @ common
Understanding of what should happenin each phase
a)
ace
Pre_shuldown:
ost_shuldown
it
ih
‘The UVM Phases,garting UVM Phase Execution
fo start UVM testbench, the ra_est() method has to be called from the
called rom within an initial block in the top level module ofthe testbench
Calling run_test() constructs the UVM environmer
run.
tate part ofthe testbench. It is usually
root component and then initiates the UVM phasing, ‘Th
Se ind ce rae! pm ae ah pee wh. segs Se
class which is used a8 the root node of the testbench hierarchy. However the un_test() method checks for a
‘command line plusarg called UVM_TESTNAME and uses that plusarg string to lookup a factory registered
tuvm_component, overriding any default type name. By convention, the root node wil
: be derived fiom a uvm_test
component, but it can be derived from any uvm_component, The root node defines the testcase to be executed by
specifying the configuration of the testbench components and the sinus tobe executed by them.
For instance, in order to specify the test component "my_test as the UVM testbench root class, the Questa command
line would be.
vsim th_top +UVM_TESTNAME=my_test
Phase Descriptions
‘The following section deseribes the purpose of each of the different UVM phases
Build Phases
The build phases are executed at the start of the UVM testbench simulation and their overall purpose is fo construct,
configure and connect the testbench component hierarchy.
‘All the build phase methods are functions and therefore execute in zero simul
time.
build
Once the UVM testbench root node component is constructed, the build phase starts to execute. I constructs the
teatbench component hierarchy from the top downwards, The construction of each component is deferred so that
tach layer in the component hierarchy can be configured by the level above. During the build phase
tuvm_components ae indreetly constructed using the UVM factory
connect
‘The connect phase is used to make TLM connections between components or to assign handles to testbench
esoures It has to occur after the build method has put the tetbench component hierarchy in place and works from
the bottom of the hierarchy upwards.
cend_of elaboration
‘The endo elaboration phase i used to make any fina adjustment to the stratre, configuration or connectivity of
the teabench before simulation stats. Its implementation ean assume thatthe tetbench component hierarchy and
ity is in place. This phase executes botiom up.
inter-connecti
Run Time Phases
‘Te tebench stimulus i generated and executed during the run ime phases which Follow the build phases. Aer the
li star_of simulation phase, the UVM executes the run phase and the phases prereset through (0 post_shutdown in
parallel, The run phase was present inthe OVM and is preserved tallow OVM components 0 bs easily migrated to
the UVM. Its also the phase that transactors will use, The oer phases were added fo the UVM to give fine re
time phase granularity for tests, scoreboards and other similar components. 1s expected that most testbenches will
| » Soly use reset, configure, main and shutdown and nt ther pre and pos variants
i
|
eee )Phasing
start_of simulation
‘The sa_of simulation phase is funtion which occurs before the time consuming part of the testbench begins, 1
ed 10 ¥: 0F configuration information. It is called in bottom
implement these phases.
re_reset
‘The pre_reset phase stars at the same time as the run Phase. Is purpose is to take care of any activity that should
ercat before reset, such as waiting fora power-good signal ta 80 active, We do not anticipate much use for this
Phase.
face specific reset behavior, For exam
ple, this phase would be used to
It state.
‘thing that is required to prepare forthe DUT's configuration process after
omponents (eg. drivers) required for configuration to complete training
e used as a last chi information described by the
reset is completed, such as waiting for c
and/or rate negotiation, It may also by
Pre_main
The pre_main phase is used to ensure
anticipate much use for this phase,erated and applied to the DUT. It completes when either
sta throughput will be handled by sequences stated in this
This phase is used to take ca
{0 eke care of any finalization of the main phase, We donot anticipate much use for this phase
re_shutdown
‘This phase isa buffer for any DUT stimulus tha
t needs fo take place before the shutdown phase, We do not
‘anticipate much use for this phase ; rT
shutdown,
The shutdown phase
he shutdown phase is used to ensure thatthe effects of the stimulus generated during the main phase have
Propagated through the DUT and that any resultant data has drained away. It might also be used to execute time
‘consuming sequences that read status registers,
ost_shutdown
Perform any final activities before exiting the active simulation phases. At the end of the post_shutdown phase, the
UVM testbench execution process stats the clean up phases. We do not anticipate much use for this phase (with the
Possible exception of some bject-to-one code)
Clean Up Phases
The clean up phases are used to extract information from scoreboards and functional coverage monitors to determine
‘whether the testcase has passed and/or reached its coverage goals, The clean up phases are implemented as functions
sand therefore take zero time to execute. They work fom the bottom to the top ofthe component hierarchy.
extract
‘The extract phase is used to retrieve and process information feom scoreboards and functional coverage monitors.
This may include the calculation of statistical information used by the report phase, This phase is usually used by
lysis components
check
‘The check phase is used to check that the DUT behaved correctly and to identify any erors that may have occurred
during the execution ofthe testbench. This phase is usually used by analysis components,
report
“The report phase is used to display the results ofthe simulation or to write the results to fle. This phase is usually
used by analysis components.
final
The final phase is used to complete any other outstanding actions thatthe testbench has not already completed.Overview
re UVM driv le We transaction level with the sequence via Thy
# communicating, at the transaction
Wi liver fs responsible for communicating, ay
ion side and pinlevel
ith the sequencer and converting, between the sequtence ie i pi
c implies, drivers typically get a
licaing, with the DUT vin a vital interlnee, Ax the name implies, drivers typically. gu
vertain applications, also r
ul uve thal information to drive signals to the DUT and may. in certain appl
he sequence to complete the
vel response from the DUT and convert it hack into a sequence item for the sequen i
0 fanetion ws a
lennsaetion, A diver may al
we mode") in which the driver rea
1 response transaction back to the driver to
ssponder" (ie
ie with a sequence that then send
‘complete the protacol tansaetion, When its nent is configured to b
instantiated in the agent
its 10 pin-level
ctv in the interface to conn
ni
passive mode, the driver is, by definition, not
Anatomy of a UVM Driver
‘A user-defined driver compunent isa
Prony class derived from a wm_ adver base
4 System Verilog interface. ‘The nw driver bas
the seq item export of the sper
5€¢ item. port as well, but vertain
‘9p. port ofthe driver. ¥
Connections,
18s ancl contains a BEM which is
1 class provide
Seq. item_port that gets conneeted by the agent to
Usually, responses are passed back tothe seq
lcationy may require that responses be sent back to the se
4 detailed discussion of commecting
‘wm, sequence
through the
«quencer via the
‘diver to a sequencer, please see Sequencer-Driver
UVM Driver API
‘The wm driver is designed ultimatel
ly to internet with a wm sequence
‘The det
tails Of this API are deseribed here
‘uning on the connected wm_sequencer
UVM Driver Use Models
Stimulus generation inthe UVM relies on a coupling between sequences and drivers,
when the characteristics of a diver are known, otherwise there 4 potentia
4 deadlock waiting for the other to
Provide an item. ‘This problem
base uilty sequences which can be
‘A sequence can only be written
forthe sequen
an be mitiga
or the driver to get into
ted for reuse by providing a set of
nenting the behavior of the driver,
‘There are a large number of
* forthe sequence driver combination, most of
which are discussed here,
\‘The key difference between &
ss on the interface. When an
ough a vinual interface. and contains code that recognizes protocol
Protocol pattem is recognized, a Monitor builds an abstract transaction model
SSPEGSavie that atvity and broadcessthe ranstion to any interested components
Construction
Monitors are composed of a proxy
7 lass which should extend from uvm_monitor and a BFM which is a
=e Verilog interface, The proxy should have ane analysis port and vita interface handle that pons toa BM.
interface,
Glass nb_bus_monitor extends uvm_monitors
‘wb_bus_monitor)
uymanalysis pore #{wb_txn) wb_mon_ap:
virtual wb_bus monitor bfm m_bfm; //B6tt handle
wb_contig m config;
function new(string name, uvm_component parent);
super new (name, parent);
endfunction
function void build phase( uvm_phase phase );
ap", thie);
we_mon_ap — new
config - wb_config::get_config(this}; // get config object
m_bfm — m_config.W8_mon_btm; // set local virtual if property
mbin.proxy this; //sct séM proxy handle
endfunction
se (uvm_phase phase);
mpbfm.run(); //Don't start che BFM until we get to the run_phase
endtack
task run_p!
function void notify transaction (wb txn item); //Used by BFM to
return transactions
wb_mon_ap.write (item);
endfunction : notify transaction
endelassUVM Monitor
\
sm (wishbone_bus_syscon_if wo bus 165
interface wo_bus_ponitor_bim (wishbone bos. sy" \
import wishbone pis
// Data Kenbers
Wr o ooo eaeee \
wip bue_monitor Proxy?
yanaee .
// woshoss
[own -
task son |
wio_txn tans |
/Jcaptare proocel pin nto txn }
proxy.notity transaction (tan! |
ena |
enatask |
endintertace |
Passive Monitoring
‘As in a scientific experiment the at of observing should not aeet the activity observed, monitor components should
be passive. They should nt inject any atvity into the DUT signals. Practically speaking, this means that monitor
code should be completely read-only when interacting with DUT signals. Additionally, the BEM will not being
‘bserving data uni intructed todo so bythe proxy to ensure tha the BFM is aligned with UVM phasing,
Recognizing Protocols
'A monitor must have knowledge ofa protocol in order to detect recognizable paters in signal activity. Deteetion
«an be done by writing potocolspecific state machine code inthe monitor BFM'srun( task. This code waits fora
patter of ky signal activity by observing through the pin interface handle,ing Transaction Objects :
Cree the pateen i secrrpines, ten
bee deme by
vity. This can
8 il ene on pensiby
* fin
‘ i tae
stn aed gas
Socstion. a by 9
cabin
‘aitiona thes soraetly represents the signal
9 We tacsivarippsitc aioe (oy data yalar and
tition sates oy ay ining transection as they are
hg wee haces, when 2 Mion
Cals the handle yet copied sod treads vy
tech its ongainng leap of peetnens
the nent iteration of the
the the Monitor created,
‘Wties tansaction bactle 8 of is analysis pom,
‘This wise operation heppess cach time the Monitor rns
Peni te Dich tae To presecs overuttng toe same Object memory in
loop, the ale thesis brendan should pais w a segura copy ofthe ansastion object
tnasibers,
This can be accomplished in tine
+ Creat
iw tranvaction abject in
h iteration of ie,
the loop
Kewve the same teansactins
a ine
f teration of the orp, bt clone the object immediaely prior to calling
“Writely and broadcast the handle of the ch
Broadcasting the Transaction
Once «new oF cloned transaction has been built iby
auld be brosdeast wo all interested observers by writing to an
analysis port
Example Monitor
forever %
LE te bu
(pomedge
% (posedge wine
end
else begin
wait