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:
systemveriloguvm_config_db#(type)::set(context, instance_path, field_name, value);
Getting a value:
systemveriloguvm_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:
systemverilogclass 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:
systemverilogclass 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:
systemverilogclass 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 Pattern | Who 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:
systemveriloguvm_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
| Pitfall | Solution |
|---|---|
| Type mismatch between set and get | Use exact same type parameter |
| Wrong scope — can't find value | Use wildcards (*) or check path |
| Get before set (timing) | Set in test's build_phase, get in agent's build_phase |
| Forgetting to check return value | Always use \uvm_fatal on failure |
Best Practices
- Use config objects instead of many individual set/get calls.
- Always
\uvm_fatalon get failure for required configurations. - Set values at the highest appropriate level (test → env → agent).
- Use
nullcontext for truly global values (virtual interfaces from top module).