UVM RAL · Chapter 11 · Debugging RAL
Prediction Error Debug
A mirror mismatch is what you observe, and a prediction error is one of its most important causes. Prediction is the mechanism that keeps the model mirror in step with the real design, so when it breaks it rarely breaks for just one register. It breaks for many at once, because the shared update pipeline itself is broken. That breadth is the diagnostic signature: when lots of registers are wrong, suspect the prediction path, not any single register. The prediction path is a chain from bus activity to the monitor, then to the predictor, the adapter's bus2reg, the map, and finally the mirror. Common break points include a predictor never connected to the monitor, a bus2reg returning the wrong address, an address that misses the map, or auto and explicit prediction fighting. This lesson teaches tracing that chain and breaks a passive setup where nothing predicts, so every register drifts after the first write.
Foundation12 min readUVM RALdebuggingpredictionpredictoranalysis port
Chapter 11 · Section 11.2 · Debugging RAL
1. Why Should I Learn This?
When many registers mismatch at once, you are not looking at a register bug — you are looking at a broken prediction pipeline, and chasing individual registers wastes enormous time. Knowing that a prediction error is a broken link in a chain — and how to trace that chain from the monitor to the mirror to find the break — is what turns a board-wide 'everything is wrong' into a single-point fix.
Learning to debug prediction errors builds directly on the mirror-mismatch method (11.1) — it is the cause class behind the broadest mismatches — and on the prediction mechanics of Chapter 6, turned into a diagnostic path-trace.
2. Industry Story — every register wrong after the first write
A team stands up a passive register environment — the model's mirror is meant to be updated by a predictor watching bus traffic through a monitor (explicit prediction, 6.x). They run a test, and almost every register mismatches after the first write. The sheer breadth is bewildering — surely not every register is broken — so they start checking registers one by one, finding each individually fine.
The breadth was the clue they missed. Because so many registers were wrong together, the failure was not in the registers but in the shared mechanism that updates them all — the prediction path. The predictor's analysis export had never been connected to the monitor's analysis port, so no bus traffic ever reached the predictor, and the mirror was never updated from the bus. It stayed frozen at reset, so the moment any register was written and read back, the read's value (the written data) mismatched the mirror's reset value — and this happened for every register, because none of them were being predicted. One missing connect call broke the update pipeline for the whole model. Once the analysis port was connected, the predictor received traffic, the mirror tracked, and all the mismatches vanished at once. The post-mortem lesson: a prediction error breaks the shared update pipeline, so it makes many registers drift together — that breadth is the diagnostic signature that points at the prediction path, not any register; trace the chain (monitor -> predictor -> bus2reg -> map -> mirror) to the broken link, and a whole-model mismatch is usually one broken connection (an unconnected predictor), not many broken registers.
3. Concept — trace the prediction chain to the broken link
Prediction keeps the mirror in step; a prediction error is a broken link in the chain that does it. The method is to trace the chain and find where it breaks:
- The chain: bus activity -> monitor (observes transactions) -> analysis port -> predictor ->
adapter.bus2reg(transaction -> register op) -> map (address -> register) -> model mirror updated. - Break points and their symptoms:
- Predictor not connected to the monitor's analysis port -> nothing predicts -> mirror never updates from bus traffic (explicit/passive envs) -> frozen at reset -> every register mismatches. Signature: whole-model breadth.
bus2regwrong (wrong address/data/rw returned) -> predictor updates the wrong register or with wrong data (11.3).- Address not in the map -> predictor cannot find the register -> silently predicts nothing for the affected accesses.
- Auto + explicit both enabled -> the two predictors fight (double prediction), corrupting the mirror.
- Breadth is the first clue. Many registers wrong together = the shared pipeline is broken (connection, or a systemic bus2reg/config error). One register wrong = a modelling gap (11.1). Let breadth pick the layer.
Here is the prediction data path, with the connection that most often breaks highlighted:
4. Mental Model — a prediction error is a broken conveyor belt, and breadth locates it
5. Working Example — connecting the predictor and tracing the path
Wire the prediction path correctly, and know how to trace it when the mirror does not update:
// The prediction path in an explicit/passive environment: the predictor MUST be connected to the
// monitor's analysis port, and given the map + adapter. This is the belt's starting connection.
class my_env extends uvm_env;
uvm_reg_predictor#(bus_item) predictor;
my_monitor mon;
my_adapter adapter;
virtual function void connect_phase(uvm_phase phase);
predictor.map = reg_model.default_map; // map: address -> register
predictor.adapter = adapter; // bus2reg: transaction -> register op
mon.ap.connect(predictor.bus_in); // <-- THE CONNECTION: monitor traffic -> predictor
// Miss this connect, and NO bus traffic predicts -> mirror frozen -> whole-model mismatch.
endfunction
endclass// TRACE the path when the mirror does not update. Breadth first, then link by link:
// 1. Breadth? MANY registers wrong -> pipeline, not a register. (One register -> 11.1 modelling.)
// 2. Is the predictor CONNECTED? Is mon.ap.connect(predictor.bus_in) present and reached?
// 3. Is bus2reg returning the right register op? (log addr/data/rw it decodes -> 11.3 if wrong)
// 4. Does the address resolve in the MAP? (an address not in the map predicts nothing, silently)
// 5. Are BOTH auto and explicit prediction on? (they fight -> corruption)// A quick probe: is the predictor receiving ANYTHING? Instrument its write() (or bus_in) to log traffic.
// If it logs NOTHING while the bus is active -> the analysis port is not connected (the belt is off).
// If it logs traffic but the mirror is still wrong -> the break is downstream (bus2reg / map).Connecting the predictor to the monitor is the belt's start; tracing the chain link by link — connected? right op? address found? — localizes any break. The next section is the most common one: the belt never connected.
6. Debugging Session — an unconnected predictor freezing the whole mirror
An unconnected predictor means no bus traffic predicts, so the mirror is frozen at reset and every register mismatches after the first write — the breadth points at the pipeline, not the registers
CONNECT THE PREDICTOR// The predictor is created and configured, but its analysis input is NEVER connected to the monitor:
virtual function void connect_phase(uvm_phase phase);
predictor.map = reg_model.default_map;
predictor.adapter = adapter;
// BUG: missing mon.ap.connect(predictor.bus_in);
// No bus traffic ever reaches the predictor -> the mirror is NEVER updated from the bus.
endfunction
// The mirror stays frozen at RESET. Every register written then read mismatches (read=written, mirror=reset).Almost every register mismatches after the first write — an alarming, board-wide 'everything is wrong.' Checking registers one by one finds each individually fine, which deepens the confusion: how can every register be broken? The mismatches all have the same shape — the read returns the written value while the mirror holds the reset value — because the mirror never moved off reset. The breadth (whole-model) and the uniform shape (mirror stuck at reset) are the signature, but they only make sense once you stop looking at registers and look at the update mechanism.
Applying the method: the breadth — many registers wrong together — immediately says this is the shared prediction pipeline, not any register (a register modelling gap would affect one register, 11.1). Tracing the chain from the start: the predictor's analysis input (predictor.bus_in) was never connected to the monitor's analysis port (mon.ap), so no bus traffic ever reached the predictor. With nothing feeding it, the predictor never updated the mirror from the bus, and the mirror stayed frozen at its reset values. Consequently, every register that gets written (changing the DUT) and read back returns the written value, which mismatches the mirror's reset value — and this happens for every register, because none are being predicted. The single missing connect call broke the update pipeline for the entire model. Instrumenting the predictor would show it receiving nothing while the bus is active — the definitive sign the analysis port is not connected. It is not many register bugs; it is one broken link at the start of the shared chain.
Connect the predictor to the monitor's analysis port: mon.ap.connect(predictor.bus_in) in connect_phase, so bus traffic reaches the predictor and the mirror is updated from every observed access — after which all the mismatches vanish together. The method the debug teaches: a prediction error breaks the shared update pipeline, so it makes many registers drift together — let that breadth point you at the prediction path rather than the registers, then trace the chain (monitor connected? -> bus2reg right op? -> address in map? -> auto/explicit not fighting?) to the broken link. The most common break is the most basic — an unconnected predictor — and the tell is the predictor receiving no traffic while the bus is active, with the mirror frozen at reset and every register mismatching after the first write. Breadth is the diagnosis: whole-model mismatch is a pipeline break, not a register bug.
7. Common Mistakes
- Debugging registers one by one when many are wrong. Breadth says the pipeline is broken — trace the prediction chain, not the registers.
- Forgetting to connect the predictor. No
mon.ap.connect(predictor.bus_in)means no traffic predicts and the mirror freezes at reset (whole-model mismatch). - Not configuring the predictor's map/adapter. The predictor needs the map (address -> register) and adapter (
bus2reg) to update the right register with the right data. - Enabling both auto and explicit prediction. They fight and corrupt the mirror — pick one prediction mode (6.x).
- Ignoring the mismatch shape. 'Read = written, mirror = reset' across the board is the frozen-mirror signature of an unconnected predictor.
8. Industry Best Practices
- Let breadth choose the layer. Many registers wrong = prediction pipeline; one register wrong = modelling gap (11.1).
- Trace the prediction chain to the break. Monitor connected? -> bus2reg right op? -> address in map? -> single prediction mode? — find the broken link.
- Wire the predictor completely. Connect its analysis input to the monitor and set its map and adapter, in
connect_phase. - Probe whether the predictor receives traffic. No traffic while the bus is active = an unconnected analysis port; traffic but wrong mirror = a downstream break (bus2reg/map).
- Use one prediction mode. Auto or explicit, not both — two predictors fighting corrupt the mirror (6.x).
9. Interview / Review Questions
10. Key Takeaways
- A prediction error is a broken link in the update pipeline that keeps the mirror in step (6.x) — and because that pipeline is shared, it makes many registers drift together, unlike a single-register modelling gap (11.1).
- Breadth is the first clue: many registers wrong together = the prediction pipeline (connection/
bus2reg/config); one register wrong = a modelling gap (11.1) — let breadth pick the layer. - Trace the chain to the break: bus -> monitor -> analysis port (connected?) -> predictor ->
bus2reg(right op?) -> map (address found?) -> mirror — match the symptom to the link. - The most common break is the most basic: an unconnected predictor (
mon.ap.connect(predictor.bus_in)missing) — no traffic predicts, the mirror is frozen at reset, and every register mismatches after the first write (read = written, mirror = reset). - Wire the predictor completely (analysis input connected, map + adapter set), use one prediction mode (auto or explicit, not both), and probe whether the predictor receives traffic — none while the bus is active means the analysis port is not connected.