Part 9 · Register Model (RAL) · Intermediate
uvm_reg_predictor Wiring
How monitor transactions flow through adapter bus2reg into uvm_reg_predictor and update the register map mirror for reliable checks.
Signal path: monitor -> predictor -> map
Explicit prediction is the robust frontdoor architecture. The monitor observes bus traffic, predictor converts bus item to reg operation using adapter, then map updates mirror.
[UVM] predictor wiring diagram
[BUS AGENT]
monitor.ap -------------------------------> predictor.bus_in
│
│ uses adapter.bus2reg()
▼
uvm_reg_bus_op
│
▼
predictor.map
│
▼
[RAL] mirrored value update
Required assignments:
predictor.map = reg_model.default_map;
predictor.adapter = bus_adapter;
monitor.ap.connect(predictor.bus_in);[CHECK] what each block owns
monitor:
passive observation of real bus traffic
adapter.bus2reg:
protocol item -> canonical uvm_reg_bus_op fields (kind/addr/data/status)
predictor:
finds matching reg/field via map, calls predict semantics
map:
address decoding context and access path metadataReference environment wiring (SystemVerilog)
The connect code below is the production baseline for frontdoor RAL usage. Keep auto_predict off when explicit predictor is present.
class reg_env extends uvm_env;
`uvm_component_utils(reg_env)
apb_agent apb;
my_reg_block reg_model;
apb_reg_adapter adapter;
uvm_reg_predictor #(apb_item) predictor;
function void build_phase(uvm_phase phase);
super.build_phase(phase);
apb = apb_agent::type_id::create("apb", this);
adapter = apb_reg_adapter::type_id::create("adapter");
predictor = uvm_reg_predictor#(apb_item)::type_id::create("predictor", this);
reg_model = my_reg_block::type_id::create("reg_model");
reg_model.build();
reg_model.lock_model();
endfunction
function void connect_phase(uvm_phase phase);
super.connect_phase(phase);
// Frontdoor path for register API calls.
reg_model.default_map.set_sequencer(apb.sqr, adapter);
// Use monitor-based explicit prediction.
reg_model.default_map.set_auto_predict(0);
predictor.map = reg_model.default_map;
predictor.adapter = adapter;
apb.mon.ap.connect(predictor.bus_in);
endfunction
endclassReadability conventions
Set sequencer/adapter and predictor wiring in the same connect block.
Keep `set_auto_predict(0)` adjacent to predictor assignments to avoid split-brain behavior.
Name predictor instance clearly (`reg_predictor` or `predictor`) for grep-friendly debug.
Adapter contract for prediction correctness
Prediction quality depends on bus2reg correctness. Address, kind, data, and status must represent observed transfer semantics exactly.
class apb_reg_adapter extends uvm_reg_adapter;
`uvm_object_utils(apb_reg_adapter)
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 t = apb_item::type_id::create("t");
t.addr = rw.addr;
t.data = rw.data;
t.write = (rw.kind == UVM_WRITE);
return t;
endfunction
virtual function void bus2reg(uvm_sequence_item bus_item, ref uvm_reg_bus_op rw);
apb_item t;
if (!$cast(t, bus_item)) begin
rw.status = UVM_NOT_OK;
return;
end
rw.kind = t.write ? UVM_WRITE : UVM_READ;
rw.addr = t.addr;
rw.data = t.data;
rw.status = UVM_IS_OK;
endfunction
endclass[RAL] adapter mistakes and observed symptoms
bus2reg addr wrong:
mirror updates a different register than bus target
bus2reg kind swapped (read/write):
side-effect modeling and compare semantics collapse
rw.status never set UVM_IS_OK:
predictor may skip effective mirror update
byte-lane/endianness mismodel:
recurring bit-slice mismatches in mirror checksAdvanced wiring: multi-map and shared buses
SoC environments often have multiple maps or non-RAL traffic on the same monitor stream. Prediction still works if routing/filtering is explicit.
[UVM] multi-map considerations
Scenario:
one physical bus monitor carries:
- RAL-mapped CSR traffic
- non-CSR DMA/descriptor traffic
Strategy:
- filter monitor items before predictor when possible
- or let bus2reg tag unsupported transactions with UVM_NOT_OK
- ensure predictor.map matches address space for target block
- create one predictor per map when address regions overlap logicallyclass csr_filter_subscriber extends uvm_subscriber #(apb_item);
`uvm_component_utils(csr_filter_subscriber)
uvm_analysis_port #(apb_item) csr_ap;
function new(string name, uvm_component parent);
super.new(name, parent);
csr_ap = new("csr_ap", this);
endfunction
virtual function void write(apb_item t);
if ((t.addr >= 'h0000) && (t.addr < 'h1000))
csr_ap.write(t);
endfunction
endclass
// connect_phase idea:
// apb.mon.ap -> filter.analysis_export
// filter.csr_ap -> predictor.bus_inKey takeaways
Explicit predictor wiring is the default-safe architecture for frontdoor RAL.
Correct adapter bus2reg mapping is mandatory for trustworthy mirror state.
Keep auto_predict disabled when explicit predictor consumes monitor traffic.
In mixed-traffic systems, filter or map-route transactions intentionally.
Common pitfalls
Connecting predictor but forgetting to assign map or adapter.
Leaving auto_predict enabled alongside explicit prediction without intent.
Feeding predictor unrelated transactions and blaming random mirror drift.