# UVM Tutorial for Candy Lovers – 18. Configuration Database Revisited

In the post, Configurations, we looked at the configuration flow of the jelly bean verification. We also looked at the behind the scenes of the configuration flow in the post, Configuration Database. This post will focus on the syntax and semantics of accessing the configuration database. In Configurations, we stored and retrieved the jelly_bean_ifjelly_bean_env_config, and jelly_bean_agent_config using the configuration database. The following figure depicts the component hierarchy used in Configurations on the left, and the configuration database (shown as clouds) on the right. The code snippets to access the database are shown in the middle.

Accessing Configuration Database

## Storing the jelly_bean_env_config

Let’s look at how to store and retrieve the jb_env_cfg (shown in gray in the figure) first as this might be the easiest to understand. The jelly_bean_base_test called set() function to store the jb_env_cfg in the database as follows.

uvm_config_db#( jelly_bean_env_config )::set( .cntxt( this ), .inst_name( "*" ),
.field_name( "jb_env_cfg" ), .value( jb_env_cfg ) )

The uvm_config_db is a parameterized class. In the above code, the uvm_config_db is specialized with the jelly_bean_env_config type. The cntxt (context) and inst_name (instance name) are used to create a scope in the database. The scope is created by concatenating the full name of the context and the instance name ({ cntxt.get_full_name(), ".", inst_name }). In the above example, the scope is { this.get_full_name(), ".", "*" }, which is evaluated to "uvm_test_top.*". Note that the full name of the jelly_bean_base_test is assigned to be "uvm_test_top" when the run_test() task is called in the top-level module (top). Note also that the "*" is a wildcard character that matches any components. The object handle of jb_env_cfg is stored under the name of "jb_env_cfg". The picture below conceptually shows how the jb_env_cfg is tagged in the database.

The jb_env_cfg Stored in the Configuration Database

## Retrieving the jelly_bean_env_config

The jb_env called get() function to retrieve the jb_env_cfg from the database as follows.

uvm_config_db#( jelly_bean_env_config )::get( .cntxt( this ), .inst_name( "" ),
.field_name( "jb_env_cfg" ), .value( jb_env_cfg ) )

The meanings of the arguments of the get() function are the same as those of the set() function. Similar to the set() function, the scope is defined as { cntxt.get_full_name(), ".", inst_name }. In the above code, the scope is evaluated to "uvm_test_top.jb_env". It is typical to use this as the cntxt and "" as the inst_name. Note that if the inst_name is empty (""), the dot (".") is also omitted. The get() function searches the database and tries to find the object that matches the type, scope, and field_name. Since the scope of the jb_env_cfg was defined as "uvm_test_top.*" in the database, the scope, "uvm_test_top.jb_env", successfully matches it.

## Storing the jelly_bean_agent_config

Now let’s look at another example. This time, the jb_env stores the jb_agent_cfg, then the jb_agent1 retrieves it (shown in orange in the figure on the top). The jb_env called set() function to store the jb_agent_cfg in the database 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 ) )

The uvm_config_db is specialized with the jelly_bean_agent_config type. The scope of the object is { this.get_full_name(), ".", "jb_agent1*" }, which is evaluated to "uvm_test_top.jb_env.jb_agent1*". Note that this scope matches jb_agent1 and any components under it. The jb_env_cfg.jb_agent_cfg1 is stored under the name of "jb_agent_cfg". The picture below conceptually shows how the jb_agent_cfg1 is tagged in the database.

The jb_agent_cfg1 Stored in the Configuration Database

## Retrieving the jelly_bean_agent_config

The jb_agent1 called get() function to retrieve the jb_agent_cfg1 as follows.

uvm_config_db#( jelly_bean_agent_config )::get( .cntxt( this ), .inst_name( "" ),
.field_name( "jb_agent_cfg" ), .value( jb_agent_cfg ) )

The scope is { this.get_full_name(), ".", "" }, which is evaluated to "uvm_test_top.jb_env.jb_agent1". Since the scope of the jb_agent_cfg1 in the database is "uvm_test_top.jb_env.jb_agent1*", it successfully matches the scope defined by this get() function.

## Storing the jelly_bean_if

Let’s look at the last example. The top-level module stores a virtual interface (shown in yellow in the figure on the top). The top module called set() function as follows.

uvm_config_db#( virtual jelly_bean_if )::set( .cntxt( null ), .inst_name( "uvm_test_top" ),
.field_name( "jb_if1" ), .value( jb_if1 ) )

Two things to note here. The first is that we used null as the cntxt. This was because the top-level module is not a uvm_component and cannot obtain its full name by calling the get_full_name(). The second is that we used "uvm_test_top" as the inst_name. As we have seen, the "uvm_test_top" is the full name of the top-level test component. Thus, it is important to use this name as a part of the scope.
If the cntxt is null, the scope consists of the inst_name only, which is "uvm_test_top". The picture below conceptually shows how the jb_if1 is tagged in the database.

The jb_if1 Stored in the Configuration Database

## Retrieving the jelly_bean_if

The jelly_bean_base_test called get() function to retrieve the jb_if1 as follows.

uvm_config_db#( virtual jelly_bean_if )::get( .cntxt( this ), .inst_name( "" ),
.field_name( "jb_if1" ), .value( jb_agent_cfg1.jb_if ) )

The scope is { this.get_full_name(), ".", "" }, which is evaluated to "uvm_test_top" ("." is not included if the inst_name is ""). Since the scope of the jb_if1 in the database is "uvm_test_top", it successfully matches the scope defined by this get() function.

## Summary of the scopes

The table below summarizes which component matches the scopes defined in our example assuming get() function uses this as the cntxt and "" as the inst_name. Note that the scope "uvm_test_top.*" matches any components under the uvm_test_top, but it does not match the scope "uvm_test_top" (1). On the other hand, the scope "uvm_test_top" matches "uvm_test_top" only. It does not match any components under the uvm_test_top (2).

 Component/Scope uvm_test_top.* uvm_test_top.jb_env.jb_agent1* uvm_test_top jelly_bean_base_test (uvm_test_top) (1) (2) uvm_test_top.jb_env uvm_test_top.jb_env.jb_agent1 uvm_test_top.jb_env.jb_agent2