Skip to content

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

8 Commits

Folders and files

Repository files navigation

APMU Software

Bare-metal software for the case studies in our EMSOFT 2026 paper, "A Centralized Performance Monitoring Architecture for Heterogeneous Multicore SoCs." These programs run on the he-soc SoC — a quad-core CVA6 platform extended with our APMU / EVU / SPU monitoring infrastructure — on a Xilinx VCU118 board, and were used to produce the paper's results.

Artifact evaluation (EMSOFT 2026). Active development of this artifact continues in this GitHub repository: https://github.com/Rodolfo-Pellizzoni-Lab/apmu-software.

Folder Experiment
mempol/ Memory-bandwidth policing: the APMU core interrupts and halts a CVA6 core when it exceeds its bandwidth budget, and resumes it when the budget refills
sad_profile/ EVU PC-milestone profiling of function entry & exit: per-call cycle/event profiles of padarray4 inside the SD-VBS disparity (SAD) benchmark
evu_test/ Self-checking EVU smoke test (core 0 only, ~6 ms of simulated time): PC-track milestones on a small function, counted by APMU counters 20/21 and logged by the sad_profile firmware; exit code 0 = PASS

Each experiment's main code is in the following files:

APMU: pmu_firmware/main.c, RV32IM C compiled for the Ibex PMU core. CVA6 side: pmu_bench.c, RV64 bare-metal program for the CVA6 cores.

They compile together as one binary: the firmware is compiled first, its .text/.data are turned into raw bins, and pmu_text_wrapper.S / pmu_data_wrapper.S embed them (.incbin) into the CVA6 ELF. At boot the CVA6 program copies the firmware into the APMU's ISPM (0x10427000) and DSPM (0x10428000).

Prerequisites

  • RV64 bare-metal toolchain (riscv64-unknown-elf-gcc) for the CVA6 side.
  • RV32 bare-metal toolchain (riscv32-unknown-elf-gcc, zicsr support) for the Ibex firmware.
  • python3 (sad_profile's two-pass address extraction).

Both toolchains are picked up from PATH: override with RISCV_PREFIX= (RV64 side) and RV32_PREFIX= (firmware) on the make command line if yours live elsewhere.

Building

mempol

cd mempol
make clean
make pmu_bench fpga=1

Produces pmu_bench.riscv

sad_profile

cd sad_profile
make clean
make two-pass fpga=1

Running on the FPGA

Load pmu_bench.riscv over JTAG and run hart 0 — e.g. with OpenOCD and GDB:

(gdb) target extended-remote :<openocd-port>
(gdb) monitor reset halt
(gdb) load pmu_bench.riscv
(gdb) continue

Then watch the serial console:

picocom -b 115200 --imap lfcrlf /dev/ttyUSB1

Both programs set the UART to 115200 baud (50 MHz UART clock). Multi-hart bring-up is done inside pmu_bench.c.


Experiment 1: mempol/: Mempol-style bandwidth policing with halt interrupts

The APMU firmware runs a token-bucket regulator over the CVA6 cores' memory traffic. When a core spends its budget, the APMU pauses it by injecting an interrupt; when the bucket refills, it injects another interupt to trigger resume.

Experiment 2: sad_profile/: EVU function entry/exit profiling

Per-call profiling of padarray4 (one of the disparity/SAD kernel functions) without instrumenting the benchmark: the EVU watches the CVA6 commit PC, and the APMU firmware records cycles and event counts between each entry and exit.

Profiling a different function

  1. Edit extract_addrs.py / the DYNAMIC_PROFILE_FUNC_* defines in pmu_bench.c to point at the new function (entry symbol + offset of its first ret from the disassembly).
  2. Rebuild with make two-pass fpga=1 — it re-extracts addresses and rebuilds the firmware to match.

Demo: running the three programs on the VCU118

From an alsaqr-software checkout (toolchains, OpenOCD, GDB and the bitstreams live there):

APMU=$(pwd)                       # this checkout, with the three programs built (fpga=1)
cd ~/alsaqr-software && source source.sh
make load_bitstream BITSTREAM=bitstreams/alsaqr_xilinx_50MHz.bit HW_TARGET=xilinx_tcf/Digilent/210308B3AC77
# wait ~30 s for DDR calibration; if the first attach fails with "IR capture error", run it again
./scripts/load.sh $APMU/evu_test/evu_test.riscv     --time 3000   --batch --serial-log evu.log
./scripts/load.sh $APMU/sad_profile/pmu_bench.riscv --time 60000  --batch --serial-log sad.log
./scripts/load.sh $APMU/mempol/pmu_bench.riscv      --time 120000 --batch --serial-log mempol.log

--serial-log records /dev/ttyUSB3 at 38400 (the UART is hardwired to that rate in the bitstream; the programs only set 8N1 and never touch the divisor). What to expect: === EVU TEST PASS ===; sad_profile prints 8 padarray4 calls per pass with milestone counters 20/21 at 8 and a per-call table, the interference pass several times slower; mempol prints the stage timings, the pause/resume interrupt counts and the mempol log as CSV. Reference results (50 MHz bitstream, 2026-09-18): sad_profile solo about 113k cycles per call, about 446k under interference; mempol about 900 pause/resume interrupts over 30 iterations.

EVU smoke test: evu_test/

A quick check that the CVA6 EVU, the APMU counters and the sad_profile firmware still work together, small enough for the he-soc xsim RTL simulation (about 6 ms of simulated time; on the board it runs in an instant). It arms PCTRACK0/1 on the entry and the first ret of evu_probe(), counts the milestone hits in counters 20/21, calls the function N_CALLS (16) times and checks the two counters and the firmware's per-call log against that number. The verdict goes to the UART and to tohost (exit code 0 = PASS).

cd evu_test
make clean
make two-pass                # or fpga=1 for the board; N_CALLS=<n> to change the call count

Firmware loading note (all three programs): the firmware image is copied into the ISPM with 32-bit word stores, and evu_test/sad_profile read it back and report mismatches. memcpy may finish an image whose size is not a multiple of 8 (the sad_profile firmware is 2292 bytes) with byte stores, and the ISPM/DSPM SRAMs index by byte address without honouring byte strobes, so those bytes land in the wrong entries: the last instruction of the firmware, the polling loop's back-edge, became j . and the firmware never logged a call. This was reproduced both in the he-soc xsim simulation and on the 50 MHz bitstream; the RTL fix belongs in ip_list/apmu/src/pmu_ispm.sv.

Per-call cycle counts from the polling firmware have a resolution of roughly one poll iteration (about 80 cycles, two AXI-Lite counter reads); calls shorter than that, or several calls within one iteration, are reported as the poll overhead. The milestone counters themselves are exact.

Artifact evaluation

This repository is part of the EMSOFT 2026 artifact (we apply for the Artifacts Available badge). The artifact-evaluation documents are under docs/:

License

The software we wrote for this artifact — the APMU firmware (*/pmu_firmware/), the CVA6-side harnesses (pmu_bench.c, pmu_test_func.c), the profiling glue, and the build scripts — is released under the MIT License (see LICENSE).

Vendored third-party components keep their own upstream licenses:

  • inc/ — PULP / AlSaqr platform drivers and headers, © ETH Zurich / University of Bologna, under the Apache License 2.0 (see the per-file headers).
  • sad_profile/sdvb/ — the SD-VBS (San Diego Vision Benchmark Suite) disparity kernel, © UC San Diego, under its original SD-VBS license.
  • The mempol/ policing firmware adapts the published mempol memory-bandwidth regulation approach; the implementation in this repository is our own.

Citation

If you use this software, please cite the paper:

@inproceedings{jafri2026centralized,
  author    = {Jafri, Mohammed Sajjad and Rahman, Abdur and Sarkar, Emon and Hassen, Mahdi and Thayyil, Gopishankar and Mani, Ashwin Krishna and Pellizzoni, Rodolfo},
  title     = {A Centralized Performance Monitoring Architecture for Heterogeneous Multicore SoCs},
  booktitle = {Proc. ACM SIGBED International Conference on Embedded Software (EMSOFT)},
  year      = {2026}
}

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages