Skip to Content

RP1 Models

Relevant source files (branch fix/adapter-pid-readiness; not on main)

None of this exists on main. The models live on the stacked branches feat/rp1-pwm-model, feat/rp1-gpio-model, feat/rp1-rio-model, feat/rp1-pad-gating (all contained in fix/adapter-pid-readiness). They are isolated unit models: not installed in virt-pi5.repl, not attached through PCIe, and they qualify no guest driver.

Why C# and not RP2040 reuse

The spec planned to adapt Renode’s RP2040 models and write Python peripherals first. The Renode model audit (2026-10-01, Renode 1.16.1.16973) found:

CandidateFinding
RP1 / RP2040 / BCM2712 typesNo matching public types or platform entries among 1,234 enumerated Antmicro.Renode.Peripherals.* types
PCIeBasePeripheral, PCIeEndpoint, PCIeRootComplex, BAR classesPresent; candidates for endpoint plumbing, untested for BCM2712/RP1
MPFS_PCIeDifferent controller; cannot substitute
picosoc.replPicoRV32 CPU, not an RP2040 peripheral implementation
PL011 reserved offset 0x40Silently ignored with no log, so warning detection alone cannot prove strict coverage

TODO_NOW.md also notes that interconnect/PCIe modeling requires C# rather than request-based Python peripherals. Both RP1 models are therefore C# and validate every access themselves.

Common strictness rules

  • Only aligned 32-bit accesses. Byte, word, and quadword interfaces are implemented explicitly to throw, so the bus cannot silently translate them.
  • Unsupported offsets, aliases, bits, or control combinations log an Error (RP1_GPIO_UNSUPPORTED / RP1_PWM_UNSUPPORTED) and throw before mutating state.
  • State changes stream to the log as RP1_GPIO_STATE / RP1_PWM_STATE with sequence number and virtual timestamp. Capture sequence and unsupported-access counts survive reset.
  • With VOLN_VP_STRICT_MMIO=1, the Renode runtime adapter also fails on any retained native warning, including unmapped bus accesses. Model Error logs fail the adapter regardless of the flag.

RP1_GPIO: IO_BANK0, RIO and pads

RP1_GPIO(IMachine machine) models 28 pins and implements IGPIOReceiver. It exposes three connection regions: default (IO_BANK0), rio, and pads. Each supports atomic alias windows at +0x1000 (XOR), +0x2000 (SET), +0x3000 (CLEAR); alias reads do not mutate.

RegisterOffsetModeled behavior
STATUS8*pinRead-only: input bit 17, peripheral out/oe bits 8/12, effective out/oe bits 9/13, event bits 20-23, combined IRQ bits 28/29
CTRL8*pin+4Reset 0x9f; FUNCSEL 5 (GPIO/RIO) and 31 (NULL) only; OUTOVER/OEOVER; event masks; self-clearing IRQRESET bit 28
INTR0x100Per-pin bitmap after event masks
PCIE_INTE0x11c28-bit destination enable
PCIE_INTS0x124INTR & PCIE_INTE; any bit asserts the Renode IRQ line
RIO OUT / OErio 0x00 / 0x04GPIO0-27 output source when FUNCSEL is 5; reset to zero as an explicit unit preset
Padpads 4 + 4*pinBits 7:0 stored; OD (bit 7) gates output drive; IE (bit 6) gates input sampling; reset 0x9a (GPIO0-8), 0x96 (GPIO9-27)

Behavioral policies:

  • OnGPIO(pin, value) supplies an external digital level, gated by IE. Edges latch independently of masks; repeated values create no edge.
  • IE clear samples low. Toggling IE resamples a held external level, so enabling IE while high latches a rising edge. This is a documented unit-test policy, not validated hardware timing.
  • Outputs never loop back into inputs. Drive strength, pulls, Schmitt and slew bits are readback only; no analog behavior.
  • RIO SYNC_IN and other RIO inputs, alternate peripheral muxing, F_M changes, filtered/debounced events, INOVER/IRQOVER, VOLTAGE_SELECT, and PCIE_INTF are rejected.

RP1_PWM

RP1_PWM(IMachine machine, long frequency) models four channels with an explicit, positive clock frequency.

RegisterOffsetBehavior
GLOBAL_CTRL0x00Channel enable bits 0-3; SET_UPDATE bit 31
Channel CTRL0x14 + 0x10*nReset 0x100; modes constant-zero and trailing-edge, optional inversion; FIFO_POP_MASK retained but inert
Channel RANGE0x18 + 0x10*nPeriod in clock ticks
Channel DUTY0x20 + 0x10*nHigh-time ticks

Timing policy (deterministic, not measured silicon):

  • SET_UPDATE applies the latest control/enables one model clock period after the first pending trigger; later writes do not postpone it.
  • RANGE/DUTY are staged and apply at the channel’s next overflow; starting a stopped channel consumes the staged values immediately.
  • Zero-range trailing-edge activation is rejected.
  • Output is classified as disabled, low, high, or pwm. Individual pulse edges are not emitted.

Phase, common/FIFO, interrupt, DMA, and sigma-delta registers are unsupported.

Running the native tests

These run directly through renode-test with Renode’s own Python environment; they are separate from hosted CI, which uses stand-in emulators.

timeout --kill-after=2s 60s renode-test --jobs=1 \ --keep-renode-output --save-logs always --results-dir /tmp/rp1-gpio-unit \ --variable MODEL_FILE:"$PWD/backends/renode/peripherals/RP1_GPIO.cs" \ backends/renode/tests/rp1-gpio.robot \ backends/renode/tests/rp1-gpio-invalid.robot timeout --kill-after=2s 60s renode-test --jobs=1 \ --keep-renode-output --save-logs always --results-dir /tmp/rp1-pwm-unit \ --variable MODEL_FILE:"$PWD/backends/renode/peripherals/RP1_PWM.cs" \ backends/renode/tests/rp1-pwm.robot \ backends/renode/tests/rp1-pwm-invalid.robot

The GPIO fixture maps IO_BANK0 at 0x10000, RIO at 0x20000, and pads at 0x30000 via BusMultiRegistration; these are test addresses, not the Pi map. The invalid suites expect exceptions, so their Robot assertions pass while their Error logs must fail an adapter run.

Recorded results

Model revisionNative testsProbe
PWM12 pass2026-10-01-rp1-pwm-model.md
GPIO (IO_BANK0 + IRQ)9 pass2026-10-01-rp1-gpio-model.md
GPIO + RIO15 pass2026-10-01-rp1-rio-model.md
GPIO + RIO + pads21 pass2026-10-01-rp1-pad-gating.md

Each probe also ran the real Renode runtime adapter with VOLN_VP_STRICT_MMIO=1 for a positive suite (exit 0), the invalid suite (exit 1, model Error logs), and a deliberately wrong assertion (exit 1). All results recorded qualification_claims: [].

Still open

PCIe root complex and RP1 endpoint, MSI-X/MIP delivery, RP1 clocks, PWM-to-pad muxing, installation into virt-pi5, and any guest-driver execution. See RP1 Driver Coverage.

Last updated on