What is uvm_config_db?
uvm_config_db
is a high-level, user-friendly mechanism used in UVM to pass configuration objects or values down the hierarchy (from test or environment into agents, sequences, drivers, etc.).
To know more about uvm_config_db’s options, methods, and examples, read this article: uvm_config_db
Key features:
- It is type-safe (click link to read about What is Type-Safe in UVM)
- Scope-based (based on component hierarchy path). Wild characters are also supported.
- Designed specifically for configuration purposes
- Widely used in most UVM testbenches
When to use uvm_config_db:
- When you need to pass values/configs into components. For example, an interface handle can be passed from the top to the monitor level.
- For enabling/disabling features, setting timeouts, and parameters.
- For readability and maintainability. Hierarchy can be mentioned for readability.
Example:
//Example1: Setting a value
uvm_config_db#(int)::set(this, "*agent.drv", "data_width", 32);
// Getting the value
int data_w;
if (!uvm_config_db#(int)::get(this, "", "data_width", data_w))
`uvm_fatal("CONFIG", "data_width not set");
//Example2: Setting driver configuration
class my_test extends uvm_test;
virtual function void build_phase(uvm_phase phase);
int bus_width = 16;
uvm_config_db#(int)::set(this, "env.agent.drv", "bus_width", bus_width);
endfunction
endclass
What is uvm_resource_db?
uvm_resource_db
is a more generic and powerful (but lower-level) database in UVM used for storing and accessing values or objects using resource names and types.
To know more about uvm_resource_db’s options, methods, and examples, read this article: uvm_resource_db
Key features:
- Not type-safe (click link to read about What is Type-Safe in UVM)
- Scope is not required (more global)
- Supports overrides and lookups by resource name
- Suitable for cross-hierarchy access and global shared resources
When to use uvm_resource_db:
- When values need to be shared across disjoint hierarchies
- For global flags, or logging/reporting settings
- For tool-level or factory-level overrides
Example:
// Set resource
uvm_resource_db#(bit)::set("ENABLE_CRC", 1, this);
// Get resource
bit crc_enable;
if (!uvm_resource_db#(bit)::read_by_name("ENABLE_CRC", crc_enable))
`uvm_error("CONFIG", "CRC flag not found");
//Example2: Enabling global feature from test class
class my_test extends uvm_test;
virtual function void build_phase(uvm_phase phase);
uvm_resource_db#(bit)::set("FEATURE::CRC_ENABLE", 1, this);
endfunction
endclass
class my_driver extends uvm_driver;
bit crc_enable;
virtual function void build_phase(uvm_phase phase);
uvm_resource_db#(bit)::read_by_name("FEATURE::CRC_ENABLE", crc_enable);
endfunction
endclass
Key differences
Feature | uvm_config_db | uvm_resource_db |
Usage purpose | Configuration of components | General-purpose resource sharing |
Scopre hierarchy | Yes (Component path based) | No (Resource name based) |
Type safety | Yes | Scope hierarchy |
Readability | High (Preferred for component config) | Low (Need careful naming) |
Typical use case | Sequence/Agent/Driver/Virtual interface, etc., config | No. (Can be made type-safe by explicit casting) |
Best Practices
- Prefer
uvm_config_db
for hierarchical component configuration. - Use
uvm_resource_db
for global control or when hierarchy paths aren’t predictable. - Always check return values of
get()
orread()
methods. - Avoid overusing
resource_db
— it can make debugging harder.
No responses yet