Sie sind auf Seite 1von 122

AdvancedUVM

intherealworld
Tutorial
MarkLi.erick
JasonSpro.
JonathanBromley
VanessaCooper

Accellera Systems Initiative 1


INTRODUCTION

Verilab & Accellera 2


WhatisUVM?

Application-specific code
VericaHonEnvironment
Uses UVM building blocks
Open source (Apache)
UniversalVericaHonMethodology Class library
(UVM) Consistent methodology
Facilitates interoperability
SystemVerilogIEEE1800 Supported by all simulators

Multi-language simulators
MentorTM
Questa IUSTM
Cadence VCSTM
Synopsys VHDL, Verilog,
SystemVerilog, SystemC

Verilab & Accellera 3


KeyElements
SystemVerilog Verification
Language Concepts
syntax constrained-random
RTL coverage-driven
OOP transaction-level
class sequences
interface scoreboards
etc... etc...

UVM Methodology
base-classes
use-cases
configuration-db
factory operation
phases
etc...
Verilab & Accellera 4
SystemVerilog
Languagesyntax&semanHcsareprerequisite
detailedunderstandingisnotuniquetoUVM...
...but,vericaHonsupersetmuchbiggerthandesign!

Design Verification
RTL signals OOP
blocks interfaces class
modules clocking-block random
vectors scheduling constraints
assignments functions coverage
arrays tasks queues
etc. etc. etc.

Verilab & Accellera 5


VericaHonConcepts
Genericlanguageindependentconceptsapply
detailedunderstandingisnotuniquetoUVM...
...but,implementaHondetailsdovary!

eRM Verification Concepts


architecture (env-agent-sqr/drv/mon) UVM
Vera
random configuration & build
constrained-random sequence stimulus
scoreboard & protocol checkers
AVM
functional coverage collection & analysis
VMM transaction-level modeling & TLM ports
messaging & simulation debug
OVM
verification planning & closure
etc...
Verilab & Accellera 6
Methodology
regmodel
Baseclasslibrary factory
congdb
genericbuildingblocks callbacks
soluHonstosoXwarepa.erns parameterizing
sequences
saveHme&eort seqitems
transacHons
Wayofdoingthings phases
consistentapproach transacHonrecording
eventpool
facilitatesinteroperability eldmacros
TLMports
engineeringresourceexibility
virtualinterfaces
range of complexity, messaging
implementation difficulty, components
and learning curve objects

Verilab & Accellera 7


TutorialTopics
Selectedbasedon:
experiencesonmanyprojectsatdierentclients
relaHvelycompleximplementaHonorconfusingforuser
benetfromdeeperunderstandingofbackgroundcode
requiremoredescripHonthanavailabledocumentaHon
DemysHfyingtheUVMConguraDonDatabase
BehindtheScenesoftheUVMFactory
EecHveSDmulus&SequenceHierarchies
AdvancedUVMRegisterModeling&Performance

Verilab & Accellera 8


Demys&fyingtheUVM
Congura&onDatabase
VanessaCooper,Verilab,Inc.
PaulMarrio?,VerilabCanada

Accellera Systems Initiative 1


Introduc&on
Whatistheuvm_cong_db?
Whenistheuvm_cong_dbused?
Howisdatastoredandretrieved?
HowdoIdebugwhensomethinggoeswrong?
Conclusion

Verilab & Accellera 2


WHATISTHECONFIGURATION
DATABASE

Verilab & Accellera 3


Congura&onDatabase
The database is essentially a lookup table
which uses a string as a key and allows you to
add and retrieve entries.

uvm_resource_db
datasharingmechanismwherehierarchyisnotimportant
eachentryiscalledaresource
whenaccessingthedatabase,youmustspecifythe
resourcetypeasaparameter

class uvm_resource_db#(type T=uvm_object)

Verilab & Accellera 4


Congura&onDatabase
Methods DescripGon
get_by_type Getstheresourcebythetypespeciedby
theparametersotheonlyargumentisthe
scope
get_by_name Getsaresourcebyusingboththescope
andname
set Createsanewresourceinthedatabase
read_by_name Locatestheresourceusingthescopeand
name
read_by_type Locatestheresourceusingonlythescope

write_by_name Createstheresourcebyscopeandname
write_by_type Createstheresourcebyscopeonly

TABLE 1: uvm_resource_db methods

Verilab & Accellera 5


Congura&onDatabase
Example: A scoreboard has a bit disable_sb that turns off checking if the
value is 1. How do you change the value of that bit using the
uvm_resource_db?

uvm_resource_db#(bit)::set(CHECKS_DISABLE,
static function void set(input string scope, disable_scoreboard,
input string name, 1, this);
T val,
input uvm_object accessor=null)

static function bit read_by_name(input string scope,


input string name,
uvm_resource_db#(bit)::read_by_name(CHECKS_DISABLE,
inout T val,
disable_scoreboard,
input uvm_object accessor=null)
disable_sb);

All functions are static and must


use scope resolution operator ::
Verilab & Accellera 6
Congura&onDatabase
Example: Using the uvm_resource_db with register tests

uvm_resource_db#(bit)::set({REG::,
m_env.m_reg.get_full_name( ),
.cfg_reg},
NO_REG_TESTS, 1, this);

Verilab & Accellera 7


WHENISTHECONFIGURATION
DATABASEUSED

Verilab & Accellera 8


Congura&onDatabase
The database is essentially a lookup table
which uses a string as a key and allows you to
add and retrieve entries.

uvm_cong_db
usedwhenhierarchyisimportant
canspecify,withgreatdetail,thelevelofaccesstoa
resource
almostalwaysusedinsteadoftheresourcedatabase

class uvm_config_db#(type T=int) extends uvm_resource_db#(T)

Verilab & Accellera 9


DATASTORAGEANDRETRIEVAL

Verilab & Accellera 10


Congura&onDatabase
cntxt: starting point
set adds object to the uvm_config_db
get retrieves an object from the uvm_config_db
inst_name: instance name
which limits accessibility

static function void set(uvm_component cntxt,


string inst_name,
string field_name,
T value)

field_name: label used for lookup

value: value to be stored

Verilab & Accellera 11


Congura&onDatabase
cntxt: starting point Example: The Virtual Interface

inst_name: instance name tb_intf)::set(uvm_root::get( ),


uvm_config_db#(virtual
which limits accessibility *,
dut_intf,
vif);

* should rarely be used


field_name: label used for lookup

value: value to be stored

Verilab & Accellera 12


Congura&onDatabase
uvm_config_db#(TYPE)::set(uvm_root::get( ),*.path,label,value);

dut_intf vif

retry_count rty_cnt

my_env_cfg env_cfg

uvm_config_db#(TYPE)::get(this,,label,value);

retry_count rty_cnt

Verilab & Accellera 13


DEBUGGING

Verilab & Accellera 14


Congura&onDatabase
Whats the first step in debugging?

if(!uvm_config_db#(TYPE)::get(this,,label,value))
`uvm_fatal(NOVIF, Virtual interface GET failed.)

Verilab & Accellera 15


Congura&onDatabase
sim_cmd +UVM_TESTNAME=my_test +UVM_RESOURCE_DB_TRACE

sim_cmd +UVM_TESTNAME=my_test +UVM_CONFIG_DB_TRACE

UVM_INFO reporter [CFGDB/SET] Configuration *_agent.*_in_intf


(type virtual interface dut_if) set by = (virtual interface
dut_if)

UVM_INFO report [CFGDB/GET] Configuration


uvm_test_top.env.agent.driver.in_intf (type virtual interface
dut_if) read by uvm_test_top.env.agent.driver = (virtual
interface dut_if) ?

Verilab & Accellera 16


CONCLUSION

Verilab & Accellera 17


Congura&onDatabase
Thedatabaseisapowerfulfacilityusedintestbench
constuc&on
Theresourcedatabasecanbethoughtofasapoolof
variablesusedwithoutconcernforhierarchy
Thecongura&ondatabaseisstructured
hierarchicallyandismoresuitedtodatathatis
relatedtothestructureofthetestbenchitself.

Verilab & Accellera 18


REFERENCES

Verilab & Accellera 19


Addi&onalReading&References

h?p://www.accellera.org
VanessaCooper,GeMngStartedwithUVM:A
BeginnersGuide,1sted,VerilabPublishing,2013

Verilab & Accellera 20


Ques&ons

Accellera Systems Initiative 21


BehindtheScenesofthe
UVMFactory
MarkLi7erick,VerilabGmbH.

Accellera Systems Initiative 1


IntroducAon
Factorypa*erninOOP
standardsoEwareparadigm
Implementa0oninOVM/UVM
baseclassimplementaAonandoperaAon
UsageoffactoryandbuildconguraAon
understandingdetailedusagemodel
Debuggingfactoryproblems&gotchas
thingsthewatchoutforandcommonmistakes
Conclusion
addiAonalreadingandreferences
Verilab & Accellera 2
FACTORYPATTERN

Verilab & Accellera 3


SoEwarePa7erns
In software engineering, a design pattern is
a general reusable solution to a commonly
occurring problem within a given context.

SystemVerilogisanObjectOrientedProgramminglanguage
OVM/UVMmakeextensiveuseofstandardOOPpa*erns
FactorycreaAonofobjectswithoutspecifyingexacttype
ObjectPoolsharingsetofiniAalizedobjects
Singletonensureonlyoneinstancewithglobalaccess
Proxyprovidessurrogateorplaceholderforanotherobject
Publisher/SubscriberobjectdistribuAonto0ormoretargets
Strategy/Policyimplementbehaviouralparametersets
etc...

Verilab & Accellera 4


TheFactoryPa7ern
The factory method pattern is an object-oriented creational design pattern
to implement the concept of factories and deals with the problem of creating
objects without specifying the exact class of object that will be created.
OVM/UVMimplementaversionofthefactorymethodpa7ern
Factorymethodpa7ernoverview:
deneaseperatemethodforcreaAngobjects
subclassesoverridemethodtospecifyderivedtype
clientreceiveshandletoderivedclass
Factorypa7ernenables:
usersoverrideclasstypesandoperaAon
withoutmodifyingenvironmentcode
justaddderivedclass&overrideline
originalcodeoperatesonderivedclass
withoutbeingawareofsubsAtuAon

substitute any component or object in the verification
environment without modifying a single line of code

Verilab & Accellera 5


FactoryUsageinOVM/UVM
Factoryisanessen0alpartofOVM/UVM
requiredfortestregistraAonandoperaAon
recommendedforallcomponents
(env,agent,sequencer,driver,monitor,scoreboard,etc.)
recommendedforallobjects
(cong,transacAon,seq_item,etc.)
notappropriateforsta0cinterconnect
(TLMport,TLMFIFO,covergroup,interface,etc.)
OperatesinconjuncAonwithconguraAon
bothaecttopologyandbehaviorofenvironment
factoryresponsibleforinstandtypeoverridesandconstruc0on
congura0onresponsibleforbuildandfunc0onalbehavior

Verilab & Accellera 6


FACTORYIMPLEMENTATION

Verilab & Accellera 7


OVM/UVMFactoryImplementaAon

ThemainO/UVMlesare:
o/uvm_object_denes.svh
o/uvm_registry.svh
a great benefit of OVM/UVM is that
o/uvm_factory.svh all source-code is open-source
Overview:
userobjectandcomponenttypesareregisteredviatypedef
factorygeneratesandstoresproxies:*_registry#(T,Tname)
proxyonlyknowshowtoconstructtheobjectitrepresents
factorydetermineswhattypetocreatebasedonconguraAon,then
asksthattypesproxytoconstructinstancefortheuser

Verilab & Accellera 8


UserAPI
Registercomponentsandobjectswiththefactory
`uvm_component_utils(component_type) do not use deprecated
sequence*_utils
`uvm_object_utils(object_type)

Constructcomponentsandobjectsusingcreatenotnew
componentsshouldbecreatedduringbuildphaseofparent
component_type::type_id::create(name,this);

object_type::type_id::create(name,this);
Usetypebasedoverridemechanisms
set_type_override_by_type(...); do not use
name-based API
set_inst_override_by_type(...);

Verilab & Accellera 9


`uvm_component_uAlsMacro
`define uvm_component_utils(T) \
`m_uvm_component_registry_internal(T,T) \
class my_comp extends uvm_component;
`m_uvm_get_type_name_func(T) \
`uvm_component_utils(my_comp)
endclass
`define m_uvm_component_registry_internal(T,S) \
typedef uvm_component_registry #(T,`"S`") type_id; \
class
staticmy_comp
functionextends
type_iduvm_component;
get_type(); \
typedef uvm_component_registry
return type_id::get(); \ #(my_comp,"my_comp") type_id;
static function
endfunction \ type_id get_type();
return type_id::get();
virtual function
endfunction
explains
uvm_object_wrapper what my_comp::type_id
get_object_type(); \ is
return
declared type_id::get();
a typedef specialization \
virtual function uvm_object_wrapper get_object_type();
ofendfunction
uvm_component_registry
return type_id::get(); class
endfunction but what about register and ::create ???
`define m_uvm_get_type_name_func(T) \
conststatic
const staticstring
stringtype_name
type_name==`"T`";
"my_comp";
\
virtual function string get_type_name ();
virtual function string get_type_name (); \
return type_name;
return type_name; \
endfunction
endfunction
endclass

Verilab & Accellera 10


uvm_component_registryRegister
class uvm_component_registry proxy type
#(type T, string Tname) extends uvm_object_wrapper;
lightweight substitute for real object
typedef uvm_component_registry #(T,Tname) this_type;
local static this_type me = get(); local static proxy variable calls get()
static function this_type get();
if (me == null) begin construct instance of proxy, not real class
uvm_factory f = uvm_factory::get();
me = new;
register proxy with factory
f.register(me);
end
registration is via static initialization
return me;
endfunction => happens at simulation load time
function void uvm_factory::register (uvm_object_wrapper obj);
virtual function uvm_component create_component (name,parent)...
...
static function T create (name, parent, contxt)...
// add to associative arrays
static function void set_type_override (type, replace)...
m_type_names[obj.get_type_name()] = obj;
static function void set_inst_override (type, inst, parent)...
m_types[obj] = 1;
endclass
...
to register a component type, you only need a typedef
endfunction
specialization of its proxy class, using `uvm_component_utils
Verilab & Accellera 11
uvm_component_registryCreate
comp = my_comp::type_id::create(comp,this);

uvm_component_registry #(my_comp,"my_comp") static create function

class uvm_component_registry #(T, Tname) extends uvm_object_wrapper;


...
static function T create(name,parent,contxt="");
uvm_object obj; request factory create based on existing type overrides (if any)
uvm_factory f = uvm_factory::get();
obj = f.create_component_by_type(get(),contxt,name,parent);
if (!$cast(create, obj)) uvm_report_fatal(...);
return handle to real override object
endfunction
virtual function uvm_component create_component (name,parent);
T obj;
search queues for overrides
obj = new(name, parent);
return obj; uvm_component uvm_factory::create_component_by_type
function
endfunction
(type,contxt,name,parent);
... requested_type = find_override_by_type(requested_type, path);
endclass return requested_type.create_component(name, parent);
endfunction
call create_component for proxy of override type
Verilab & Accellera 12
FactoryOverrides
not shown: use static *_type::get_type() in all cases
Userscanoverrideoriginaltypeswithderivedtypes:
usingregistrywrappermethods

original_type::type_id::set_type_override(override_type);

original_type::type_id::set_inst_override(override_type,...);
usingcomponentfactorymethods

set_type_override_by_type(original_type,override_type);

set_inst_override_by_type(...,original_type,override_type);

Factoryconstructsoverridedescriptorandaddstoaqueue:

function void uvm_factory::set_type_override_by_type (...);


override = new(...);
m_type_overrides.push_back(override);
endfunction
this is the queue searched by uvm_factory::find_override_by_type
Verilab & Accellera 13
FactoryOperaAon
a extends uvm_comp; uvm_registry#(a,a) uvm_factory
`uvm_comp_utils(a) get() register()
set_override() set_override_by_type()
create() create_comp_by_type()
b extends a; create_comp() find_override_by_type()
`uvm_comp_utils(b)
uvm_registry#(b,b) m_types[obj]
test get() a 1
a::type_id::set_override(b) set_override() b 1
create() b :
env create_comp() o 1
a::type_id::create()
m_type_overrides[$]
:
register uvm_registry#(o,o)
a,b
override ...
create)

Verilab & Accellera 14


SummaryofFactoryOperaAon
usersonlyhavetocallmacrostoregistertypeswithfactory
resulAngtypedefisenoughforregistraAontooccur
staAciniAalizaAonregistersproxyclasseswithfactory
calltype_id::createinsteadofnew
allowsfactorytosearchfortypeoverrides
factorycreatesinstanceofrequiredtypeandreturnshandle
componentscallcreateinbuildphasetoallowconguraAon
overrideusingtypebasedinterface
factoryconstructsdescriptorofoverrideandaddstoqueue
overridescanbeperinstanceorforallinstancesofthattype
overridetypesmustderivefromoriginaltypes
externallescanmodifyenvironmentclassstructureand
behaviorwithoutchangingcode

Verilab & Accellera 15


CONFIGURATIONDATABASE

Verilab & Accellera 16


OVM/UVMConguraAonOverview
OVM&UVMprovideglobalandcomponentset/get_cong*
forint(integral),stringandobjecttypes,e.g.
set_config_object("inst","field",value,0);

if (!this.get_config_object("field",value)) `uvm_fatal(...)

UVMthesearemappedtocong_db,e.g.(simplicaAon)
function void set_config_object("inst","field",value);
uvm_config_db#(uvm_object)::set(this,"inst","field",value);
endfunction
InUVMitisrecommendedtousecong_dbexplicitly
uvm_config_db#(my_type)::set(cntxt,"inst","field",value);

Implementsstringbasedlookuptablesinadatabase
set methods do not configure targeted component fields directly

Verilab & Accellera 17


AutomaAcFieldConguraAon
Normallytheuserhastodoanexplicitgetfromdb,e.g.
uvm_config_db#(my_type)::get(this,"","field",value)

buildphaseforcomponentbaseclassautomaAcally
conguresalleldsregisteredusingeldmacros
function void uvm_component::build_phase(...);
apply_config_settings(..); // search for fields & configure
endfunction

buildphaseforderivedcompsmustcallsuper.build
class my_comp extends uvm_component;
missing field-macro results in no auto-config
`uvm_component_utils_begin(my_comp)
`uvm_field_int(my_field,UVM_DEFAULT)
...
missing super.build results in no auto-config
function void build_phase(...);
super.build_phase(..);
// class-specific build operations like create

Verilab & Accellera 18


INTERACTIONOF
FACTORY&CONFIGURATION

Verilab & Accellera 19


ExampleEnvironment
class my_comp extends uvm_component;
`uvm_component_utils(my_comp)
endclass register class type with factory

class my_obj extends uvm_object;


`uvm_object_utils(my_obj)
endclass
class my_env extends uvm_env;
my_comp comp;
my_obj obj;
register field for automation
`uvm_component_utils_begin(my_env)
`uvm_field_object(obj,UVM_DEFAULT)
`uvm_component_utils_end allow auto-config using apply_config_settings()
function new(..);
function void build_phase(..);
super.build_phase(..); (example) requires obj to be in config_db
if (obj==null) `uvm_fatal(..) (there is no create/new inside this env)
comp = my_comp::type_id::create(comp,this);
endfunction
endclass use create() instead of new() for children

Verilab & Accellera 20


ExampleCongureandOverride
class test_comp extends my_comp;
`uvm_component_utils(test_comp) must be derived in order to substitute
// modify behavior
endclass class test_comp extends uvm_component;
does not work, must be derived from my_comp
class my_test extends uvm_test;
my_env env;
my_obj obj;
`uvm_component_utils(my_test)
function new(..);
function void build_phase(..); create using factory (results only in new not build)
super.build_phase(..);
env = my_env::type_id::create(env,this);
obj = my_obj::type_id::create(obj,this);
set_type_overide_by_type( override type in factory prior to env::build
my_comp::get_type(),
test_comp::get_type()); configure obj in db prior to env::build
set_config_object(env,obj,obj,0);
endfunction
endclass build phase is top-down
lower-level child::build comes after parent::build completed
Verilab & Accellera 21
OverrideOrder
override env and comp before my_env::type_id::create is always OK

remember create only results in a new() not a build

function void my_test::build_phase(..);


...
set_type_overide_by_type(my_comp,test_comp); // Good
set_type_overide_by_type(my_env,test_env); // Good
env = my_env::type_id::create(env,this);
set_type_overide_by_type(my_comp,test_comp); // Good
set_type_overide_by_type(my_env,test_env); // Bad
...
endfunction override comp after my_env::type_id::create is OK
since my_comp is not yet created
(it is created later in my_env::build_phase)

override env after my_env::type_id::create is BAD


since my_env is already created
(hence override is simply ignored)
Verilab & Accellera 22
CongureOrder
set_config using a null value is an error
(obj is not yet constructed)

set_config after obj is created and before env is created is OK


(env create does not use the value anyway)
function void my_test::build_phase(..);
...
set_config_object(env,obj,obj,0); // Bad
obj = my_obj::type_id::create(obj,this);
set_config_object(env,obj,obj,0); // Good
env = my_env::type_id::create(env,this);
set_config_object(env,obj,obj,0); // Good
...
endfunction set_config after both obj and env are created is also OK
(obj setting in config_db is not used until env::build phase)

so set_config* can come before or after the create for corresponding component!

do not confuse create (which tells the factory to new original or override type)
with build phase (which is top-down dynamic building of environment)
Verilab & Accellera 23
InteracAonofFactory,Cong&Build
test
class my_test extends uvm_test;
env
function new(..);
test
function void build_phase(..);
comp
env = my_env::type_id::create(env,this);
obj = my_obj::type_id::create(obj,this); obj
set_type_overide_by_type(my_comp,test_comp);
set_config_object(env,obj,obj,0);
endfunction obj
endclass
factory
class my_env extends uvm_env; test
`uvm_field_object(obj,UVM_DEFAULT) comp
function void build_phase(..);
super.build_phase(..);
if (obj==null) `uvm_fatal(..) db
comp = my_comp::type_id::create(comp,this);
endfunction obj
endclass

Verilab & Accellera 24


FACTORY&CONFIGURATION
PROBLEMS

Verilab & Accellera 25


ProblemDetecAon
FactoryandconguraAonproblemsareespeciallyfrustra0ng
oEenthecodecompilesandruns,becauseitislegalcode
butignorestheuseroverridesandspecializaAon
Dierentkindsofproblemsmaybedetected:
atcompileAme(ifyouareluckyorcareless!)
atrunAme(usuallyduringiniAalphases)
never...
...byinspecAononly!
WorsesAll,accuracyofreportistooldependant
althoughsomebugsarereportedbyOVM/UVMbaseclasses
factory and configuration problems are a special category of bugs

Verilab & Accellera 26


CommonFactoryProblems
usingnewinsteadof::type_id::create
typicallydeepinhierarchysomewhere,andnotexposed
derivingoverrideclassfromsamebaseasoriginalclass
overrideclassmustderivefromoriginalclassforsubsAtuAon
performing::type_id::createonoverrideinsteadoforiginal
thiswilllimitexibilityandwasprobablynotintended
factoryoverrideaVeraninstanceoforiginalclasscreated
thisorderproblemishardtoseeandreportsnoerrors
confusingclassinheritancewithbuildcomposi0on
superhasnothingtodowithparent/childrelaAonship
itisonlyrelatedtosuperclassandsubclassinheritance
badstringmatchingandtyposwhenusingnamebasedAPI
namebasedfactoryAPIisnotrecommended,usetypebased

Verilab & Accellera 27


CommonConguraAonProblems
missingeldmacrowhenusingautomaAcconguraAon
apply_cong_se?ngs()onlyworkswithregisteredelds
missingsuper.build*whenusingautomaAc
conguraAon
apply_cong_se?ngs()isonlyinuvm_componentbase
missingcong_bd::getwhencong_db::setwasused
cong_db::setdoesnotinteractwithapply_cong_se?ngs()
needanexplicitcong_db::gettoretrievesefngs
a7empAngset_cong_objectonanullobject
badstringmatchingandtyposforinstandname
sefngs
scopeandcontextproblemswithstringbasedcong
Verilab & Accellera 28
DebuggingHints
callfactory.print()inbasetestend_of_elaboraAonphase
printsallclassesregisteredwithfactoryandcurrentoverrides
if (uvm_report_enabled(UVM_FULL)) factory.print();
callthis.print()inbasetestend_of_elaboraAonphase
printstheenAretestenvironmenttopologythatwasactuallybuilt
if (uvm_report_enabled(UVM_FULL)) this.print();
temporarilycallthis.print()anywhereduringbuild
e.g.attheendofrelevantsuspiciousnewandbuild*funcAons
use+UVM_CONFIG_DB_TRACEtodebugconguraAon
paya7enAontothehandleidenPersintoolwindows
e.g.component@123orobject@456
theyshouldbeidenAcalforallreferencestothesamething

Verilab & Accellera 29


CONCLUSION&REFERENCES

Verilab & Accellera 30


Conclusion
OVM/UVMFactoryiseasytouse
simpleuserAPIandguidelines
complicatedbehindthescenes
canbediculttodebug
StandardOOPpa*ernnotinventedforOVM/UVM
UsedinconjuncAonwithconguraAontocontroltestbench
topology,classtypes,contentandbehavior
withoutmodifyingsourcecodeofenvironment
YoudonotneedtounderstanddetailedinternaloperaAon
butOVM/UVMhaveopensourcecode
sowecanseehowitisimplementedandlearn...
...coolstuthatkeepsusinterestedandinformed!

Verilab & Accellera 31


AddiAonalReading&References
OVMandUVMbaseclasscode
OVMandUVMclassreferencedocumentaAon
TheOVM/UVMFactory&FactoryOverrides:HowTheyWork
WhyTheyAreImportant
SNUG2012,CliCummings,www.sunburstdesign.com
ImproveYourSystemVerilogOOPSkills:ByLearning
PrinciplesandPa]erns
SVUG2008,JasonSpro7,www.verilab.com
h7ps://vericaAonacademy.com/sessions/understanding
factoryandconguraAon
VericaAonAcademyVideo,Mentor
h7p://cluelogic.com/2012/11/uvmtutorialforcandy
lovers10insidecandyfactory/
UVMTutorial,ClueLogic
Verilab & Accellera 32
QuesAons

Accellera Systems Initiative 33


UVMS&mulusandSequences

JonathanBromley,VerilabLtd
MarkLi=erick,VerilabGmbH

Accellera Systems Initiative 1


Introduc&on
tbd

Verilab & Accellera 2


GETTINGTHEBASICSRIGHT

Verilab & Accellera 3


UVMs&mulusarchitecturereview
UVM
Monitor+driver+sequencer sequences

=ac#veagent
agent
implemen&ngaprotocol C
sqr
S&mulusdrivenintoDUT sequence
monitored
items
byadriver items

driver monitor
S&mulusdatasenttodriver
fromasequencer
Runsequencesonsequencer
tomakeinteres&ngac&vity DUTobj

obj

Verilab & Accellera 4


S&mulustransac&onclass(item)
ItembaseclassshouldcontainONLYtransac&ondata
class vbus_item extends uvm_sequence_item;
rand logic [15:0] addr; Used by monitor
...
UVM
`uvm_object_utils_begin(vbus_item) sequences
`uvm_field_int(addr, UVM_DEFAULT)
agent
...
sqr

monitored
sequence items

S6mulusitemneedsaddi&onal items

driver monitor

constraintsandcontrolknobs
class vbus_seq_item extends vbus_item;
rand bit only_IO_space; Bus protocol controls only!
constraint c_restrict_IO { Class is part of uVC
only_IO_space -> (addr >= 'hFC00); NO distribution constraints
} ... NO DUT-specific strategy

Verilab & Accellera 5


Lowlevelsequences
Simple,generalpurposestreamoftransac&onswith
Not DUT-specific! Supplied with the uVC
somecoordina&on
class vbus_seq_block_wr extends vbus_sequence;
UVM
rand bit [15:0] block_size;
sequences
rand bit [15:0] base_addr;
constraint c_block_align { agent

sqr
block_size inside {1,2,4,8,16};
monitored
addr % block_size == 0; NO distribution constraints sequence items
items
} NO DUT-specific strategy driver monitor
rand vbus_seq_item item;
task body();
for (int beat=0; beat<block_size; beat++) begin
`uvm_do_with( item,
{addr==base_addr+beat; dir==WR;} )
end
endtask Behaviour is meaningful even without any external constraint
...

Verilab & Accellera 6


Thestorysofar...
providesaexiblebaseforcustomiza&on
doesnotrestricttheuVC'sapplicability
alreadyinteres&ngforreac&veslavesequences
predominantlyrandom
moreguidancelaterinthissec&on
maybeusefulforsimplebringuptests

Verilab & Accellera 7


LAUNCHINGSEQUENCES

Verilab & Accellera 8


Launchingasequence:`uvm_do
Onsamesequencer,fromanothersequence'sbody
goodforsimple class vbus_seq_block_wr ...
rand bit [15:0] block_size;
sequencehierarchy rand bit [15:0] base_addr;

class vbus_seq_bwr2 extends vbus_sequence;


vbus_seq_block_wr bwr_seq;
task body();
bit [15:0] follow_addr; lower sequence runs on same sequencer
`uvm_do( bwr_seq )
follow_addr = bwr_seq.base_addr + bwr_seq.block_size;
`uvm_do_with( bwr_seq, {base_addr == follow_addr;} )
...

constraint using values picked from


previous sequence's randomization

Verilab & Accellera 9


Launchingasequence:`uvm_do_on
UVM
Onadierentsequencer sequence virtualsequencer
goodforvirtualsequences p_sequencer
sqr_v sqr_i
`uvm_do_on
vbus I2C
S
vbus_seq UVC
Si2c_seq
UVC

class collision_seq extends dut_sequence; D M D M


`uvm_object_utils(collision_seq)
`uvm_declare_p_sequencer(dut_sequencer)
vbus_write_seq vbus_seq; datatype of virtual sequencer
i2c_write_seq i2c_seq;
task body(); properties of the virtual sequencer
fork
`uvm_do_on_with(vbus_seq, p_sequencer.sqr_v, {...})
`uvm_do_on_with(i2c_seq, p_sequencer.sqr_i, {...})
join
...

Verilab & Accellera 10


Launchingasequence:start
Canbecalledfromanycode
Alwaysusedtostarttopleveltestsequence
UVM environment

virtualsequencer
class smoke_test extends dut_test;
`uvm_component_utils(smoke_test)
S vbus
S I2C
smoke_test_seq test_seq;
UVC

UVC

base_dut_env env; D M D M

...
task run_phase(uvm_phase phase);
...
test_seq = smoke_test_seq::type_id::create("smoke_test");
...
test_seq.start(env.top_sequencer); start(null) is possible
...
configure/randomize the test seq

Verilab & Accellera 11


ReviewofUVM1.2changes
Defaultsequenceofsequencerisdeprecated
<describeotherconsequentchanges>

Verilab & Accellera 12


Exploi&ngthesequencer
m_sequencer
referencetothesequencerwe'rerunningon
datatypeisuvm_sequence,toogenericformostuses
p_sequencer
existsonlyifyouuse`uvm_declare_p_sequencer
hasthecorrectdatatypeforthesequence'sexpected
sequencerclass
allowsaccesstomembersofthatclass
persistentdataacrossthelifeofmanysequences
storageofcongura&oninforma&on,subsequencerreferences,...

Verilab & Accellera 13


Virtualsequencesandsequencers
Withoutasequenceitem
Rolesandresponsibili&es
Methodologydetailscomelaterinthissec&on

Verilab & Accellera 14


Sequenceswithoutsequencers?
Werecommendyoudonotdothis
Ahierarchyofsequencersallowsclearisola&onof
concerns
eachlayeroftheTBtakesresponsibilityforitsownac&vity
makeuseoffacili&esprovidedbylowerlevels
Eachsequencercanbegivenreferencestoallthe
lowerlevelsequencersitneedstouse

Verilab & Accellera 15


Examplehierarchicalsequences
TBD:exampleshowingdierentstylesofconstraint
anddierentsequencedesignconcernsateachlevel
lowest(UVC)level:completelygeneric,nostrategy,only
legalityandcontrolknobstocongurelegalityandbasic
values
UVCsequencelibrarylevel:abigrepertoireofsequences
toperformtypicalopera&ons,withcontrolknobsrelevant
tothoseopera&ons
DUTlevel:coordinatesequencesacrossmul&pleUVCsto
establishsetupac&vity,typicalopera&onscenarios,error
condi&ons

Verilab & Accellera 16


Responsibili&esofsequencesat
variouslevels
TBD:seepreviousslide,closerlookatconcernson
eachlevel
roleofcontrolknobsinseqvs.scenario
dierentstylesofconstraintatdierentlevels

Verilab & Accellera 17


Readbackfromasequence
Ifasequencedoessomethingthatreturnsaresult...
readdatafromabus
transac&onhasaresponsevalue
...laterpartsofthesequencemayneedtheresult
Forasequenceitem:getresultdirectlyfromthe
itemwhenthesequencehasnished
Forasequence:providestorageinthesequence,
populatefromlowerlevelsequenceoritem
needsconsistentplanningthroughthesequencehierarchy

Verilab & Accellera 18


Readbackfromasequence
TBD:severalslidesillustra&ngpreferredtechniques
briefmen&onofmethodsbasedonuseofthe
monitor
somemen&onofitem_done()responses,generally
discouragedbe=ertousereftorequestitem

Verilab & Accellera 19


Usingauvm_regmodelinsequences
(briey!)
builtinregsequences
readingandwri&ngregisters

Verilab & Accellera 20


Howsequencesshouldinteractwith
thecongDBandusercongobjects
Sequencesshouldavoidpullingdatadirectlyfrom
thecongDB
heavyperformanceoverhead
Asalways,populateacongobjectfromthecong
DBatbuild&me
Areferencetoacentralizedcongobjectmeansthatvalue
updatesinthecentralobjectareautoma&callyvisible
Sequenceshouldlookintoitssequencertond
congobject
usingp_sequencer

Verilab & Accellera 21


Guidelinesforusingobjec&onsin
sequences
roughly,don't
buttherearesomeexcep&ons
TBD:prescrip&veguidanceandsugges&ons,probably
"onlyintopleveltestsequence"(???)

Verilab & Accellera 22


Acoupleoffancyexamples:
TBD:
interruptsequence(illustrateuseofgrab)
randomchoiceofsequenceinascenario(using
uvm_sequence_library????)

Verilab & Accellera 23


CONCLUSION&REFERENCES

Verilab & Accellera 24


Conclusion
TBD

Verilab & Accellera 25


Addi&onalReading&References
UVMbaseclasscode
UVMclassreferencedocumenta&on
...

Verilab & Accellera 26


Ques&ons

Accellera Systems Initiative 27


AdvancedUVMRegister
Modeling&Performance
MarkLi(erick,VerilabGmbH.

Accellera Systems Initiative 1


Introduc9on
UVMregistermodeloverview
structure,integra9on,concepts&opera9on
eldmodeling,accesspolicies&interac9on
behaviormodica9onusinghooks&callbacks
Modelingexamples
workedexampleswithmul9plesolu9onsillustrated
eldaccesspolicies,eldinterac9on,modelinterac9on
Registermodelperformance
impactoffactoryonlargeregistermodelenvironments

2
Verilab & Accellera 2
REGISTERMODELOVERVIEW

Verilab & Accellera 3


RegisterModelStructure
Registermodel(orregisterabstrac+onlayer)
modelsmemorymappedbehaviorofregistersinDUT
topology,organiza9on,packing,mapping,opera9on,...
facilitatessKmulusgenera9on,checks&coverage
REGISTER BLOCK REGISTERS FIELDS DUT
CPU F/W
REG MODEL
R1 FA FB FC FD
MEM R1
R2 FE FF
MEMORY MEM
R2
R3 FG
... R3
RX FX ...
ADDRESS ADDR ...
MAP RX
MAP RN FL FN
...
RN
MIRRORED VALUE ACTUAL VALUE
4
Verilab & Accellera 4
RegisterModelIntegra9on
REG MODEL ENV DUT
R1 SEQ
MEM VS C CPU F/W

R2
... R1
MEM
MAP RN
C BUS UVC
R2

R3

INTERFACE
...

VIF
ADAPTER S D NORMALLY AUTO-
GENERATED
RX
...
VIF
PREDICTOR M DUE TO REGULAR
AGENT RN
STRUCTURE AND LARGE SIZE

SetofDUTspeciclesthatextenduvm_reg*base
Instan9atedinenvalongsidebusinterfaceUVCs
adapterconvertsgenericread/writetobustransac9ons
predictorupdatesmodelbasedonobservedtransac9ons
5
Verilab & Accellera 5
RegisterModelConcepts
REG MODEL ENV DUT
R1 SEQ
MEM VS C CPU F/W

R2 BACKDOOR ACCESS
... R1
MEM
MAP RN
C BUS UVC
R2

R3

INTERFACE
FRONT-DOOR ACCESS ...

VIF
ADAPTER S D
VOLATILE
RX UPDATE
...
VIF
PREDICTOR M ACTIVE MONITORING
AGENT RN

NormalfrontdooraccessviabustransacKon&I/F
sneakybackdooraccessviahdl_pathnobustransac9on
VolaKleeldsmodiedbynonbusRTLfunc9onality
modelupdatedusingacKvemonitoringviahdl_path
6
Verilab & Accellera 6
Ac9ve&PassiveOpera9on
REG MODEL ENV DUT
R1 SEQ
MEM VS C CPU F/W

1 R2... 2 3 R1
MEM
MAP RN
C BUS UVC
R2

R3

INTERFACE
...

VIF
ADAPTER S D
RX
...
VIF
PREDICTOR M
AGENT RN

Modelmusttolerateac9ve&passiveopera9ons:
1. acKvemodelread/writegeneratesitemsviaadapter
2. passivebehaviorwhenasequencedoesnotusemodel
3. passivebehaviorwhenembeddedCPUupdatesregister
7
Verilab & Accellera 7
RegisterAccessAPI
stimulus result
configure()
reset() REG MODEL
m_reset
randomize() m_mirrored
value
set() predict()

m_desired DUT RTL

write(),update(),poke() read(),mirror(),peek()

Usecasecanberegisteroreldcentric
constrainedrandoms9mulustypicallyregistercentric
e.g.reg.randomize();reg.update();
directedorhigherlevelscenariostypicallyeldcentric
e.g.object.randomize();eld.write(object.var.value);
8
Verilab & Accellera 8
RegisterFieldModeling
Fieldaccesspolicy modify on write modify on read
selfcontained REG
opera9onson
thisregistereld W FIELD R
field value field operation
FieldinteracKon
W SOURCE R
betweendierent
registerelds
W AFFECTED R
Registeraccessrightsinassociatedmemorymap
Modelfunc9onalbehaviorofDUTforvolaKleelds
9
Verilab & Accellera 9
FieldAccessPolicies
Comprehensivepredenedeldaccesspolicies
NO WRITE WRITE WRITE WRITE WRITE
WRITE VALUE CLEAR SET TOGGLE ONCE
NO
WO WOC WOS WO1
READ
WC WS
READ W1T
RO RW W1C W1S W1
VALUE W0T
W0C W0S
WSRC
READ Just defining access
RC WRC W1SRC
CLEAR
W0SRC policy is not enough!
WCRS
READ Must also
RS WRS W1CRS implement
SET
W0CRS special behavior!
Userdenedeldaccesspoliciescanbeadded
local static bit m = uvm_reg_field::define_access(UDAP);

if(!uvm_reg_field::define_access(UDAP)) `uvm_error(...)
10
Verilab & Accellera 10
Hooks&Callbacks
Fieldbaseclasshasemptyvirtualmethodhooks
implementinderivedeldtospecializebehavior
class my_reg_field extends uvm_reg_field; pre_write
virtual task post_write(item rw); post_write
// specific implementation pre_read
endtask post_read

Callbackbaseclasshasemptyvirtualmethods
implementinderivedcallback&registeritwitheld
class my_field_cb extends uvm_reg_cbs; pre_write
function new(string name, ...); post_write
virtual task post_write(item rw); callback
most important pre_read
// specific implementation post_read
for passive operation is
endtask post_predict
post_predict
encode
my_field_cb my_cb = new("my_cb", ...); decode
uvm_reg_field_cb::add(regX.fieldY, my_cb);
11
Verilab & Accellera 11
Hook&CallbackExecu9on
Fieldmethodhooksarealwaysexecuted
Callbackmethodsareonlyexecutedifregistered
task uvm_reg_field::do_write(item rw);
...
ACTUAL WRITE
rw.local_map.do_write(rw);
... HOOK METHOD
post_write(rw);
for (uvm_reg_cbs cb=cbs.first();
cb!=null;
CALLBACK METHOD
cb=cbs.next())
FOR ALL REGISTERED CBS
cb.post_write(rw);
...
endtask callbacks registered with field using add
multiple callbacks can be registered with field
callback methods executed in cbs queue order
12
Verilab & Accellera 12
MODELINGEXAMPLES

Verilab & Accellera 13


WritetoResetExample
set to reset value on write

W WRES R
Exampleuserdenedeldaccesspolicy
predenedaccesspoliciesforWritetoClear/Set(WC,WS)
userdenedpolicyrequiredforWritetoReset(WRES)
uvm_reg_field::define_access(WRES)
Demonstratethreepossiblesolu9ons:
post_writehookimplementa9oninderivedeld
post_writeimplementa9onincallback
post_predictimplementa9onincallback
14
Verilab & Accellera 14
WRESUsingpost_writeHook
class wres_field_t extends uvm_reg_field;
... DERIVED FIELD
virtual task post_write(uvm_reg_item rw);
if (!predict(rw.get_reset())) `uvm_error(..)
IMPLEMENT post_write TO
endtask
NOT PASSIVE SET MIRROR TO RESET VALUE

class wres_reg_t extends uvm_reg;


USE DERIVED FIELD
rand wres_field_t wres_field;
...
FIELD CREATED IN REG::BUILD
function void build();
// wres_field create()/configure(..WRES..)

class my_reg_block extends uvm_reg_block;


rand wres_reg_t wres_reg;
...
function void build(); REGISTER CREATED IN BLOCK::BUILD
// wres_reg create()/configure()/build()/add_map()

reg/block build() is not component build_phase()


15
Verilab & Accellera 15
WRESUsingpost_writeCallback
class wres_field_cb extends uvm_reg_cbs;
... DERIVED CALLBACK
virtual task post_write(uvm_reg_item rw);
if (!predict(rw.get_reset())) `uvm_error(..)
IMPLEMENT post_write TO
endtask
NOT PASSIVE SET MIRROR TO RESET VALUE

class wres_reg_t extends uvm_reg;


rand uvm_reg_field wres_field;
... USE BASE FIELD
function void build();
// wres_field create()/configure(..WRES..)

class my_reg_block extends uvm_reg_block;


CONSTRUCT CALLBACK
rand wres_reg_t wres_reg;
... REGISTER CALLBACK
function void build(); WITH REQUIRED FIELD
// wres_reg create()/configure()/build()/add_map()
wres_field_cb wres_cb = new("wres_cb");
uvm_reg_field_cb::add(wres_reg.wres_field, wres_cb);
16
Verilab & Accellera 16
WRESUsingpost_predictCallback
IMPLEMENT post_predict TO
class wres_field_cb extends uvm_reg_cbs;
SET MIRROR VALUE TO RESET STATE
...
virtual function void post_predict(..,fld,value,..);
if(kind==UVM_PREDICT_WRITE) value = fld.get_reset();
endfunction
PASSIVE OPERATION virtual function void post_predict(
class wres_reg_t extendsinput
uvm_reg; uvm_reg_field fld,
input uvm_reg_data_t previous,
rand uvm_reg_field wres_field;
... inout uvm_reg_data_t value,
function void build(); input uvm_predict_e kind,
input uvm_path_e
// wres_field create()/configure(..WRES..) path,
input uvm_reg_map map
);
class my_reg_block extends uvm_reg_block;
post_predict
rand wres_reg_t wres_reg;
is only if we use this callback
... available for fields with a register we get
not registers
function void build(); silent non-operation!
// wres_reg create()/configure()/build()/add_map()
wres_field_cb wres_cb = new("wres_cb");
uvm_reg_field_cb::add(wres_reg.wres_field, wres_cb);
17
Verilab & Accellera 17
Lock/ProtectExample
only allow write if lock is off

W PROTECTED R
W LOCK R
ExampleregistereldinteracKon
protectedeldbehaviorbasedonstateoflockeld,or
lockeldoperaKonmodiesbehaviorofprotectedeld
Demonstratetwopossiblesolu9ons:
post_predictimplementa9onincallback
dynamiceldaccesspolicycontrolledbycallback
(notbadpre_writeimplementa9onfromUVMUserGuide)
18
Verilab & Accellera 18
LockUsingpost_predictCallback
class prot_field_cb extends uvm_reg_cbs;
HANDLE TO
local uvm_reg_field lock_field; LOCK FIELD
function new (string name, uvm_reg_field lock);
super.new (name);
this.lock_field = lock;
endfunction
virtual function void post_predict(..previous,value);
if (kind == UVM_PREDICT_WRITE)
if (lock_field.get()) REVERT TO PREVIOUS
value = previous; VALUE IF LOCK ACTIVE
endfunction
CONNECT LOCK FIELD
class my_reg_block extends uvm_reg_block;
prot_field_cb prot_cb = new(prot_cb, lock_field);
uvm_reg_field_cb::add(prot_field, prot_cb);
REGISTER CALLBACK
WITH PROTECTED FIELD
19
Verilab & Accellera 19
LockUsingDynamicAccessPolicy
class lock_field_cb extends uvm_reg_cbs;
HANDLE TO
local uvm_reg_field prot_field; PROTECTED FIELD
function new (string name, uvm_reg_field prot);
super.new (name);
this.prot_field = prot;
endfunction
SET ACCESS POLICY FOR
virtual function void post_predict(...);
PROTECTED FIELD BASED ON
if (kind == UVM_PREDICT_WRITE) LOCK OPERATION
if (value)
void'(prot_field.set_access("RO"));
else prot_field.get_access()
void'(prot_field.set_access("RW"));
RETURNS CURRENT POLICY
endfunction
REGISTER CALLBACK
WITH LOCK FIELD CONNECT PROTECTED FIELD
class my_reg_block extends uvm_reg_block;
lock_field_cb lock_cb = new(lock_cb, prot_field);
uvm_reg_field_cb::add(lock_field, lock_cb);
20
Verilab & Accellera 20
BueredWriteExample
write to buffer read from current

W BUFFER

copy on write
to trigger
CURRENT R
TRIGGER
W R

ExampleregistereldinteracKon
triggereldoperaKoneectsbueredeldbehavior
Demonstratetwopossiblesolu9ons:
overlappedregisterimplementa9onwithcallback
derivedbuereldcontrolledbymul9plecallbacks

21
Verilab & Accellera 21
BueredWriteUsing2Registers
HANDLES TO BOTH
class trig_field_cb extends uvm_reg_cbs;
CURRENT & BUFFER FIELDS
local uvm_reg_field current, buffer;
function new (string name, uvm_reg_field current,
uvm_reg_field buffer);
... COPY FROM BUFFER TO CURRENT
virtual function void post_predict(...);
ON WRITE TO TRIGGER
if (kind == UVM_PREDICT_WRITE) begin
uvm_reg_data_t val = buffer.get_mirrored_value();
if (!current.predict(val)) `uvm_error(...)
RO & WO REGISTER AT SAME ADDRESS
all writes go to WO buffer
class my_reg_block extends uvm_reg_block;
all reads come from RO current
...
default_map.add_reg(cur_reg, 'h10, "RO");
default_map.add_reg(buf_reg, 'h10, "WO");
...
cannot share address again REGISTER CALLBACK WITH TRIGGER FIELD
trig_field_cb trig_cb
complicated to generate = new(
trig_cb,
confusing cur_reg.cur_field, buf_reg.buf_field);
map for user
uvm_reg_field_cb::add(trig_field, trig_cb);
22
Verilab & Accellera 22
BueredWriteUsingDerivedField
class buf_reg_field extends uvm_reg_field;
uvm_reg_data_t buffer; ADD BUFFER TO DERIVED FIELD
virtual function void reset(string kind);
super.reset(kind); RESET BUFFER TO FIELD RESET VALUE
buffer = get_reset(kind);
post_predict callback
class buf_field_cb extends uvm_reg_cbs;
required for passive
local buf_reg_field buf_field;
virtual function void post_predict(...); // if write
buf_field.buffer = value;SET BUFFER TO VALUE ON WRITE TO FIELD,
value = previous; SET MIRROR TO PREVIOUS (UNCHANGED)
class trig_field_cb extends uvm_reg_cbs;
local buf_reg_field buf_field; COPY BUFFER TO MIRROR
virtual function void post_predict(...);ON// if write
WRITE TO TRIGGER
buf_field.predict(buf_field.buffer);
REGISTER CALLBACKS WITH
buf_field_cb buf_cb = new(buf_cb,buf_field);
BUFFERED & TRIGGER FIELDS
uvm_reg_field_cb::add(buf_field, buf_cb);
trig_field_cb trig_cb = new(trig_cb,buf_field);
uvm_reg_field_cb::add(trig_field, trig_cb);
23
Verilab & Accellera 23
RegisterSideEectsExample
Randomizeormodifyregisters&recongureDUT
whataboutUVCconguraKon?
updatefromregistersequences not passive

snooponDUTbustransac9ons not backdoor


implementpost_predictcallback passive & backdoor

callback registered access UVC config


with model field via a handle
REG MODEL MY_UVC
side_effect_cb
C
R1
MEM
if(field.write(val))

VIF
R2
cfg.set_var(val);
S D
...
MAP M

VIF
RN
AGENT
ENV
24
Verilab & Accellera 24
CongUpdateUsingCallback
class reg_cfg_cb extends uvm_reg_cbs;
my_config cfg; HANDLE TO CONFIG OBJECT
function new (string name, my_config cfg);
super.new (name);
this.cfg = cfg;
endfunction SET CONFIG ON WRITE
virtual function void post_predict(...);TO REGISTER FIELD
(TRANSLATE IF REQUIRED)
if (kind == UVM_PREDICT_WRITE)
cfg.set_var(my_enum_t'(value));
endfunction
ENVIRONMENT HAS
class my_env extends uvm_env; UVC & REG_MODEL
...
uvc = my_uvc::type_id::create(...); CONNECT CONFIG
reg_model = my_reg_block::type_id::create(...);
... REGISTER CALLBACK
reg_cfg_cb cfg_cb = new(cfg_cb, uvc.cfg);
uvm_reg_field_cb::add(reg_model.reg.field, cfg_cb);
25
REGISTERMODELPERFORMANCE

Verilab & Accellera 26


Performance
Bigregistermodelshaveperformanceimpact
fullSoCcanhave>10kelds MANY REGISTER CLASSES
(MORE THAN REST OF ENV)
Registermodel&RTLtypicallyautogenerated
DIFFERENT USE-CASE
madetomeasureforeachdevicederiva9ve
THAN FACTORY

REGISTERDESCRIPTION ENV DUT CPU F/W


REG MODEL
(TEXT,XML,YAML,etc.) R1
MEM R1
R2
MEM
... R2
MAP RN R3
...
ADP PDT
RX
...
C UVC RN
GENERATOR TOOL/SCRIPTS
27
Verilab & Accellera 27
LifeWithoutTheFactory
ExampleSoCwith14k+eldsin7kregisters
manyregisterclasses(mosteldsarebasetype)
notusingfactoryoverridesgeneratedondemand
MODE FACTORY COMPILE LOAD BUILD DISK
TYPES TIME TIME TIME USAGE
NOREGISTERMODEL 598 23 9 1 280M
+REGISTERSUSINGFACTORY 8563 141 95 13 702M
+REGISTERSNOFACTORY 784 71 17 1 398M

COMPILE TIME x2 LOAD + BUILD TIME x5


+1 min infrequently +1.5 min for every sim
Registermodels9llworkswithoutthefactory
donotuseuvm_object_u8lsmacroforelds&registers
constructregistersusingnewinsteadoftype_id::create
28
Verilab & Accellera 28
`uvm_object_u9ls
`define uvm_object_utils(T) \
`m_uvm_object_registry_internal(T,T) \
breakintothemainmacrosasaddi9onalanima9on
`m_uvm_object_create_func(T)
class my_reg extends uvm_reg;\
`m_uvm_get_type_name_func(T)
`uvm_object_utils(my_reg) \
...
endclass
`define m_uvm_object_registry_internal(T,S) \
typedef
class uvm_object_registry#(T,`"S`")
my_reg extends uvm_reg; type_id; \
static
typedef function type_id get_type();
uvm_object_registry ...\
#(my_reg,"my_reg") type_id;
virtual function uvm_obj*
static function get_object_type(); ...\
type_id get_type();
`definereturn type_id::get();
m_uvm_object_create_func(T) \ explains what my_reg::type_id is
endfunction
function uvm_object create (string name=""); ...\
declare a
virtual typedef specialization
function uvm_object_wrapper get_object_type();
`define m_uvm_get_type_name_func(T) \
of uvm_object_registry
return
const static class
type_id::get();
string type_name = `"T`"; \
endfunction but what about factory registration
virtual function string get_type_name (); ...\
function uvm_object create (string name=""); and type_id::create ???
const static string type_name = "my_reg";
virtual function string get_type_name ();
return type_name;
endfunction
declare some methods
endclass
for factory API
Verilab & Accellera 29
29
uvm_object_registry
class uvm_object_registry proxy type
#(type T, string Tname) extends uvm_object_wrapper;
lightweight substitute for real object
typedef uvm_object_registry #(T,Tname) this_type;
local static this_type me = get(); local static proxy variable calls get()
static function this_type get();
if (me == null) begin construct instance of proxy, not real class
uvm_factory f = uvm_factory::get();
me = new;
f.register(me); register proxy with factory
end
return me;
registration is via static initialization
endfunction => happens at simulation load time
function
virtual void
function uvm_factory::register
uvm_object create_object (uvm_object_wrapper
(...); obj);
...
static function T create (...);
// add to
static function voidassociative arrays
set_type_override (type, replace);
m_type_names[obj.get_type_name()]
static function void set_inst_override (type, = obj;inst, parent);
m_types[obj] = 1;
endclass
thousands
... of registers means thousands of proxy classes
are constructed and added to factory when files loaded
endfunction
do not need these classes for register generator use-case!
30
type_id::create
reg= my_reg::type_id::create(reg,,get_full_name());

uvm_object_registry #(my_reg,"my_reg") static create function

class uvm_object_registry #(T, Tname) extends uvm_object_wrapper;


...
static function T create(name,parent,contxt="");
uvm_object obj; request factory create based on existing type overrides (if any)
uvm_factory f = uvm_factory::get();
obj = f.create_object_by_type(get(),contxt,name,parent);
if (!$cast(create, obj)) uvm_report_fatal(...);
return handle to object
endfunction
virtual function uvm_object create_object (name,parent);
T obj;
search queues for overrides
obj = new(name, parent);
return obj;
function
constructs uvm_object
actual object uvm_factory::create_object_by_type
endfunction
(type,contxt,name,parent);
...
requested_type
create and factory =search
find_override_by_type(requested_type,
takes time for thousands of registers path);
endclass
return requested_type.create_object(name, parent);
during the pre-run phase for the environment (build time)
endfunction
no need to search for overrides for register
call create_object generator
for proxy use-case!
of override type
31
Conclusions
Theresmorethanonewaytoskinareg...
butsomearebe(erthanothers!
consider:passiveopera9on,backdooraccess,usecases,...
FullchipSoCregistermodelperformanceimpact
forgeneratedmodelswecanavoidusingthefactory
Allsolu9onsevaluatedinUVM1.1d&OVM2.1.2
updateduvm_reg_pkgthatincludesUVM1.1dbugxes
(availablefromwww.verilab.com)

32
Verilab & Accellera 32
Ques9ons

Accellera Systems Initiative 33