Part 8 · Checking & Coverage · Intermediate

Multi-Master, Backdoor, and Predictor Debug

Multiple monitors on predictor, manual predict after backdoor, and debug checklist.

Multi-master environments

In a typical SoC, multiple bus masters touch the same register block — CPU, DMA, debug port, firmware. With explicit prediction, every master that performs register bus cycles must feed the predictor. Missing one master leaves the mirror stale for that master's writes.

diagram
Legend: [RAL] [UVM]

  MULTI-MASTER PREDICTOR WIRING

  cpu_agt.mon.ap  ──┐
                    ├──► predictor.bus_in ──► adapter.bus2reg() ──► mirror
  dma_agt.mon.ap  ──┤
                    │
  dbg_agt.mon.ap  ──┘

  All three monitors fan into the same predictor.bus_in analysis export.
  UVM analysis ports support many-to-one connections.

Multi-master wiring and backdoor predict

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

  reg_model.default_map.set_sequencer(cpu_agt.sqr, adapter);
  predictor.map     = reg_model.default_map;
  predictor.adapter = adapter;

  // Every master that touches registers must feed the predictor
  cpu_agt.mon.ap.connect(predictor.bus_in);
  dma_agt.mon.ap.connect(predictor.bus_in);
  dbg_agt.mon.ap.connect(predictor.bus_in);
endfunction

// Backdoor access bypasses the bus — manual predict required
task backdoor_set_ctrl(bit [31:0] val);
  reg_model.ctrl_reg.write(..., .path(UVM_BACKDOOR), .status(status), .value(val));
  // Mirror NOT updated by backdoor write — predict manually:
  void'(reg_model.ctrl_reg.predict(val));
endtask

// HDL force also bypasses bus
task force_status_reg(bit [31:0] val);
  uvm_hdl_deposit("tb.dut.status_reg", val);
  void'(reg_model.status_reg.predict(val));
endtask

Debug checklist and common failures

Systematic debug steps

  1. Confirm set_auto_predict(0) — print reg_model.get_auto_predict() in build_phase.

  2. Frontdoor write then mirror(UVM_CHECK) — does mirror match readback?

  3. Print bus2reg output for a known APB transaction — addr offset correct?

  4. Verify monitor emits complete transactions — PSEL high through PREADY?

  5. Check adapter.base_addr against system memory map documentation.

  6. Confirm predictor.bus_in connected to monitor.ap, not driver port.

  7. For multi-master: verify every master's monitor is connected to predictor.

  8. After backdoor write: confirm manual predict() was called.

diagram
PREDICTOR DEBUG DECISION TREE [RAL]

  mirror(UVM_CHECK) fails
       │
       ├─ auto_predict == 1 and no external master?
       │     └─ Should pass — check addr map alignment
       │
       ├─ auto_predict == 0?
       │     ├─ predictor wired? ──NO──► connect monitor.ap  predictor.bus_in
       │     └─ YES
       │           ├─ bus2reg addr correct? ──NO──► fix adapter.base_addr
       │           └─ YES
       │                 ├─ monitor sees transaction? ──NO──► check monitor filters
       │                 └─ YES
       │                       ├─ backdoor access? ──YES──► add manual predict()
       │                       └─ external master not connected? ──► wire its monitor

Common failure signatures

  • Mirror always 0 after frontdoor write — predictor not wired or auto_predict(0) without predictor.

  • Mirror correct for CPU writes, wrong for DMA — DMA monitor not connected to predictor.

  • Intermittent mirror mismatch — double predict (auto_predict + predictor both active).

  • Mirror updates to wrong register — adapter base_addr mismatch.

  • Mirror stuck after backdoor test — forgot manual predict() after UVM_BACKDOOR write.

Key takeaways

  • All bus masters that touch registers should feed predictor or manual predict.

  • Backdoor and HDL force always require explicit reg.predict(value).

  • Use bus2reg debug print as the first step in any mirror mismatch triage.

Common pitfalls

  • Predictor on driver — mirror never updates from real bus traffic.

  • Implicit + explicit both on — corrupted mirror with intermittent failures.

  • Only CPU monitor wired — DMA/debug master writes leave mirror stale.

  • Forgetting predict() after backdoor — mirror check fails on next frontdoor read.