cpu/cyclonev_hps: Add Intel Cyclone V HPS (hard dual Cortex-A9) support - #2496
Merged
Conversation
This was referenced Jul 6, 2026
…ore. Add the Cyclone V HPS as a hardcore CPU (similar to Zynq7000/ZynqMP): - H2F LW AXI3 master used as LiteX peripheral bus, with the bridge's window-relative addresses extended to ARM physical addresses so that the LiteX memory map matches the ARM's view (CSRs at 0xff20_0000). - Optional H2F AXI3 master (0xc000_0000, 960MB window) through add_axi_h2f_master() and F2H AXI3 slave through add_axi_f2h_slave() for Fabric -> HPS DDR3/peripherals accesses. - F2H interrupts (32 IRQs) and Clocks/Resets/Trace/Boot tie-offs. The HPS is integrated through direct cyclonev_hps_interface_* atom instantiation (no Qsys/Platform Designer), targeting boards where the HPS is pre-booted from SD-Card (e.g. MiSTer/DE10-Nano) and where only the Fabric-side bridge interfaces are then required. Unused H2F/F2H bridges are explicitly instantiated with port_size_config=unused, as done by MiSTer.
Similar to Zynq7000 but self-contained (no external BSP): - system.h: UART redirected to HPS UART0 (16550 at 0xffc02000, already configured by the Preloader/U-Boot), cache flush stubs. - irq.h: Stubs (GIC support will be added later if needed). - boot-helper.c: Simple jump to address. - crt0.S: Empty (BIOS is only compiled/linked when the target adds rom/sram regions in HPS DDR3, as on Zynq targets).
Hardcore CPU: can't be simulated in the CI boot tests (as Zynq7000/ ZynqMP/EOS-S3).
Wishbone Slave to Avalon-MM Master bridge (Classic single-beat accesses), complementing the existing AvalonMM2Wishbone bridge. Useful to connect Avalon-MM Slaves (ex Cyclone V HPS F2SDRAM ports) to the LiteX bus. Add simulation coverage against an Avalon-MM RAM model (32/64-bit, base address translation, wait-states, pipelined read latency).
Add add_fpga2sdram_port() providing direct Avalon-MM ports to the HPS SDRAM Controller (higher bandwidth than the F2H bridge). The port layout is fixed (Port 0: 128-bit, Ports 1/2: 64-bit) since it has to match the configuration applied by the Preloader/U-Boot (applycfg), here MiSTer's one; the atom configuration/wiring replicates MiSTer's generated sys framework. The fpga2sdram atom is only instantiated when at least one port is used; unused ports are tied-off (Clks driven, commands disabled).
Replace the irq.h stubs and empty crt0.S with a functional (hardware
still to be validated) bare-metal interrupt path for the BIOS when
launched from the Preloader/U-Boot (ex go 0x01000000):
- crt0.S: Cortex-A9 startup with exception vectors placed at the image
start (VBAR, 32-byte aligned), VFP/NEON enable (BIOS is built
hard-float), IRQ mode stack, .data copy/.bss clear and an IRQ
trampoline (AAPCS caller-saved registers + SPSR save/restore) calling
isr().
- irq.h: GIC-390 (Distributor at 0xfffed000, CPU Interface at
0xfffec100) implementation of irq_getie/setie/getmask/setmask/
pending; the 32-bit LiteX interrupt mask maps to the F2H IRQs (GIC
IDs 72-103), other GIC IDs (HPS peripherals) are not disturbed;
irq_setie(1) routes the F2H IRQs to CPU0 and enables the Distributor/
CPU Interface (hooked to the BIOS irq_setmask(0)/irq_setie(1) init).
- libbase/isr.c: cyclonev_hps ISR with GIC IAR/EOIR claim-based
dispatch to the common interrupt table (F2H IRQ0 <-> LiteX IRQ0).
- core.py: add -D__cyclonev_hps__ to gcc_flags (used by isr.c).
Verified by building the BIOS with arm-none-eabi-gcc and inspecting
the disassembly: vectors at rom base/entry point (0x01000000), GIC
Distributor/CPU Interface accesses (ITARGETSR 0xfffed848-64, PMR,
CTLRs) inlined in main(), exception return sequence (ldm sp!, {..}^).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR adds Intel Cyclone V HPS support as a hardcore CPU (
--cpu-type=cyclonev_hps), similar to what is already done for Zynq7000/ZynqMP, targeting boards where the HPS is pre-booted from SD-Card (e.g. MiSTer/DE10-Nano) and where only the Fabric-side bridge interfaces are then required.Integration:
0xff20_0000, directly usable from the HPS withdevmem//dev/mem).0xc000_0000, 960MB window) viaadd_axi_h2f_master()and F2H AXI3 slave viaadd_axi_f2h_slave()for Fabric -> HPS DDR3/peripherals accesses.add_fpga2sdram_port()for direct (higher bandwidth) Fabric -> HPS SDRAM Controller accesses; the port layout is fixed (Port 0: 128-bit, Ports 1/2: 64-bit) to match the configuration applied by MiSTer's Preloader/U-Boot.interconnect/avalonWishbone2AvalonMMbridge (with simulation coverage) to connect the F2SDRAM Avalon-MM ports to the LiteX bus.go 0x01000000): Cortex-A9crt0.Swith exception vectors at the image start (VBAR), VFP enable, IRQ-mode stack and AAPCS IRQ trampoline; GIC-390irq.h(the 32-bit LiteX interrupt mask maps to the F2H IRQs / GIC IDs 72-103 without disturbing other IDs); IAR/EOIR claim-based ISR dispatch inlibbase/isr.c.Implementation notes:
cyclonev_hps_interface_*atom instantiation (no Qsys/Platform Designer). Port lists were taken from Quartus's WYSIWYG component library and cross-checked against MiSTer's sys framework (which instantiates the same atoms directly); the F2SDRAM atom configuration/wiring replicates MiSTer's generated sys framework.port_size_config=unused, as done by MiSTer; the F2SDRAM atom is only instantiated when at least one port is used.dbg_apbtie-off atom used by MiSTer (Quartus 17) is not instantiated: it is no longer present in recent Quartus releases (23.1) and is not required.Tested:
.rbfproduced; BIOS compiles witharm-none-eabi-gcc.Wishbone2AvalonMMsimulation test (32/64-bit, base address translation, wait-states, pipelined read latency).arm-none-eabi-gccand inspecting the disassembly: vectors at rom base/entry point (0x01000000), GIC Distributor/CPU Interface accesses (ITARGETSR/PMR/CTLRs) inlined inmain()throughirq_setie(1), exception return sequence — runtime behavior still to be validated on hardware.devmem, SDRAM access at0xc000_0000through the H2F bridge, HPS DDR3 access at0xd000_0000through F2SDRAM).Companion PRs: litex-hub/litex-boards#746 (DE10-Nano target), #2497 (
litex_server --devmemfor remote litex_cli/litescope accesses from the HPS).Possible follow-ups: Qsys backend for standalone (non pre-booted) boards.