Last Updated: July 24, 2016
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_configs. 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.

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 ) ); |
The diagram below shows what will be created after these set functions have been called.

- Since the
topis a module, not auvm_component,nullis passed as thecntxtwhensetis called. In this case,uvm_top, which is the singleton object ofuvm_rootclass, will be used as thecntxt. - An entry of an associative array (
m_rsc) is created using thecntxtobject 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_nameand thefield_nameas the key (lookup). Note that theinst_nameand thefield_nameare concatenated with a string (“__M_UVM__“) when thelookupis created. - If the
lookupdoes not exist, auvm_resourceobject is created. If theinst_nameis"", the full name of thecntxt, which is"uvm_test_top", is stored as thescope. Thevaluepassed to theset()function is also stored. - The handle to the
uvm_resourceobject is stored in two kinds ofuvm_queues. The first kind of queues store the handles to theuvm_resourceobjects that have the commonfield_name. Auvm_queueis created for every uniquefield_name. In our case, twouvm_queues 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_resourceobjects that have the common type. Auvm_queueis created for every unique type. In our case, oneuvm_queueis created for thevirtual jelly_bean_iftype. - The queues are registered in the singleton
uvm_resource_pool. Theuvm_resouce_poolhas two associative arrays. One array (rtab) uses thefield_nameas the key. - The other array (
ttab) uses the type of theuvm_resourceas the key.
Getting a Virtual Interface
In Configurations, the jelly_bean_base_test retrieved the jelly_bean_ifs 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 ) ); |
The diagram below shows how the jb_if1 is retrieved.

- Look up the name table of the
uvm_resource_poolwith thefield_nameas 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_resourceis stored in a newly createduvm_queue. - The
uvm_resourcewith 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.

- The
jelly_bean_envcalls theset()function withthis(jb_env) as thecntxt. - An entry of an associative array (
m_rsc) is created using thecntxtobject 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_nameand thefield_nameas the key (lookup). Note that theinst_nameand thefield_nameare concatenated with a string (“__M_UVM__“) when thelookupis created. - If the
lookupdoes not exist, auvm_resourceobject is created. Unlike the virtual-interface case, theinst_nameis not""this time. In this case, the full name of thecntxtobject concatenated with theinst_nameis stored as thescope. Thevaluepassed to theset()function is also stored. - The handle to the
uvm_resourceobject is stored in two kinds ofuvm_queues. The first kind of queues store the handles to theuvm_resourceobjects that have the commonfield_name. Auvm_queueis created for every uniquefield_name. In our case, oneuvm_queueis created for the"jb_agent_cfg". - The second kind of queues store the handles to the
uvm_resourceobjects that have the common type. Auvm_queueis created for every unique type. In our case, oneuvm_queueis created for thejelly_bean_agent_configtype. - The queues are registered in the singleton
uvm_resource_pool. Theuvm_resouce_poolhas two associative arrays. One array (rtab) uses thefield_nameas the key. - The other array (
ttab) uses the type of theuvm_resourceas 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.

- Look up the name table of the
uvm_resource_poolwith thefield_nameas 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_resourceis stored in a newly createduvm_queue. Note that there are twouvm_resourceobjects, but their scopes are different. The full name of thecntxtobject passed to theget()function distinguishes between the two. - The
uvm_resourcewith 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.

Its great article to learn uvm_config_db in detail
Hi Keisuke,
What is the diference between uvm_config_db and uvm_resource_db?
How to choose between these two?
Regards,
Siva
Both the
uvm_config_dband theuvm_resource_dbprovide a convenience interface for the resource database. UVM recommends using theuvm_config_dbas it is more robust.As it is correctly said by “Keisuke Shimizu”, Both the uvm_config_db and the uvm_resource_db provide a convenience interface for the resource database. UVM recommends using the uvm_config_db as it is more robust.
uvm_config_db is more robust because with uvm_config_db, we can restrict the db so that it will not be visible to certain components. In other words, while setting up the config_db, we can set a path. So, that this db can be accessed only by the components that are existing in the specified path… But, uvm_resource_db has no such facility (since this db can be accessed by any of the components inTB) uvm_resource_db has global visibility.
It is user’s responsibility to set correct scope when you call
uvm_resource_db#(T)::set( input string scope, input string name, T val, input uvm_object accessor = null )as thescopecan be any string. On the other hand, when you calluvm_config_db#(T)::set( uvm_component cntxt, string inst_name, string field_name, T value ), you give auvm_componentfor the scope (or context,cntxt), which is less error-prone.Hi Keisuke,
How is uvm_config_db diffrent from set_inst_override or set_type_override, In which context should we use each of them. Can you please explain, Thanks in advance !!
The
uvm_config_dbis used to share information between components and objects. For example, the top-level test-bench module often stores a virtual interface to theuvm_config_db. Then auvm_drivercan get the interface from the database for pin wiggling. Please see this and this for how we did it.The
set_inst_overrideandset_type_overrideare used to substitute a component or an object for another without changing the test-bench code. For example, a user can substitute a transaction for an error transaction. Please see this for how we substituted a jelly bean with a sugar-free jelly bean from a test.Hi
The article is a bit too sophisticated, it explains more about behind the scenes, then about the actual way of using it, as you did in the previous articles. Can you please add some more examples for each field in the set/get of the config_db.
Thanks
This sequel post might help you.
Please ignore my earlier reply, I continued on and saw you elaborated on the issue in another chapter.
Thanks again
great article
Hi Keisuke,
Thanks for the very nice explanation on config db. No I know how to appropriately give the .cntxt, .instname, arguments.
I have a question. I see the configuration object retrieval is only concerned with the associative array in uvm_resource_pool and the handles to uvm_queue they point to. I wanted to know why initially an entry is made in “m_rsc” table and a “uvm_pool” is created with another associative array? Why not start by creating uvm_resource objects for the item and get their handle in uvm_queue and make an entry in the arrays in uvm_resource_pool singleton? What benefit is gained from extra book keeping done initially?
Regards,
Gautam
This is a good question. I don’t know why.
Very good article.
Hi Keisuke,
From where do I read about the internal working of things like you have explained about internal working of a configuration database? What materials do I refer to?
Regards,
Gautam
I read the source code of UVM. Good luck!
Hi shimizu
I want get data from test to testbench is it possible to get by using config db get in test bench
Regards
Ch.siva
You should be able to do like this:
Hi Keisuke,
I have a question regarding to input a name in a interface.
I have a interface like below:
then in my testbench top level, I have declare a instance like below:
general_bfm i_general_bfm("i_general_bfm",clk, resetn);However, it compiles with NCSIM successfully. But when I tried to compile with VCS, it gave me error:
I am not sure what the error exactly means? Can you please help me on that?
many thanks
Steve
It seems you cannot use
stringas the interface port type. You could either define thenameas an interface item like this:or use a parameterized interface:
Hi
We have uvm_pool class which is helpful for seting and getting objects, but why still we need config_db ? we can achieve same thing in uvm_pool also but why do we go for uvm_config_db?
You could use
uvm_poolif simple lookup ofuvm_objectis good enough. However, if you want scope resolution for example,uvm_resourceneeds to be involved. Look at the diagram in Summary section and see how many objects are involved to resolve the scope. Theuvm_config_dbprovides simple API for this.hi
below code iam using config db set and get
uvm_config_db#( apb_reg_block)::set(this,"*","RAL",ral); uvm_config_db#(apb_reg_block)::get(this," ","RAL",ral);but in this line error is pointing like this
can u plz help me out
If
apb_reg_seqcalls theget(), you cannot usethisas the first argument becauseapb_reg_seqis not auvm_component. Try to usem_sequencerinstead ofthis.