Part 9 · Register Model (RAL) · Intermediate

Adapter Debug Patterns and Triage

Systematic debugging of adapter issues: wrong address/data mapping, cast failures, response mismatches, and mirror drift triage workflow.

Most common adapter failure signatures

Adapter defects usually appear in repeatable patterns: off-by-offset addresses, swapped read/write data fields, cast failures in bus2reg, status never propagating, and mirror drift after apparently successful accesses.

diagram
[RAL] adapter bug signatures

  symptom A:
    read/write hits wrong register consistently
    -> address translation or map base issue

  symptom B:
    reads always return previous write value
    -> bus2reg read-data mapping bug

  symptom C:
    intermittent UVM_NOT_OK without protocol error
    -> response path/config mismatch

  symptom D:
    mirror diverges after traffic bursts
    -> predictor wiring or bus2reg decode gap
  • Pattern recognition cuts debug time more than random waveform inspection.

  • Start with deterministic single-register reproducer before random tests.

  • Capture reg2bus and bus2reg logs with transaction IDs for correlation.


Wrong address/data mapping patterns

Address bugs are often structural: missing base offset, incorrect byte-to-word conversion, or map configured with wrong byte width. Data bugs often stem from endianness or lane mismatches.

systemverilog
// Lightweight adapter instrumentation (temporary for triage)
virtual function uvm_sequence_item reg2bus(const ref uvm_reg_bus_op rw);
  apb_item tr = apb_item::type_id::create("tr");
  tr.addr  = rw.addr;
  tr.write = (rw.kind == UVM_WRITE);
  tr.wdata = rw.data;
  tr.strb  = rw.byte_en[3:0];

  `uvm_info(
    "ADAPT_R2B",
    $sformatf("kind=%s addr=0x%0h data=0x%0h be=0x%0h",
      (rw.kind==UVM_WRITE)?"W":"R", rw.addr, rw.data, rw.byte_en),
    UVM_HIGH
  )
  return tr;
endfunction

virtual function void bus2reg(uvm_sequence_item bus_item, ref uvm_reg_bus_op rw);
  apb_item tr;
  if (!$cast(tr, bus_item)) begin
    `uvm_error("ADAPT_B2R", "cast failed")
    rw.status = UVM_NOT_OK;
    return;
  end
  rw.kind  = tr.write ? UVM_WRITE : UVM_READ;
  rw.addr  = tr.addr;
  rw.data  = tr.write ? tr.wdata : tr.rdata;
  rw.status= tr.slv_err ? UVM_NOT_OK : UVM_IS_OK;
  `uvm_info(
    "ADAPT_B2R",
    $sformatf("kind=%s addr=0x%0h data=0x%0h st=%s",
      tr.write?"W":"R", rw.addr, rw.data,
      (rw.status==UVM_IS_OK)?"OK":"ERR"),
    UVM_HIGH
  )
endfunction
diagram
[BUS] wrong-mapping triage ladder

  Step 1:
    issue one directed write/read to known register

  Step 2:
    inspect ADAPT_R2B log for intended addr/data/be

  Step 3:
    inspect monitor item and ADAPT_B2R decode

  Step 4:
    compare against register map expected absolute address
diagram
[UVM] map conversion gotchas

  byte-addressed map vs word-addressed bus
  little-endian vs big-endian lane ordering
  sub-map base offsets at block integration level
  mirrored test values masking lane swap errors
  • Use asymmetric test values (e.g. 0x12_34_56_78) to reveal lane swaps.

  • Check one sub-map edge register to catch base-offset mistakes.

  • Avoid broad randomization until directed mapping sanity passes.


Cast failures and response-path triage

bus2reg cast failures mean predictor received an unexpected type. Common causes: wrong monitor analysis port connected, mixed item polymorphism without adapter support, or incorrect predictor parameter type.

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

  // Correct predictor typing and connection are mandatory
  pred.map     = rm.default_map;
  pred.adapter = adapter;
  apb.mon.ap.connect(pred.bus_in);
endfunction

// Optional stronger cast diagnostics
virtual function void bus2reg(uvm_sequence_item bus_item, ref uvm_reg_bus_op rw);
  apb_item tr;
  if (!$cast(tr, bus_item)) begin
    `uvm_fatal(
      "ADAPT_CAST",
      $sformatf("Expected apb_item, got %s", bus_item.get_type_name())
    )
    return;
  end
  // ...normal decode...
endfunction
diagram
[UVM] cast-failure quick causes

  predictor typed with wrong item class
  monitor publishes wrapper item, adapter expects raw item
  wrong analysis port connected (e.g. response channel mismatch)
  factory override changed bus item subtype unexpectedly
diagram
[RAL] response triage decision tree

  read returns no data?
    |
    +-- provides_responses=1 ?
    |      |
    |      +-- yes: verify driver sends item_done(rsp) with rdata/status
    |      |
    |      +-- no: verify monitor->predictor path and bus2reg read-data decode
    |
    +-- check rw.status propagation for protocol errors

End-to-end debug playbook

  1. Run one deterministic register write/read on a known address.

  2. Enable adapter R2B/B2R logs at UVM_HIGH for that test only.

  3. Correlate sequencer item, driver activity, monitor item, and predictor decode.

  4. Check adapter knobs (byte_enable, responses) against bus-agent behavior.

  5. Re-run built-in reset/bit-bash/access sequences after fixes.

  6. Keep one adapter-smoke test in CI to lock regression safety.

Key takeaways

  • Adapter issues present as repeatable mapping, cast, or status patterns.

  • Instrument reg2bus and bus2reg symmetrically to localize translation defects.

  • Cast failures are usually connection/type mismatches, not random simulator noise.

  • A deterministic triage ladder resolves adapter bugs faster than ad-hoc debug.

Common pitfalls

  • Relying only on waveform debug without transaction-level adapter logs.

  • Downgrading cast failures to warnings and continuing with bad prediction data.

  • Changing multiple adapter knobs simultaneously during triage.

  • Declaring DUT bug before validating map+adapter+predictor alignment.