UVM has an internal database table in which we can store values under a given name and can be retrieved later by some other testbench component. The uvm_config_db
class provides a convenience interface on top of the uvm_resource_db
to simplify the basic interface used for uvm_component instances. Note that all the functions are static and must be called using the ::
scope operator.
Such a configuration database allows us to store different configuration settings under different names that could potentially configure testbench components when required without modifying the actual testbench code. For example, to turn on functional coverage for an agent, we would simply have to give the path to that agent and set a variable within the configuration database to value 1. The agent could check for the value under this variable and start collecting coverage if it is turned on.

set()
static function void set ( uvm_component cntxt,
string inst_name,
string field_name,
T value);
Use this static function of the class uvm_config_db
to set a variable in the configuration database. In the example below, set()
function will set a variable of name cov_enable at the path uvm_test_top.m_env.m_apb_agent with value 1.
virtual function void build_phase (uvm_phase phase);
...
uvm_config_db #(int) :: set (null, "uvm_test_top.m_env.m_apb_agent", "cov_enable", 1);
...
endfunction
Use of set()
will create a new or update an existing configuration setting for field_name in inst_name from cntxt. The setting is made at cntxt with the full scope of the set being {cntxt, ".", inst_name}
. If cntxt is null, then the complete scope of getting the information will be provided by inst_name.
// Set virtual interface handle under name "apb_vif" available to all components below uvm_test_top, indicated by the *
uvm_config_db #(virtual apb_if) :: set (null, "uvm_test_top.*", "apb_vif", apb_if);
// Set an int variable to turn on coverage collection for all components under m_apb_agent
uvm_config_db #(int) :: set (null, "uvm_test_top.m_env.m_apb_agent.*", "cov_enable", 1);
// Consider you are in agent's build_phase then you may achieve the same effect by
uvm_config_db #(int) :: set (this, "*", "cov_enable", 1);
Note that in the last example the cntxt is this
, and will be substituted by the path to the current component which in this case is "uvm_test_top.m_env.m_apb_agent". As explained above the full scope becomes "uvm_test_top.m_env.m_apb_agent.*"

get()
static function bit get ( uvm_component cntxt,
string inst_name,
string field_name,
inout T value);
Use this static function to get the value of variable given in field_name from the configuration database. Remember that the value will be returned only if the scope is true. For example, if you had set
a variable by field_name m_cfg at scope "uvm_test_top.m_env.m_func_cov", then you have to give the same scope or a scope that is true for the expression, to retrieve the value under field_name. cntxt is the starting search concatenated with inst_name gives the entire scope.
// Get virtual interface handle under name "apb_vif" into local virtual interface handle at m_env level uvm_config_db #(virtual apb_if) :: get (this, "*", "apb_vif", apb_if); // Get int variable fails because no int variable found in given scope uvm_config_db #(int) :: get (null, "uvm_test_top", "cov_enable", cov_var);
exists()
static function bit exists ( uvm_component cntxt,
string inst_name,
string field_name,
bit spell_chk);
Checks if a value for field_name is available in inst_name, using component cntxt as the starting point. If the field_name does not exist at a given scope, the function will return a zero. The spell_chk arg can be set to 1 to turn spell checking on if it is expected that the field should exist in the database.
// Check if interface handle exists at the given scope
if (! uvm_config_db #(virtual apb_if) :: exists (this, "*", "apb_vif"))
`uvm_error ("VIF", "Could not find an interface handle", UVM_MEDIUM)
wait_modified()
static task wait_modified ( uvm_component cntxt,
string inst_name,
string field_name);
Use of this task will block execution of statements following this until the configuration setting named in field_name specified at scope {cntxt.inst_name} is changed.
class my_agent extends uvm_agent;
virtual task run_phase (uvm_phase phase);
...
// Waits until loopCount variable gets a new value
uvm_config_db #(int) :: wait_modified (this, "", "loopCount");
endtask
endclass
class my_env extends uvm_env;
my_agent m_apb_agent;
virtual task main_phase (uvm_phase phase);
...
// Update loopCount variable in database
for (int i = 0; i < N; i++) begin
...
uvm_config_db #(int) :: set (this, "m_apb_agent", "loopCount", i);
end
endtask
endclass
Convenience tasks
There are a few typedef
aliases for the following parameterized versions of uvm_config_db
.
typedef uvm_config_db #(uvm_bitstream_t) uvm_config_int;
typedef uvm_config_db #(string) uvm_config_string;
typedef uvm_config_db #(uvm_object) uvm_config_object;
typedef uvm_config_db #(uvm_object_wrappet) uvm_config_wrapper;