Introduction
Introduction Get started Hello UVM example UVM Phases Part 1 UVM Phases Part 2 UVM Base Classes UVM Object and Core Methods UVM ComponentsBuilding a Testbench
UVM Transaction UVM Sequence UVM Sequencer UVM Driver UVM Monitor UVM Scoreboard UVM Agent UVM Environment UVM TestOther Components
Coverage CollectorExecution Model
UVM Phases ObjectionsCommunication
TLM Basics TLM Blocking Put Port TLM Non-Blocking Put Port TLM Blocking Peek Port Analysis Ports TLM FIFOConfiguration
UVM Factory UVM Config DBRuntime Control
UVM Plusargs Seeds & Reproducibility Verbosity Control Debug Runtime ControlsAdvanced
Virtual Sequences Virtual SequencerUVM RAL
Intro Abstraction Flexibility Comparison Coverage Minimum Requirements Learning Path Register Types First Implementation Register with 2 Fields Register with Reserved Bits Access Policies Part 1 Access Policies Part 2 Access Policies Part 3 Access Policies Part 4 Memory Modeling Register Block Adapter Introduction Adapter Methods Adapter Example Predictor Types Desired and Mirror Values Register Methods Desired Value Mirror ValueUVMArena
Introduction
Introduction Get started Hello UVM example UVM Phases Part 1 UVM Phases Part 2 UVM Base Classes UVM Object and Core Methods UVM ComponentsBuilding a Testbench
UVM Transaction UVM Sequence UVM Sequencer UVM Driver UVM Monitor UVM Scoreboard UVM Agent UVM Environment UVM TestOther Components
Coverage CollectorExecution Model
UVM Phases ObjectionsCommunication
TLM Basics TLM Blocking Put Port TLM Non-Blocking Put Port TLM Blocking Peek Port Analysis Ports TLM FIFOConfiguration
UVM Factory UVM Config DBRuntime Control
UVM Plusargs Seeds & Reproducibility Verbosity Control Debug Runtime ControlsAdvanced
Virtual Sequences Virtual SequencerUVM RAL
Intro Abstraction Flexibility Comparison Coverage Minimum Requirements Learning Path Register Types First Implementation Register with 2 Fields Register with Reserved Bits Access Policies Part 1 Access Policies Part 2 Access Policies Part 3 Access Policies Part 4 Memory Modeling Register Block Adapter Introduction Adapter Methods Adapter Example Predictor Types Desired and Mirror Values Register Methods Desired Value Mirror ValueUVM RAL – Basic Register Implementation with Two Fields
Modeling a 32-bit register containing two 16-bit fields using UVM RAL.
Overview
In this example, we implement our second register using UVM RAL. This register contains two fields:
- slv_cntrl → Bits [15:0] (16-bit)
- slv_data → Bits [31:16] (16-bit)
Both fields are Read/Write, support reset, and allow randomization.
Step 1 – Extend uvm_reg
Every UVM register must extend uvm_reg and be registered
with the UVM factory.
class reg2 extends uvm_reg;
`uvm_object_utils(reg2)
Step 2 – Declare Two uvm_reg_field Variables
rand uvm_reg_field slv_cntrl;
rand uvm_reg_field slv_data;
We use the rand modifier to enable field randomization.
Step 3 – Constructor
The total register width is 32 bits (0–31). Even though each field is 16 bits, the register size must represent the total width.
function new (string name = "reg2");
super.new(name,32,UVM_NO_COVERAGE);
endfunction
Coverage is disabled using UVM_NO_COVERAGE.
Step 4 – Build and Configure Fields
Inside the build() function, we:
- Create each field using factory
- Configure size and bit position
- Define access policy and reset behavior
function void build;
slv_cntrl = uvm_reg_field::type_id::create("slv_cntrl");
slv_cntrl.configure(
.parent(this),
.size(16),
.lsb_pos(0),
.access("RW"),
.volatile(0),
.reset(16'h0),
.has_reset(1),
.is_rand(1),
.individually_accessible(1));
slv_data = uvm_reg_field::type_id::create("slv_data");
slv_data.configure(
.parent(this),
.size(16),
.lsb_pos(16),
.access("RW"),
.volatile(0),
.reset(16'h0),
.has_reset(1),
.is_rand(1),
.individually_accessible(1));
endfunction
Important: The LSB position must exactly match the DUT bit mapping.
Complete Working Example
`include "uvm_macros.svh"
import uvm_pkg::*;
class reg2 extends uvm_reg;
`uvm_object_utils(reg2)
rand uvm_reg_field slv_cntrl;
rand uvm_reg_field slv_data;
function new (string name = "reg2");
super.new(name,32,UVM_NO_COVERAGE);
endfunction
function void build;
slv_cntrl = uvm_reg_field::type_id::create("slv_cntrl");
slv_cntrl.configure(
.parent(this),
.size(16),
.lsb_pos(0),
.access("RW"),
.volatile(0),
.reset(16'h0),
.has_reset(1),
.is_rand(1),
.individually_accessible(1)
);
slv_data = uvm_reg_field::type_id::create("slv_data");
slv_data.configure(
.parent(this),
.size(16),
.lsb_pos(16),
.access("RW"),
.volatile(0),
.reset(16'h0),
.has_reset(1),
.is_rand(1),
.individually_accessible(1)
);
endfunction
endclass
module tb;
reg2 r2;
initial begin
r2 = new("r2");
r2.build();
end
endmodule
Common Error – Incorrect Register Size
If you change:
super.new(name,16,UVM_NO_COVERAGE);
The simulator will generate an error because the two fields together use 32 bits. The register size must match the total bit usage.
Run This Example on EDA Playground
Click below to open the exact working example.
▶ Open on EDA PlaygroundSummary
- A single register can contain multiple fields.
- The register size must equal total field width.
- Each field must have correct LSB position.
- Incorrect sizing leads to simulator errors.