HomeProblemsTheoryUVM
Intermediate3 min readChapter 10

Configuration Database

Pass configuration data between testbench components using uvm_config_db — virtual interfaces, parameters, and objects.

Configuration Database (uvm_config_db)

The uvm_config_db is UVM's centralized configuration mechanism. It lets any component store and retrieve values — virtual interfaces, parameters, configuration objects — without direct references.


The API

Setting a value:

systemverilog
uvm_config_db#(type)::set(context, instance_path, field_name, value);

Getting a value:

systemverilog
uvm_config_db#(type)::get(context, instance_path, field_name, variable);

Example 1: Passing the Virtual Interface

The most common use — passing the DUT interface from the top module to UVM components:

systemverilog
// ── Top module (sets the interface) ── module tb_top; logic clk; apb_if vif(clk); // Instantiate DUT dut u_dut (.clk(clk), .psel(vif.PSEL), /* ... */); initial begin // Store the interface in config_db uvm_config_db#(virtual apb_if)::set( null, // null = global "uvm_test_top.env.agent*", // who can see it "vif", // field name vif // the value ); run_test(); end endmodule
systemverilog
// ── Driver (gets the interface) ── function void build_phase(uvm_phase phase); super.build_phase(phase); if (!uvm_config_db#(virtual apb_if)::get(this, "", "vif", vif)) `uvm_fatal("NOVIF", "Virtual interface not found!") endfunction

Example 2: Configuration Objects

For complex configurations, create a config object:

systemverilog
class apb_agent_config extends uvm_object; `uvm_object_utils(apb_agent_config) int num_transactions = 100; bit enable_coverage = 1; bit enable_checking = 1; bit [31:0] base_address = 32'h0; function new(string name = "apb_agent_config"); super.new(name); endfunction endclass

Set it from the test:

systemverilog
class my_test extends uvm_test; function void build_phase(uvm_phase phase); super.build_phase(phase); apb_agent_config cfg = apb_agent_config::type_id::create("cfg"); cfg.num_transactions = 500; cfg.enable_coverage = 1; uvm_config_db#(apb_agent_config)::set( this, "env.agent*", "cfg", cfg ); endfunction endclass

Retrieve it in the agent:

systemverilog
class apb_agent extends uvm_agent; apb_agent_config cfg; function void build_phase(uvm_phase phase); super.build_phase(phase); if (!uvm_config_db#(apb_agent_config)::get(this, "", "cfg", cfg)) `uvm_fatal("NOCFG", "Agent config not found!") endfunction endclass

Scoping Rules

The instance_path controls which components can see the value:

Scope PatternWho Can Access
"*"Every component in the testbench
"env.agent*"env.agent and all its children
"env.agent.driver"Only the driver

Debugging config_db

Dump all entries:

systemverilog
uvm_config_db#(virtual apb_if)::dump();

Command-line trace:

text
+UVM_CONFIG_DB_TRACE

This prints every set and get call with full path information.


Common Pitfalls

PitfallSolution
Type mismatch between set and getUse exact same type parameter
Wrong scope — can't find valueUse wildcards (*) or check path
Get before set (timing)Set in test's build_phase, get in agent's build_phase
Forgetting to check return valueAlways use \uvm_fatal on failure

Best Practices

  • Use config objects instead of many individual set/get calls.
  • Always \uvm_fatal on get failure for required configurations.
  • Set values at the highest appropriate level (test → env → agent).
  • Use null context for truly global values (virtual interfaces from top module).