Part 9 · Register Model (RAL) · Intermediate

RAL Overview Hub: Architecture, Build Flow, and Bus Integration

Hub - register model hierarchy, map addressing, generation strategy, build/lock lifecycle, nested submaps, and full TEST->map->adapter->bus data flow.

Overview

The UVM Register Abstraction Layer (RAL) gives tests a spec-level API for register and memory access. Instead of manually constructing bus items for every access, tests target named registers, fields, and memories while the model handles addressing, access policy semantics, endianness, and frontdoor/backdoor path selection.

This hub focuses on the object model and integration mechanics that make RAL reliable in large environments: block hierarchy, map construction, generation strategy, lifecycle ordering, and end-to-end prediction flow.

Sub-lessons in this topic

  1. uvm-reg-block-tree - blocks, registers, fields, memories hierarchy and ownership boundaries.

  2. uvm-reg-map-addressing - offsets, byte width, endianness, and disciplined add_reg usage.

  3. generated-vs-handwritten - generator workflows (IP-XACT/SystemRDL) and safe extension strategy.

  4. block-build-lock-model - configure(), build(), and lock_model() in correct execution order.

  5. nested-blocks-submaps - multi-block hierarchy and add_submap composition at subsystem/chip level.

  6. ral-data-flow-overview - TEST->map->adapter->bus->predictor->mirror pipeline walkthrough.

Big-picture architecture map

diagram
Legend: [UVM] [RAL] [BUS] [DUT]

                     test intent (by name)
 [UVM] test/seq  ───────────────────────────────────────────────┐
   ral.ctrl.enable.set(1)                                       │
   ral.ctrl.update(status)                                      │
                                                                ▼
 [RAL] reg tree (block/reg/field/mem) + map
   ├─ hierarchy models spec ownership
   ├─ access policy drives legal semantics
   └─ address map resolves absolute bus address
                │
                ▼
 [RAL] adapter boundary (reg2bus / bus2reg)
                │
                ▼
 [BUS] sequencer -> driver -> interface -> [DUT]
                │
                ▼
 [BUS] monitor -> predictor -> [RAL] mirror update
diagram
[UVM][RAL][BUS] topology with nested blocks

 chip_block [RAL]
   ├─ csr_subsystem [RAL]
   │    ├─ cfg_block [RAL]
   │    │    ├─ ctrl_reg [RAL]
   │    │    └─ stat_reg [RAL]
   │    └─ trace_mem [RAL]
   └─ dma_subsystem [RAL]
        ├─ ch0_block [RAL]
        └─ ch1_block [RAL]

 default_map (chip)
   ├─ add_submap(csr_map, 0x0000_0000)
   └─ add_submap(dma_map, 0x0001_0000)

 resolved path:
   [UVM] test writes ch1.ctrl -> [RAL] map resolves -> [BUS] driver sends packet
diagram
[UVM][RAL][BUS] lifecycle timeline (what must happen first)

 build_phase:
  1) create top block
  2) configure child regs/blocks
  3) build() registers and maps
  4) lock_model()

 connect_phase:
  5) map.set_sequencer(bus_sqr, adapter)
  6) predictor.map = default_map
  7) monitor.ap.connect(predictor.bus_in)

 run_phase:
  8) test performs read/write/mirror/update
  9) predictor keeps mirror aligned with observed [BUS] traffic

Key takeaways

  • RAL reliability comes from correct hierarchy, map construction, and data-flow wiring together, not in isolation.

  • Design hierarchy around ownership boundaries first; addresses and bus routing become easier to reason about.

  • Model lifecycle order matters: configure/build before lock_model, then connect sequencer+adapter+predictor.

  • Prediction closes the loop between [BUS] activity and [RAL] mirror correctness.

Common pitfalls

  • Treating map setup as a minor detail - bad offsets/endianness silently corrupt register accesses.

  • Skipping predictor wiring while depending on mirror checks - false mismatches and debug churn.

  • Mixing ownership levels inside one giant block - hard-to-maintain model and fragile submap integration.

  • Hand-editing generated classes instead of extension layers - regeneration wipes behavior.