UVM Resource Database

The UVM Resource Database is a powerful feature in the Universal Verification Methodology (UVM) that allows for the storage and retrieval of configuration data across different components of a verification environment. It provides a convenient way to share information and configure components dynamically.

 

UVM Resource Database Diagram

Here’s a simplified diagram to illustrate the UVM Resource Database:

plaintext
+-------------------+
|   Resource DB     |
+-------------------+
          |
          v
+-------------------+
|   Resources       |
|   (Name, Scope)   |
+-------------------+
          |
          v
+-------------------+
|   Components      |
|   (Access DB)     |
+-------------------+

Why Use the Resource Database?

  • Centralized Configuration: Store configuration parameters, like test modes, register addresses, or simulation settings, in a single location.
  • Global Data Sharing: Share data between different parts of the testbench, such as passing information from the test to the environment or from the environment to agents.
  • Dynamic Configuration: Modify configuration settings during the simulation, allowing for dynamic test scenarios.
  • Simplified Component Communication: Reduce the need for complex connections and argument passing between components.

How the Resource Database Works:

The resource database uses a hierarchical naming scheme to organize data. This hierarchy is similar to a file system, with directories and files. Each piece of data is stored as a resource, which has a name (path) and a value.

Key Concepts:

  • Resources: Individual pieces of data stored in the database. Each resource has a name (a string path) and a value (of any data type).
  • Paths: Resources are accessed using hierarchical paths, similar to file system paths. For example: "uvm_test_top.env.agent.reg_block.reg1.address".
  • Types: Resources can store values of any data type, including integers, strings, objects, and arrays.
  • Setting Resources: Use the uvm_resource::set() method to store a resource in the database.
  • Getting Resources: Use the uvm_resource::get() method to retrieve a resource from the database.

Diagram 1: Resource Database Hierarchy

+-------------------------------------------------+
| UVM Resource Database                           |
+-------------------------------------------------+
| uvm_test_top                                    |
|   +-- env                                       |
  |       +-- agent                                   |
  |           +-- reg_block                           |
   |               +-- reg1                             |
   |                   +-- address (Resource)           |
   |                   +-- data (Resource)              |
   |               +-- reg2                             |
   |                   +-- value (Resource)             |
+-------------------------------------------------+

Using the UVM Resource Database

1. Setting a Resource

To set a resource in the database, use the set method. For example:

uvm_resource_db#(int)::set("my_scope", "my_resource", 42, this);

2. Getting a Resource

To retrieve a resource from the database, use the get_by_name or get_by_type methods. For example:

int my_resource;
uvm_resource_db#(int)::get_by_name("my_scope", "my_resource", my_resource);

3. Dumping Resources

To dump all resources in the database, use the dump method:

uvm_resource_db::dump();

Example Code:

// Setting a resource:
int reg1_addr = 'h100;
uvm_resource#(int)::set("uvm_test_top.env.agent.reg_block.reg1.address", reg1_addr);

// Getting a resource:
int retrieved_addr;
uvm_resource#(int) addr_rsrc = new("uvm_test_top.env.agent.reg_block.reg1.address");
if (addr_rsrc.get(retrieved_addr)) begin
  `uvm_info("RESOURCE_DB", $sformatf("Retrieved address: 0x%h", retrieved_addr), UVM_MEDIUM)
end else begin
  `uvm_error("RESOURCE_DB", "Failed to retrieve address");
end

// Setting a resource with priority
uvm_resource#(int)::set("uvm_test_top.env.agent.config.verbose", 1, this); // this is the priority, higher number has higher priority
uvm_resource#(int)::set("uvm_test_top.env.agent.config.verbose", 0, null);

//Getting the resource
int verbose;
uvm_resource#(int) verbose_rsrc = new("uvm_test_top.env.agent.config.verbose");
verbose_rsrc.get(verbose); // verbose will be 1

Resource Types:

UVM provides parameterized resource classes for different data types:

  • uvm_resource#(T): For general data types.
  • uvm_int_resource: For integers.
  • uvm_string_resource: For strings.
  • uvm_object_resource: For UVM objects.

Diagram 2: Resource Class Hierarchy (Simplified)

uvm_void
    └── uvm_resource_base
        ├── uvm_resource#(T)
        │   ├── uvm_int_resource
        │   ├── uvm_string_resource
        │   └── uvm_object_resource
        └── uvm_pool#(uvm_resource_base)

Resource Priorities:

When multiple resources with the same path are set, the resource with the highest priority is retrieved. The priority is an integer value passed as an argument to the set() method. Components have an implicit priority derived from their hierarchical position in the testbench, with higher levels (closer to uvm_test_top) having lower priority. Explicit priorities can override this.

Example of priority:

Setting the resource with null as the instantiator has the lowest priority (0). Setting it with an existing component has a higher priority (which is based on the depth of the component in the hierarchy).