Constructing Register Model

Constructing Register Model

This section describes how to construct a UVM register model for register and memory access.

Register Field

Register fields are declared with uvm_reg_field class type.

uvm_reg_field reg_name;
  • Register fields are declared in register class
  • The field name must be unique within the scope of its declaration
  • The access policy of a field is specified using the uvm_reg_field::configure() method
  • Configure method has to be called from the build() method of the register that instantiates it (refer to register example)

Pre-defined Field Access Policies

Access Policy Description Effect of a Write on Current Field Value Effect of a Read on Current Field Value Read back Value
RO Read Only No effet No effet Current Value
RW Read, Write Changed to the written value No effet Current Value
RC Read Clears All No effet Sets all bits to 0’s Current Value
WRC Write, Read Clears All Changed to the written value Sets all bits to 0’s Current Value
WC Write Clears All Sets all bits to 0’s No effet Current Value
W1C Write 1 to Clear If the bit in the written value is a 1, the corresponding bit in the field is set to 0. Otherwise, the field bit is not affected No effet Current Value
W0C Write 0 to Clear If the bit in the written value is a 0, the corresponding bit in the field is set to 0. Otherwise, the field bit is not affected No effet Current Value

Reserved Fields

  • There is no pre-defined field access policy for reserved fields
  • Reserved fields should be left unmodelled, where they will be assumed to be RO fields filled with 0’s

Register

The register is constructed by writing a class extended from the uvm_reg class. There must be one class per unique register type

class my_reg extends uvm_reg;
  rand uvm_reg_field Field_0;
  rand uvm_reg_field Field_1;
endclass
  • The name of the register type class must be unique within the scope of its declaration
  • The uvm_reg_field::configure() method shall be called from the register type build method
class my_reg extends uvm_reg;
  virtual function build();
    this.Field_0 = my_reg::type_id::create(
      .name(“Field_0”),
      .parent(null),
      .contxt(get_full_name()));
    this.Field_0.configure(this, ...);
  endfunction
endclass

Register File

A register file type is constructed by writing a class extended from the uvm_reg_file class

class my_reg_file extends uvm_reg_file;
  `uvm_object_utils(my_reg_file)
endclass
  • The name of the register file type class must be unique within the scope of its declaration
  • Register files can contain other register files.
  • The build() method shall call the configure() method for all register and register file class properties
  • specifying get_block() for the parent block and this for the parent register file
class reg_file extends uvm_reg_file;

virtual function build();
  uvm_reg_block blk = get_block();
  this.rf = reg_file_0::type_id::create(
             .name($psprintf(“%s.rf1”, get_name())),
             .parent(null),
             .contxt(blk.get_full_name()));
  this.rf.configure(get_block(), this, ...);
  this.rf.build();
  this.rf.add_hdl_path();
endfunction

endclass

map() Method

  • A virtual map() function, with uvm_reg_map and address offset arguments map() method shall call uvm_reg_map::add_reg() for all register class properties, adding the value of the address offset argument to the offset of the register in the register file map() method shall call the map() method of all register file class properties, adding the value of the address offset argument to the offset of the register file base offset
  • The map() method may call the add_hdl_path() method for all register or register file class properties
virtual function map(uvm_reg_map mp, uvm_reg_addr_t offset);
  mp.add_reg(this.reg_0, base_addr + 'h0);
  mp.add_reg(this.reg_1, base_addr + 'h4;
  this.rf.map(mp, base_addr + 'h100);
endfunction

set_offset() Method

  • A virtual set_offset() function, with a uvm_reg_map and address offset arguments, may also be implemented
  • The set_offset() method shall call the set_offset() method for all register and register file class properties
virtual function set_offset(uvm_reg_map mp, uvm_reg_addr_t offset);
  this.reg_0.set_offset(mp, base_addr + 'h0);
  this.reg_1.set_offset(mp, base_addr + 'h4);
  this.rf.set_offset(mp, base_addr + 'h100);
endfunction

Memory Types

  • A memory type is constructed using a class extended from the uvm_mem class
  • The name of the memory type class must be unique within the scope of its declaration
class my_mem extends uvm_mem;
  `uvm_object_utils(my_mem)
endclass

Register Block

  • A block is constructed by writing a class extended from the uvm_reg_block class
  • The name of the block type class must be unique within the scope of its declaration
class my_blk extends uvm_reg_block;
  `uvm_object_utils(my_blk)
endclass

The block type must contain a class property for each,

  • named address map
  • register
  • register file
  • memory
  • sub-block
  • These shall have the rand attribute
  • The build() method shall instantiate all named address maps by calling the uvm_reg_block::create_map() method

❮ Previous Next ❯