FVP runtime contract
Validated combinations
Section titled “Validated combinations”| Subsystem | FVP model | CPU / NPU | Runtime engines | Memory modes |
|---|---|---|---|---|
| Corstone-300 | FVP_Corstone_SSE-300_Ethos-U55 |
Cortex-M55 / Ethos-U55 | LiteRT, heliaRT, heliaAOT | Shared_Sram |
| Corstone-300 | FVP_Corstone_SSE-300_Ethos-U65 |
Cortex-M55 / Ethos-U65 | LiteRT, heliaRT, heliaAOT (LiteRT and heliaRT run; heliaAOT is accepted but not yet run on it) | Shared_Sram |
| Corstone-320 | FVP_Corstone_SSE-320 |
Cortex-M85 / Ethos-U85 | LiteRT, heliaRT, heliaAOT | Sram_Only, Shared_Sram, Dedicated_Sram |
The platform’s NPU picks the model (helia_npu.fvp.resolve_fvp_target_profile);
fvp.subsystem only insists on a subsystem, and one that does not simulate the
platform’s NPU is refused. The Corstone-300 archive carries both of its models,
and the U65 model shares the U55 model’s memory map, timing adapters and
parameter names, so it differs only in the binary and the NPU the runner is
built for. Corstone-310 and 315 pair a Cortex-M85 with the same U55 and U65;
helx does not use them, since the Corstone-300 already runs both NPUs, and has
not been validated on them.
Unsupported combinations are rejected before CMake/FVP execution.
Per-segment PMU profiling is currently validated for LiteRT and heliaRT. The pipeline rejects heliaAOT per-segment requests rather than silently omitting the fenced measurement.
Placement contract
Section titled “Placement contract”Vela exposes two logical memory areas (the naming across Vela, the SoC, the PMU and the FVP adapters is in port_mapping.md). Platform memory names describe timing and energy; the FVP linker uses its physical SRAM and DDR regions.
| Mode | Model / constants | Tensor arena | Fast NPU cache |
|---|---|---|---|
Sram_Only |
AXI0 / SRAM | AXI0 / SRAM | none |
Shared_Sram |
AXI1 / FVP DDR | AXI0 / SRAM | none |
Dedicated_Sram |
AXI1 / FVP DDR | AXI1 / FVP DDR | AXI0 / SRAM |
For generic MRAM/PSRAM platforms, FVP DDR is a physical proxy. Platform timing-adapter and energy parameters model the selected memory technology; the simulator does not contain literal MRAM or PSRAM.
Corstone-300 is currently restricted to Shared_Sram because:
- Vela model/weights/command stream are safely loaded through the FVP DDR region.
- The TFLM tensor arena is placed in SRAM.
- Both C300 timing adapters are configured from platform-derived values.
Sram_Onlyinitialized-model loading andDedicated_Sramfast-cache allocation have not been validated.
heliaAOT placement
Section titled “heliaAOT placement”Externally bound heliaAOT constant arenas use network_model_sec and follow
the model/constant placement. Mutable arenas use .bss.tensor_arena and follow
the arena placement. Codegen tests assert these section annotations and exact
constant-blob sizes. LiteRT, heliaRT, and heliaAOT KWS executions have been
validated on C300; automated linker-map assertions remain future coverage.
The C300 smoke configuration uses apollo510_evb only as a Cortex-M55
heliaAOT generation and memory-planner proxy. The execution target, linker,
timing adapters, PMU counters, and result data are Corstone-300.
PMU profiles
Section titled “PMU profiles”The table below describes U85. U55/U65 default and
default_ext_rd_stall do not count EXT write beats. Missing counts stay
unknown, so those profiles cannot supply complete counter-based energy.
U85 SRAM stall events sum across AXI ports: event/NPU-active-cycle ratios
can exceed 100% and do not measure elapsed-time occupancy. See
Arm’s PMU event definitions.
defaults.fvp.pmu_profile selects which counter set the runner firmware programs and prints. The Ethos-U85 has eight event counters plus the cycle counter; NPU_ACTIVE, NPU_IDLE and the cycle count are always reported.
| Profile | Extra counters | Use |
|---|---|---|
default |
SRAM / EXT read and write data beats (four counters) | Energy estimation; every standard run |
ext_stall |
EXT read/write request-stall and write-beat-stall counters | Diagnosing port-1 (HBLRAM / PSRAM) back-pressure |
default_ext_rd_stall |
The default beat counters with EXT read-request-stalled instead of the EXT1 read split |
Energy plus one stall signal |
dv_align |
MAC_ACTIVE, MAC_STALLED_BY_IB, MAC_STALLED_BY_W_OR_ACC plus the four beat counters (Ethos-U85 only) |
Correlating against RTL testbench and FPGA (heliaPROFILER) captures, which report the same set |
port_stall |
MAC_ACTIVE, SRAM and EXT RD_STALL_LIMIT and RD_TRAN_REQ_STALLED, SRAM and EXT read beats (Ethos-U85 only) |
Locating where the NPU waits for memory, per port; the capture the RTL testbench and the FPGA used to find the HP stall. No write-beat counters, so the measured energy estimate is skipped for these runs |
sram_stall |
MAC_ACTIVE, SRAM read/write STALL_LIMIT and TRAN_REQ_STALLED, SRAM read/write beats (Ethos-U85 only) |
Read/write queue diagnostics in one eight-counter capture. EXT traffic is uncounted, so the measured energy estimate is skipped |
Queue counters indicate request pressure. Reads, writes and useful NPU work can overlap, so these counters are not additive lost time or a predicted speedup. The fitted write limit is a timing-model parameter, not proof of the physical queue depth. Keep normal inference results separate from the recompiled fenced run. Fenced captures with a reported PMU overflow are rejected before diagnostic tables or timelines are written. Legacy logs without an overflow flag remain readable, but do not establish that overflow was absent.
Each profile is a helia_npu.pmu.PmuProgram (ordered driver event per slot,
unit, printed label); helx writes render_c_header(program) into the build
directory and the runner compiles its counter table from it, so the firmware
and the host’s required_pmu_fields come from one definition.
The runner executes one shape of program: the dedicated cycle counter (CCNT,
ungated, 64-bit) is the total, slot 0 is NPU_ACTIVE, and the one derived
field NPU IDLE is CCNT minus slot 0. A program with another cycle source or
derived set, such as heliaPROFILER’s hpx_default_v1 (cycle count in an event
slot, nothing derived), or one that wants the CCNT gated, is available as data
but is refused by name before the runner build is configured
(helia_estimator.runtime.pmu_program; the config schema’s PmuProfile enum
rejects unknown names even earlier) and again by the preprocessor in
ethosu_profiler.h, which re-checks the cycle source, gating, width, slot 0
and derived-field count (the printed label is checked in Python only); no
idle field is synthesised and no other program is substituted.
How the counters are read is the consumer’s, not the program’s, and is
recorded per consumer as PmuProgram.acquisition. helx’s runner resets the
counters before each command-stream dispatch, sums the per-dispatch reads in
64-bit in firmware, and marks the capture overflowed if any counter (event
slot or CCNT) sets its overflow bit. heliaPROFILER’s firmware, as that tool
documents it, accumulates 32-bit per layer and checks overflow over its
selected event mask. Two captures are comparable only when they ran the same
program under the same acquisition (PmuProgram.comparable_with); equal
event lists alone do not make helx and heliaPROFILER numbers interchangeable.
The Vela system-config section a run compiles with is <soc id>_<mode> (atomiq110_ULP); it names the summary CSV and is recorded as vela.profile / vela.system_config in the bundle.
On the FVP the cycle counter is quantised (totals end in …068 because the simulator advances in 1,000-cycle steps around the measurement window); the event counters are exact.
Target-specific hardware
Section titled “Target-specific hardware”| Setting | Corstone-300 | Corstone-320 |
|---|---|---|
| NPU base | 0x48102000 |
0x50004000 |
| NPU IRQ | 56 | 16 |
| UART0 base | 0x49303000 |
0x48203000 |
| TA0 / TA1 | 0x48103000 / 0x48103200 |
0x50006000 / 0x50006800 |
| FVP NPU parameter | ethosu.num_macs |
mps4_board.subsystem.ethosu.num_macs |
Host communication
Section titled “Host communication”Production runs use UART0 redirected to a result file:
-C <board>.uart0.out_file=<path>-C <board>.uart0.unbuffered_output=1-C <board>.uart0.shutdown_on_eot=1-C <board>.uart0.shutdown_tag=EXITTHESIMThe firmware retarget sends human-readable results, EOT, and EXITTHESIM. The host applies the independent host_timeout_seconds wall-clock timeout, because FVP --simlimit limits simulated time rather than host elapsed time.
Alternatives:
uart0.out_file=-: useful for interactive debugging, but still UART transport.- Semihosting: possible, but requires a separate firmware retarget/link contract and is not currently validated.
- Iris/CADI: appropriate for debug, registers, and memory inspection; not used as the result channel.
- Telnet terminals: modeled UART endpoints; disabled for automated runs.
Standalone validation:
scripts/run_corstone300_uart_probe.shThis independently verifies UART output, EOT/tag termination, U55 driver initialization, and IRQ vector wiring.