📚 UVM Register Model Creation and Integration into the UVM Environment#
UVM RAL (Register Abstraction Layer) provides a comprehensive structure for modeling the register and memory structures in a design and controlling them from the testbench. This page details both the creation of the register model and its integration into the UVM environment. It also covers critical topics such as Pre-defined Field Access Policies, the map()
and set_offset()
methods, the adapter concept, and bus interface connections.
1️⃣ Creating the Register Model#
🔨 Manual Modeling#
A register model can be manually written in SystemVerilog using classes like uvm_reg
, uvm_reg_field
, uvm_reg_block
, and uvm_mem
:
class my_reg extends uvm_reg;
rand uvm_reg_field status;
function new(string name = "my_reg");
super.new(name, 32, UVM_NO_COVERAGE);
endfunction
virtual function void build();
status = uvm_reg_field::type_id::create("status");
status.configure(this, 8, 0, "RW", 0, 1, 1, 0);
endfunction
endclass
2️⃣ Pre-defined Field Access Policies#
UVM RAL provides built-in (pre-defined) access policies for register or field access. These include:
"RW"
: Read-Write"RO"
: Read-Only"WO"
: Write-Only"RC"
: Read-Clear"W1C"
: Write-1-to-Clear
Example:
status.configure(this, 8, 0, "RW", 0, 1, 1, 0);
Here:
- 8 → Field width (number of bits)
- 0 → Offset (bit position within the register)
"RW"
→ Pre-defined field access policy- The other parameters define reset value, volatility, and other control details.
3️⃣ Creating a Register Block and Mapping (map() Method)#
A uvm_reg_block
groups registers or memories into a single structure. Within the register block, the map()
method defines the physical addresses of registers:
default_map = create_map("default_map", 'h0, 4, UVM_LITTLE_ENDIAN);
default_map.add_reg(ctrl_reg, 'h00, "RW");
Here:
'h0
→ Base address4
→ Address strideUVM_LITTLE_ENDIAN
→ Endian format
The map()
method enables the creation of address mappings at the register block level. The create_map()
method creates a new map, and add_reg()
adds registers to this map.
4️⃣ set_offset() Method#
Sometimes, the offset address of registers or register fields needs to be set dynamically. For this, set_offset()
is used:
ctrl_reg.set_offset('h10); // Sets the register offset to 'h10
This makes the register model more dynamic, supporting multiple address maps.
5️⃣ Adapter Concept and Details#
🔌 What is an Adapter?#
A uvm_reg_adapter
acts as a bridge between the register model and the bus protocol. It translates register read/write calls into bus-level transactions between the sequencer and driver.
Example adapter:
class my_adapter extends uvm_reg_adapter;
function new(string name = "my_adapter");
super.new(name);
supports_byte_enable = 0;
provides_responses = 1;
endfunction
virtual function uvm_sequence_item reg2bus(const ref uvm_reg_bus_op rw);
// Converts RAL request into a bus protocol transaction
endfunction
virtual function void bus2reg(uvm_sequence_item bus_item, ref uvm_reg_bus_op rw);
// Converts the bus response back into the RAL model
endfunction
endclass
- reg2bus(): Converts a RAL model operation into a bus-level transaction.
- bus2reg(): Converts a bus-level response back into the RAL model.
The adapter serves as the intermediary between the register model and the bus interface in the UVM environment.
6️⃣ Connecting the Map and Bus Interface#
To connect the register model for frontdoor access in the testbench:
- Link the default map of the register block to the sequencer.
- Assign the adapter.
regmodel.default_map.set_sequencer(my_sequencer, my_adapter);
my_sequencer
: The sequencer controlling the bus protocol.my_adapter
: Converts RAL access into bus transactions.
This ensures that:
- Register read/write calls from the RAL model are routed through the adapter and the bus to the driver.
- The register model is fully integrated with the bus protocol.
7️⃣ Integrated Usage Flow#
🔎 In summary:
1️⃣ Register Model: Define registers, fields, blocks, and set offsets.
2️⃣ Adapter: Write a bridge between RAL and the bus protocol.
3️⃣ Sequencer Connection: Establish frontdoor access with set_sequencer()
.
4️⃣ Testbench Integration: Instantiate the register model in the environment and write your tests.
✨ Summary Table#
Topic | Description |
---|---|
Pre-defined Policies | Field access types (RW , RO , WO , RC , W1C ) |
map() Method | Adds registers to the address map |
set_offset() Method | Dynamically sets register or field offset |
Adapter | Bridges the RAL model with the bus protocol |
Bus Interface Connection | Connects the RAL model to the sequencer/driver |