Part 9 · Register Model (RAL) · Intermediate

Sequencer, Map, Adapter: set_sequencer Deep Dive

How reg maps route frontdoor operations through adapter and sequencer, plus multi-map and base address details.

What set_sequencer really binds

The call reg_model.default_map.set_sequencer(bus.sqr, adapter) does two critical bindings: it tells the map which sequencer executes frontdoor operations, and which adapter converts uvm_reg_bus_op into protocol items.

diagram
[UVM][RAL] frontdoor conversion pipeline

reg.write(status, data)
    │
    ▼
map.do_write()
    │
    ├─ uses sequencer bound by set_sequencer()
    └─ uses adapter bound by set_sequencer()
           │
           ▼
adapter.reg2bus(rw) -> apb_item/axi_item
           │
           ▼
sequencer.start_item(item) -> driver -> DUT
  • No set_sequencer means RAL has no legal frontdoor route for that map.

  • Wrong adapter type causes bad data, address, or status translation.

  • Map binding is per-map, not global to the entire reg model.


Single-map and multi-map examples

Single map (common)

systemverilog
function void connect_phase(uvm_phase phase);
  super.connect_phase(phase);
  reg_model.default_map.set_sequencer(apb.sqr, apb_adapter);
endfunction

Multiple maps (APB + debug bus)

systemverilog
class soc_reg_env extends uvm_env;
  core_reg_block                 reg_model;
  apb_agent                      apb;
  dbg_agent                      dbg;
  apb_reg_adapter                apb_adapter;
  dbg_reg_adapter                dbg_adapter;

  function void connect_phase(uvm_phase phase);
    super.connect_phase(phase);

    // map used by normal software-like traffic
    reg_model.apb_map.set_sequencer(apb.sqr, apb_adapter);

    // map used by debug port accesses
    reg_model.dbg_map.set_sequencer(dbg.sqr, dbg_adapter);
  endfunction
endclass
diagram
[RAL] map ownership model

default_map   -> APB sequencer + APB adapter
dbg_map       -> DBG sequencer + DBG adapter
cfg_map       -> AXI-Lite sequencer + AXI adapter

Each map carries its own transport binding.
Wrong map call => valid transaction on wrong bus path.
  • Always call set_sequencer on the map that the sequence will actually use.

  • For multi-map designs, name maps clearly to avoid accidental bus selection.

  • When tests override path/map, verify adapter and base addresses per map.


Adapter responsibilities in this binding

A set_sequencer binding is only as correct as the adapter implementation behind it.

systemverilog
class apb_reg_adapter extends uvm_reg_adapter;
  `uvm_object_utils(apb_reg_adapter)
  uvm_reg_addr_t base_addr = '0;

  function new(string name = "apb_reg_adapter");
    super.new(name);
    supports_byte_enable = 0;
    provides_responses   = 0;
  endfunction

  virtual function uvm_sequence_item reg2bus(const ref uvm_reg_bus_op rw);
    apb_item item = apb_item::type_id::create("item");
    item.write = (rw.kind == UVM_WRITE);
    item.addr  = base_addr + rw.addr;
    item.data  = rw.data;
    return item;
  endfunction

  virtual function void bus2reg(uvm_sequence_item bus_item, ref uvm_reg_bus_op rw);
    apb_item item;
    if (!$cast(item, bus_item)) begin
      rw.status = UVM_NOT_OK;
      return;
    end
    rw.kind   = item.write ? UVM_WRITE : UVM_READ;
    rw.addr   = item.addr - base_addr;
    rw.data   = item.data;
    rw.status = item.slverr ? UVM_NOT_OK : UVM_IS_OK;
  endfunction
endclass

Deep dive checklist for set_sequencer bugs

  1. Print map name used by sequence; confirm it is the map bound in connect_phase.

  2. Print sequencer full name from map to ensure expected bus agent is used.

  3. Compare adapter instance pointer in set_sequencer and predictor.adapter.

  4. Verify adapter base_addr translation against memory map docs.

  5. Run one write to a known register and inspect monitor address/data.

Key takeaways

  • set_sequencer binds map transport: sequencer + adapter together.

  • Bindings are map-specific; multi-map envs need explicit per-map setup.

  • Most frontdoor routing bugs are map mismatch or adapter address translation errors.

Common pitfalls

  • Binding only default_map while tests use a secondary map.

  • Using different adapters for stimulus and prediction with inconsistent base_addr.

  • Assuming map binding is inherited automatically by sub-maps.