Understanding the Factory and Configuration
Contents are extracted from the Advanced UVM sessions by Verification Academy.
2 customization mechanism
Factory
- Allows test to change the type of a desired component or object
- Typically set up at start of simulation
Configuration
- Allows parents to define properties for children
- Static (build-time) - Highest parent “wins”
- Dynamic (run-time) - Last set ”wins”
- All UVM components get their own configuration
- Optionally use to configure their children
Factory
create()
vs new()
Registering with Factory
Objects are registered with the factory via macros
`uvm_object_utils(<type>)
`uvm_component_utils(<type>)
The macro utils will create a wrapper type that registering in the factory to allow accessing it from the factory via the create()
method
type_id::set_type_override(<type>);
is a static methods in the wrapper
Test now have the ability to override the type of component that returned from the factory
get_type()
returns the type "handle"
set_inst_override(<type>, "<instance>");
can also be used in addition to set_type_override
for overriding instance
Overriding a type
When doing
type_override
in the factory, the last change will be reflected
set_inst_override
take precedence overset_type_override
→ Will be the case regards of the order in which
set_type_override
andset_inst_override
is executed⇒ The U2 in the example will always be a triangle
Using parameterized types
Tests are components, too!
run_test() creates the test from the factory
The test type instantiation will be determined using the command line plusargs +UVM_TESTNAME
Always call run_test()
with null argument
run_test()
can be called with an argument to specify a default test to be run when there is no test name specified when running the simulation⇒ Recommended to call
run_test()
with null argument
Use the factory for objects
Configuration database
Explicitly typed
Tied to the hierarchical scopes
The value of the component on the highest of the hierarchy will be used
The build_phase
happens top-down, so when setting the value of driver’s x, the driver isn’t instantiate yet ⇒ Using configuration database will allow this to be done
Allow reusability since the test only care about setting up the value on the environment
uvm_config_db
Uses a set()
/get()
API
- No casting on
get()
- Linked to component hierarchy
uvm_config_db #(<type>)::set(this, "<inst>", "<field>", value);
uvm_config_db #(<type>)::get(this, "<inst>", "<field>", value);
On the set
:
this
: the component making the call
<inst>
: Is the name of component we wanna set relative to the component doing theset
On the get
:
The
<inst>
is usually set to null since thethis
already content the full path to the component
If field name is the same, we get the value from the database and return it
UVM Features
Passing virtual interface handle from the top level module to the test
Call the
uvm_config_db::set
to pass down theenv_cfg
objectInstance name supports pattern matching glob-style or regex
In the example, all instance looking for the object with the field name
config
of typeenv_config
will be able to do so
⇒ uvm_config_db
can affect the performance
Summary
Use uvm_object/component_utils
macro to register with factory
Always call <type>::type_id::create()
Register tests with the factory
Call run_test()
with null argument
- Specify which test via the command line
Use config DB at build-time
- Components get their config before configuring children
- Highest set wins
Use config DB at run-time
- Last set wins
- Up to the “getter” to decide when it’s legal