UVM RAL: Register Defines, Model Types, Enums, and Model Defines

The UVM Register Abstraction Layer (RAL) provides a structured approach to defining and verifying memory-mapped registers in a UVM testbench. It abstracts the register interface, making it easier to perform read/write operations, predictions, and functional coverage.

This article will cover:

  1. UVM RAL Register Defines
  2. UVM RAL Model Types
  3. UVM RAL Enumerations (Enums)
  4. UVM RAL Model Defines

Additionally, we will explain important UVM RAL enumerations such as uvm_status_e, uvm_path_e, uvm_check_e, uvm_access_e, uvm_predict_e, and uvm_reg_mem_tests_e.

1. UVM RAL Register Defines

UVM RAL provides various macros and base classes to simplify the register model implementation.

Common UVM RAL Register Defines:

  • uvm_reg_field – Defines individual register fields.
  • uvm_reg – Represents a single register.
  • uvm_reg_block – Defines a register block that contains multiple registers.
  • UVM_REG_ADDR_WIDTH – Specifies the width of the register address bus.
Example: Defining a Register in UVM RAL
class my_register extends uvm_reg;
  rand uvm_reg_field field1;

  function new(string name = "my_register");
    super.new(name, 32, UVM_NO_COVERAGE);
  endfunction

  virtual function void build();
    field1 = uvm_reg_field::type_id::create("field1");
    field1.configure(this, 8, 0, "RW", 0, 1, 1, 0, 0);
  endfunction
endclass

2. UVM RAL Model Types

UVM RAL provides several data types to manage register modeling, addressing, and data representation.

Key UVM RAL Model Types:

  1. uvm_reg_data_t – Represents register data (default width: 32 bits).
  2. uvm_reg_data_logic_t – Similar to uvm_reg_data_t, but uses logic type for representation.
  3. uvm_reg_addr_t – Represents register address values.
  4. uvm_reg_addr_logic_t – Address values represented using logic type.
  5. uvm_reg_byte_en_t – Stores byte enable values for partial register accesses.
  6. uvm_reg_cvr_t – Defines functional coverage types for registers and fields.
  7. uvm_hdl_path_slice – Represents a specific slice of an HDL path, used in backdoor accesses.
Example: Using UVM RAL Model Types
uvm_reg_data_t data;
uvm_reg_addr_t address = 32'h1000;
uvm_reg_byte_en_t byte_en = 4'b1111;

reg1.write(status, address, data, UVM_FRONTDOOR, byte_en);

Here, uvm_reg_data_t stores register data, uvm_reg_addr_t holds the register address, and uvm_reg_byte_en_t defines which bytes are enabled during the write operation.

3. UVM RAL Enumerations (Enums)

UVM RAL uses several enumerations to define register operations, access methods, and error handling.

Important UVM RAL Enumerations:

1. uvm_status_e (Transaction Status)

Defines the status of a register operation.

  • UVM_IS_OK – Operation was successful.
  • UVM_HAS_X – The transaction returned an unknown (X) value.
  • UVM_NOT_OK – Operation failed.
2. uvm_path_e (Access Path Type)

Specifies whether the register is accessed via frontdoor (bus) or backdoor (direct DUT access).

  • UVM_FRONTDOOR – Access via the bus interface.
  • UVM_BACKDOOR – Direct access to the register in the DUT.
Example: Using uvm_path_e
uvm_status_e status;
reg1.read(status, data, UVM_BACKDOOR);

This reads the register using the backdoor method, bypassing the bus.

3. uvm_check_e (Checking Strategy for Register Accesses)

Defines how register values are checked.

  • UVM_CHECK – Compares expected vs. actual values.
  • UVM_NO_CHECK – Skips comparison.
4. uvm_access_e (Register Access Permissions)

Defines how registers can be accessed.

  • UVM_READ – Read-only access.
  • UVM_WRITE – Write-only access.
  • UVM_READ_WRITE – Both read and write allowed.
  • UVM_VOLATILE – The value can change without explicit writes.
5. uvm_predict_e (Prediction Mechanism for Registers)

Defines how register predictions are updated.

  • UVM_PREDICT_DIRECT – Updates the mirror value directly.
  • UVM_PREDICT_READ – Updates mirror only when a read occurs.
  • UVM_PREDICT_WRITE – Updates mirror only when a write occurs.
6. uvm_reg_mem_tests_e (Register and Memory Test Types)

Defines different register/memory tests that can be performed.

  • UVM_DO_READS – Test reads.
  • UVM_DO_WRITES – Test writes.
  • UVM_DO_RAND_ACCESS – Perform random register accesses.
Example: Using uvm_predict_e
reg1.predict(32'hDEADBEEF, UVM_PREDICT_DIRECT);

This updates the mirror value of reg1 directly without requiring a read/write operation.

4. UVM RAL Model Defines

Defines in UVM RAL help configure global settings for register modeling.

Common UVM RAL Model Defines:

  • UVM_REG_ADDR_WIDTH – Defines the width of register addresses.
  • UVM_REG_DATA_WIDTH – Specifies the default width of register data.
  • UVM_NO_COVERAGE – Disables register functional coverage.
  • UVM_HIERARCHICAL_REG_ACCESS – Enables hierarchical access to register blocks.
Example: Setting Register Address Width
`define UVM_REG_ADDR_WIDTH 32

This ensures that all register addresses are 32 bits wide.