Tutorials

Learn More

The UVM register model (RAL) methods like the write() and read() deal with register transactions (i.e. register sequence item) and DUT accepts or sends signal level transactions (bus sequence item) from/to the testbench by an interface. Hence, there is a requirement to convert the register transactions to bus transactions and vice-versa. This is fulfilled by the “Register Adapter”. The user-defined adapter class is derived from the uvm_reg_adpater base class.

RAL Adapter

Every front door access operation (read() or write() method calls) passes through reg2bus and bus2reg API. A user must implement these two methods.

reg2bus: It converts register transactions to bus transactions

pure virtual function uvm_sequence_item reg2bus(const ref uvm_reg_bus_op rw)

bus2reg: It converts bus transactions to register transactions

pure virtual function void bus2reg(uvm_sequence_item bus_item, ref uvm_reg_bus_op rw)

User-defined reg_axi_adapter implementation

class reg_axi_adapter extends uvm_reg_adapter;
  `uvm_object_utils(reg_axi_adapter)
  
  function new(string name = "reg_axi_adapter");
    super.new(name);
  endfunction
  
  virtual function uvm_sequence_item reg2bus (const ref uvm_reg_bus_op rw);
    ...
    ...
  endfunction
  
  virtual function void bus2reg (uvm_sequence_item bus_item, ref uvm_reg_bus_op rw);
    ...
    ...
   endfunction
endclass

Plug in register adapter in testbench environment

class env extends uvm_env;
  `uvm_component_utils(env)
  agent agt;
  reg_axi_adapter adapter;
  RegModel_SFR reg_model; // Top level register block

  function new(string name = "env", uvm_component parent = null);
    super.new(name, parent);
  endfunction
  
  function void build_phase(uvm_phase phase);
    super.build_phase(phase);
    agt = agent::type_id::create("agt", this);
    adapter = reg_axi_adapter::type_id::create("adapter");
    reg_model = RegModel_SFR::type_id::create("reg_model");
    reg_model.build();
    reg_model.reset();
    reg_model.lock_model();
    reg_model.print();
    
    uvm_config_db#(RegModel_SFR)::set(uvm_root::get(), "*", "reg_model", reg_model);
  endfunction
  
  function void connect_phase(uvm_phase phase);
    super.connect_phase(phase);
    reg_model.default_map.set_sequencer( .sequencer(agt.seqr), .adapter(adapter) );
    reg_model.default_map.set_base_addr('h0);
  endfunction
endclass