This post will explain how configuration database (uvm_config_db
) works. In Configurations, we used the uvm_config_db
to store a jelly_bean_if
, a jelly_bean_env_config
, and two jelly_bean_agent_config
s. This post will analyze how a configuration data is stored and retrieved. The class diagram related to the configuration database is shown below. Note that we only showed the classes related to the jelly_bean_if
and jelly_bean_agent_config
to avoid clutter. UVM standard library classes are shown in pink, while the UVM classes specialized with the jelly_bean_transaction
type are shown in yellow.
Class Diagram Related to the Configuration Database
Setting a Virtual Interface
In Configurations, the top
module stored two virtual interfaces (jb_if1
and jb_if2
) into the configuration database as follows:
uvm_config_db#( virtual jelly_bean_if )::set( .cntxt ( null ),
.inst_name ( "" ),
.field_name( "jb_if1" ),
.value ( jb_if1 ) );
uvm_config_db#( virtual jelly_bean_if )::set( .cntxt ( null ),
.inst_name ( "" ),
.field_name( "jb_if2" ),
.value ( jb_if2 ) );
Storing the Virtual Interfaces
These are the steps involved in this course of action.
- Since the
top
is a module, not auvm_component
,null
is passed as thecntxt
whenset
is called. In this case,uvm_top
, which is the singleton object ofuvm_root
class, will be used as thecntxt
. - An entry of an associative array (
m_rsc
) is created using thecntxt
object as the key, if this entry does not exist. - The entry of the associative array points to a
uvm_pool
, which has another associative array (pool
). - An entry of the associative array is created using the
inst_name
and thefield_name
as the key (lookup
). Note that theinst_name
and thefield_name
are concatenated with a string (“__M_UVM__
“) when thelookup
is created. - If the
lookup
does not exist, auvm_resource
object is created. If theinst_name
is""
, the full name of thecntxt
, which is"uvm_test_top"
, is stored as thescope
. Thevalue
passed to theset()
function is also stored. - The handle to the
uvm_resource
object is stored in two kinds ofuvm_queue
s. The first kind of queues store the handles to theuvm_resource
objects that have the commonfield_name
. Auvm_queue
is created for every uniquefield_name
. In our case, twouvm_queue
s are created; one for the"jb_if1"
and the other for the"jb_if2"
. - The second kind of queues store the handles to the
uvm_resource
objects that have the common type. Auvm_queue
is created for every unique type. In our case, oneuvm_queue
is created for thevirtual jelly_bean_if
type. - The queues are registered in the singleton
uvm_resource_pool
. Theuvm_resouce_pool
has two associative arrays. One array (rtab
) uses thefield_name
as the key. - The other array (
ttab
) uses the type of theuvm_resource
as the key.
Getting a Virtual Interface
In Configurations, the jelly_bean_base_test
retrieved the jelly_bean_if
s as follows:
uvm_config_db#( virtual jelly_bean_if )::get( .cntxt ( this ),
.inst_name ( "" ),
.field_name( "jb_if1" ),
.value( jb_agent_cfg1.jb_if ) );
uvm_config_db#( virtual jelly_bean_if )::get( .cntxt ( this ),
.inst_name ( "" ),
.field_name( "jb_if2" ),
.value( jb_agent_cfg2.jb_if ) );
Retrieving the Virtual Interface
These are the steps involved in this course of action.
- Look up the name table of the
uvm_resource_pool
with thefield_name
as the key. - If the name matched, get the handle of the
uvm_queue
. - Traverse the entries of the queue.
- If the scope and the type of the object matches, that
uvm_resource
is stored in a newly createduvm_queue
. - The
uvm_resource
with the highest precedence is retrieved. - The value of the resource is returned.
Setting an Agent Configuration
Now let’s look at another example. In Configurations, the jelly_bean_env
stored the jelly-bean-agent configurations (jb_agent_cfg1
and jb_agent_cfg2
) as follows:
uvm_config_db#( jelly_bean_agent_config )::set( .cntxt ( this ),
.inst_name ( "jb_agent1*" ),
.field_name( "jb_agent_cfg" ),
.value( jb_env_cfg.jb_agent_cfg1 ) );
uvm_config_db#( jelly_bean_agent_config )::set( .cntxt ( this ),
.inst_name ( "jb_agent2*" ),
.field_name( "jb_agent_cfg" ),
.value( jb_env_cfg.jb_agent_cfg2 ) );
The diagram below shows what will be created after these set
functions have been called.
Storing the Agent Configurations
These are the steps involved in this course of action.
- The
jelly_bean_env
calls theset()
function withthis
(jb_env
) as thecntxt
. - An entry of an associative array (
m_rsc
) is created using thecntxt
object as the key, if this entry does not exist. - The entry of the associative array points to a
uvm_pool
, which has another associative array (pool
). - An entry of the associative array is created using the
inst_name
and thefield_name
as the key (lookup
). Note that theinst_name
and thefield_name
are concatenated with a string (“__M_UVM__
“) when thelookup
is created. - If the
lookup
does not exist, auvm_resource
object is created. Unlike the virtual-interface case, theinst_name
is not""
this time. In this case, the full name of thecntxt
object concatenated with theinst_name
is stored as thescope
. Thevalue
passed to theset()
function is also stored. - The handle to the
uvm_resource
object is stored in two kinds ofuvm_queue
s. The first kind of queues store the handles to theuvm_resource
objects that have the commonfield_name
. Auvm_queue
is created for every uniquefield_name
. In our case, oneuvm_queue
is created for the"jb_agent_cfg"
. - The second kind of queues store the handles to the
uvm_resource
objects that have the common type. Auvm_queue
is created for every unique type. In our case, oneuvm_queue
is created for thejelly_bean_agent_config
type. - The queues are registered in the singleton
uvm_resource_pool
. Theuvm_resouce_pool
has two associative arrays. One array (rtab
) uses thefield_name
as the key. - The other array (
ttab
) uses the type of theuvm_resource
as the key.
One difference from the previous example is that the rtab
has only one entry because both the uvm_agent_cfg1
and the uvm_agent_cfg2
use the same field_name
("uvm_agent_cfg"
).
Getting an Agent Configuration
In Configurations, the jelly_bean_agent
retrieved the jb_agent_cfg
as follows:
uvm_config_db#( jelly_bean_agent_config )::get( .cntxt ( this ),
.inst_name ( "" ),
.field_name( "jb_agent_cfg" ),
.value ( jb_agent_cfg ) );
The diagram below shows how the jb_agent_cfg
is retrieved.
Retrieving the Agent Configuration
These are the steps involved in this course of action.
- Look up the name table of the
uvm_resource_pool
with thefield_name
as the key. - If the name matched, get the handle of the
uvm_queue
. - Traverse the entries of the queue.
- If the scope and the type of the object matches, that
uvm_resource
is stored in a newly createduvm_queue
. Note that there are twouvm_resource
objects, but their scopes are different. The full name of thecntxt
object passed to theget()
function distinguishes between the two. - The
uvm_resource
with the highest precedence is retrieved. - The value of the resource is returned.
Summary
That’s about the configuration database. This diagram shows the main objects involved in this article. I hope this post helped you to understand how the configuration database works.
UVM Objects Involved in This Article