Verification

UVM Configuration Database (uvm_config_db): Enabling Flexible and Reusable Verification Environments

uvm-wp

Introduction 

As verification environments grow in complexity, components often require access to configuration information such as interface handles, protocol settings, timeout values, address ranges, operating modes, and environment-specific parameters. Passing such information through constructors or manually distributing it across the hierarchy quickly
becomes difficult to manage and maintain.

The Universal Verification Methodology (UVM) addresses this challenge through the UVM Configuration Database (uvm_config_db). It provides a centralized mechanism for sharing configuration information between testbench components while preserving modularity and reusability.

The configuration database allows higher-level components, such as tests and environments, to configure lower-level components without requiring direct knowledge of their implementation details. Instead of hardcoding values or creating tight dependencies between components, information can be distributed dynamically through hierarchical
configuration settings.

The uvm_config_db is built on top of the UVM Resource Database and is one of the most frequently used mechanisms in UVM testbenches. It is widely used for passing virtual interface handles, agent configuration objects, protocol parameters, environment settings, and runtime controls.

A strong understanding of uvm_config_db is essential for building scalable, configurable, and reusable verification environments.

Why Do We Need uvm_config_db? 

Consider an environment containing multiple agents, drivers, monitors, scoreboards, and sequences. Each component may require access to common configuration information.

Without uvm_config_db, verification engineers often resort to:

  • Global variables.
  • Hardcoded parameter values
  • Constructor-based parameter passing
  • Direct handle sharing

These approaches introduce several challenges:

  • Increased coupling between components
  • Reduced reusability
  • Difficult maintenance
  • Poor scalability for large projects

The configuration database eliminates these problems by providing a hierarchical mechanism for distributing configuration information throughout the testbench.

The key advantages include:

  • Improved reusability
  • Better modularity
  • Easier maintenance
  • Centralized configuration management
  • Support for test-specific customization

Basic Methods of uvm_config_db 

The two primary methods used in most environments are:

1. set()

Used to place information into the configuration database.

Syntax

uvm_config_db #(type)::set(
cntxt,
inst_name,
field_name,
value
);

Example

uvm_config_db #(int)::set(
this,
“*”,
“timeout”,
1000
);

This stores the value 1000 under the field name timeout.

2. get()

Used to retrieve information from the configuration database.

Syntax 

uvm_config_db #(type)::get(
cntxt,
inst_name,
field_name,
value
);

Example
int timeout;
if(!uvm_config_db #(int)::get(
this,
“”,
“timeout”,
timeout))
begin
`uvm_fatal(“CFG”,”Timeout not found”)
end

The value stored in the database is copied into the variable timeout.

Understanding the Arguments

cntxt

Defines the starting point for the configuration search.

Examples:

this
null
uvm_root::get()
Using this restricts the search relative to the current component.
Using null performs an absolute search.
inst_name
Specifies the hierarchy path.

Examples:
“*”
“env.agent*”
“env.agent.driver”
“”
The wildcard (*) allows configuration values to be applied to multiple instances.

field_name

Represents the configuration key.
Examples:
“vif”
“cfg”
“is_active”
“timeout”

value

The actual object or data being stored.
Examples:
virtual interface
configuration object
integer
string
enum

Passing Virtual Interfaces Using uvm_config_db

One of the most common uses of uvm_config_db is passing virtual interfaces from the top-level module into UVM components.

Top Module

module top;
my_if vif();
initial begin
uvm_config_db #(virtual my_if)::set(
null,
“*”,
“vif”,
vif
);
run_test();
end
endmodule

Driver

class my_driver extends uvm_driver #(my_txn);
virtual my_if vif;
function void build_phase(
uvm_phase phase);
if(!uvm_config_db #(virtual my_if)::get(
this,
“”,
“vif”,
vif))
begin
`uvm_fatal(“NOVIF”,
“Interface not found”)
end
endfunction
endclass

This technique completely decouples the driver from the top-level module.

Test

Passing Configuration Objects

Instead of setting individual variables one by one, UVM commonly uses configuration objects.
Configuration Class
class agent_cfg extends uvm_object;

bit is_active;
int timeout;

`uvm_object_utils(agent_cfg)

endclass

Test

agent_cfg cfg;
cfg = agent_cfg::type_id::create(“cfg”);
cfg.is_active = UVM_ACTIVE;
cfg.timeout = 500;
uvm_config_db #(agent_cfg)::set(
this,
“env.agent*”,
“cfg,”
cfg
);

Agent

agent_cfg cfg;
if(!uvm_config_db #(agent_cfg)::get(
this,
“”,
“cfg”,
cfg))
begin
`uvm_fatal(“CFG”,
“Agent config missing”)
end

This approach simplifies management of large numbers of related settings.

Real-Time Application 1: Active and Passive Agents

In a typical SoC verification environment, the same agent may operate in two modes:

  • Active Mode
    • Driver present
    • Sequencer present
    • Generates traffic
  • Passive Mode
    • Monitor only
    • Observes DUT activity 

Using uvm_config_db, the test can dynamically select the operating mode.

cfg.is_active = UVM_PASSIVE;
uvm_config_db #(agent_cfg)::set(
this,
“env.axi_agent”,
“cfg”,
cfg
);
The agent behavior changes without modifying its source code.

Real-Time Application 2: Multi-Protocol Verification

Consider a reusable VIP supporting:

  • Driver present
  • Sequencer present
  • Generates traffic

A configuration object may contain:
cfg.protocol = AXI;
cfg.data_width = 64;
cfg.addr_width = 32;
Different tests can configure protocol behavior dynamically.
The same verification environment can support multiple protocols using only configuration changes.

Real-Time Application 3: Error Injection Testing

Many projects require fault injection.
Examples:

  • Parity errors
  • ECC errors
  • Protocol violations
  • Timeout conditions

A test can enable error injection through configuration settings.
cfg.enable_error = 1;
cfg.error_rate = 10;
Drivers and sequences retrieve these settings through uvm_config_db and automatically
adjust their behavior.
No source code modifications are required.

Configuration Lookup Mechanism

When a component calls get(), UVM searches using the following order:

1. Exact instance match
2. Hierarchical parent match
3. Wildcard match
4. Global match

The closest matching entry has the highest priority.
For example:
set(null,”*”,”timeout”,1000);
set(null,
“env.agent.driver”,
“timeout”,
500);
The driver receives:
timeout = 500;
because the specific path overrides the wildcard entry.

Debugging Configuration Problems
Configuration issues are among the most common UVM debugging challenges.
Useful techniques include:
uvm_top.print_topology();
and
uvm_config_db #(int)::dump();
Common mistakes:

  • Incorrect hierarchy path
  • Typographical errors in field names
  • Calling get() before set()
  • Incorrect data types
  • Missing wildcard usag 

Best Practices

  • Store configuration values in dedicated configuration objects.
  • Use meaningful field names.
  • Perform get() operations in build_phase().
  • Always check the return value of get().
  • Use wildcards carefully.
  • Avoid excessive global settings.
  • Keep configuration ownership in test classes.
  • Use configuration objects instead of many individual settings. 

Conclusion

The UVM Configuration Database is one of the most important mechanisms in modern UVM testbenches. It provides a flexible and scalable way to distribute configuration information throughout the verification hierarchy while maintaining component independence and reusability.

Through the set() and get() methods, verification engineers can pass virtual interfaces, configuration objects, protocol settings, runtime controls, and environment parameters without introducing tight coupling between components.

Whether configuring active/passive agents, supporting multiple protocols, enabling error injection, or managing large SoC verification environments, uvm_config_db plays a central role in creating reusable and  maintainable verification architectures.

A thorough understanding of configuration database usage, lookup rules, debugging  techniques, and best practices enables engineers to build highly configurable testbenches
that can easily adapt to evolving verification requirements.

  • Naresh Kumar Koppala

    K. Naresh Kumar is a passionate VLSI design and verification engineer with 16+ years of experience, including 13 years in academia and 3+ years in industry. He specializes in SystemVerilog, UVM, AMBA protocols (AXI, AHB, APB), and RISC-V IP/SoC verification, and is known for simplifying complex verification concepts through clear, practical teaching. Having trained several hundred learners, he continues to inspire and prepare engineers with strong industry-ready skills and a deep commitment to verification excellence.

Loading Popular Posts...

Loading categories...

Download the

Maven Learning App

LEARN ANYTIME, ANYWHERE

Get trained online as a VLSI Professional

FLAT

40% OFF

On all Blended Courses

maven-silicon

Have Doubts?
Read Our FAQs

Don't see your questions answered here?