What is uvm_config_db and how to use it

4.7/5 - (14 votes)

uvm_config_db provides infrastructure to share configuration and other parameters between two or more testbench components or objects and it is the recommended way to access the resource database in UVM. uvm_config_db::set is used to put the information into the database uvm_config_db::get is used to retrieve the information from the database. This database can be populated and accessed using strings. Advantage to used uvm_config_db is that the testbench components can get access to the information without knowing where it exists in the hierarchy. This makes easy to create robust and reusable hierarchical verification environment.

uvm_config_db

Example:- testcase can set ‘mode’ variable of type bit using uvm_config_db::set and monitor can get the same value through uvm_config_db::get. See the sample code at the end of this post.

uvm_config_db

Table of Contents

Methods
set()

Create a new or update an existing configuration setting for field_name in inst_name from cntxt.

get()

Get the value for field_name in inst_name, using component cntxt as the starting search point.

exists()

Check if a value for field_name is available in inst_name, using component cntxt as the starting search point.

wait_modified()

Wait for a configuration setting to be set for field_name in cntxt and inst_name.

All the functions in uvm_config_db#(T) are static, so they must be called using the :: operator.

cntxt: is the hierarchical starting point for accessible database entry.

inst_name : is the hierarchical path that limits database entry accessibility.

field_name : is the tag or label that is used as a lookup for the database entry.

uvm_config_db

uvm_config_db

Different Scenarios
  1. Set to multiple objects
  2. Set to one object

In the above TB structure(check sample code at the end of this post) we will use set/get to explore above scenarios using metacharacters *, + and ?.

In the example TB there two agents, each contains monitor. Hierarchical paths to these monitors are

uvm_test_top.env.agent1.mon

uvm_test_top.env.agent2.mon

Scenario #1 – Set to multiple objects

from testcase set mode=1 and get it in both the monitors

set(uvm_component cntxt, string inst_name, string field_name, T value);

cntx + inst_name -> storage location or address of the object handle(field_name)

There are multiple ways to set hierarchical paths for monitors, few examples are

uvm_config_db

Scenario #2 – Set to one object

from testcase set mode=1 only for monitor1.

uvm_config_db

uvm _ config _ db supports metacharacters *, + and ? to write regular expressions and reference the same object in multiple ways.

* : 0 or more characters

+ : 1 or more characters

? : Exactly 1 character

Precedence Rules

Rule#1 – during the build phase a set() call in a context higher up the component hierarchy takes precedence over a set() call occurring lower down the hierarchy.

Rule#2 – in case of identical contexts or after the build phase, the last set() call takes precedence over the earlier one.

config_db Debug

If the run-time +UVM_CONFIG_DB_TRACE command line option is specified, all configuration DB accesses (read and write) are displayed.

In testcase: uvm_config_db #(bit)::set(uvm_root::get(), “*ag*mon*”, “MODE”, 1);

In uvm_test_top.env.agent*.mon: uvm_config_db #(bit)::get(this, “*”, “MODE”, mode)

Output will have config db set/get prints

uvm_resource_db.svh(121) @ 0: reporter [CFGDB/SET] Configuration ‘*ag*mon*.MODE’ (type bit) set by = (bit) 1

uvm_resource_db.svh(121) @ 0: reporter [CFGDB/GET] Configuration ‘uvm_test_top.env.agent1.mon.*.MODE’ (type bit) read by uvm_test_top.env.agent1.mon = (bit) 1

uvm_resource_db.svh(121) @ 0: reporter [CFGDB/GET] Configuration ‘uvm_test_top.env.agent2.mon.*.MODE’ (type bit) read by uvm_test_top.env.agent2.mon = (bit) 1

Print full state of the uvm_config_db

Use :- uvm_config_db #(int)::dump();

function void end_of_elaboration_phase(uvm_phase phase);
    super.end_of_elaboration_phase(phase);
    uvm_top.print_topology();
     uvm_config_db #(int)::dump();
endfunction

Simulation Output will have something like this:

=== resource pool ===
MODE [/^.*ag.*mon.*$/] : (bit) 1

Sample Code
line 11 – get()
line 67 – set()
example link
				
					`include "uvm_macros.svh"
import uvm_pkg::*;

//------- scoreboard ------------
class monitor extends uvm_monitor;
  `uvm_component_utils(monitor)
  bit mode;

  function new(string name = "monitor", uvm_component parent = null);
    super.new(name, parent);
    if(!uvm_config_db #(bit)::get(this, "*", "MODE", mode)) begin
      `uvm_fatal(get_type_name(), "failed to get operational mode");
    end
    `uvm_info(get_type_name(), $sformatf("operational mode = %b", mode), UVM_LOW);
  endfunction

endclass

//--------- agent ---------------
class agent extends uvm_component;
  `uvm_component_utils(agent)
  monitor mon;

  function new(string name = "agent", uvm_component parent = null);
    super.new(name, parent);
  endfunction

  function void build_phase(uvm_phase phase);
    super.build_phase(phase);
    mon = monitor::type_id::create("mon", this);
  endfunction
endclass

//------------------------
//----- UVM_ENV ----------
//------------------------
class env extends uvm_env;
  `uvm_component_utils(env)

  agent agent1;
  agent agent2;

  function new(string name = "env", uvm_component parent = null);
    super.new(name, parent);
  endfunction

  function void build_phase(uvm_phase phase);
    super.build_phase(phase);
    agent1 = agent::type_id::create("agent1", this);
    agent2 = agent::type_id::create("agent2", this);
  endfunction

endclass

//-----  UVM_TEST --------
class test extends uvm_test;
 `uvm_component_utils(test)

  env e;

  function new(string name = "test", uvm_component parent = null);
    super.new(name, parent);
  endfunction

  function void build_phase(uvm_phase phase);
    super.build_phase(phase);
    uvm_config_db #(bit)::set(this, "env.agent1.mon", "MODE", 1);
    e = env::type_id::create("env", this);
  endfunction

  function void end_of_elaboration_phase(uvm_phase phase);
    super.end_of_elaboration_phase(phase);
    uvm_top.print_topology();
  endfunction
endclass

//--------  TOP  ---------
module tb_top;
  initial begin
    run_test("test");
  end
endmodule
				
			

Leave a Comment

Your email address will not be published. Required fields are marked *