Skip to content
 
 

Repository files navigation

Status, all against real hardware:

  • Linux — fully tested. Build, flash, and remote reboot-to-bootloader all confirmed working.
  • Windows — fully tested. Build, flash, and remote reboot-to-bootloader all confirmed working.
  • macOS — fully tested. Build, flash, and remote reboot-to-bootloader all confirmed working, on Apple silicon. No driver or permission setup is needed for any of it.

Installation

Step-by-step instructions for each platform, using that platform's standard package manager so there's nothing to download by hand:

  • Windows — PowerShell and winget
  • Linuxapt (with notes for Fedora and Arch)
  • macOS — Homebrew

About this fork

This is a fork of FPGAwars/apio, maintained for use in a logic design class. The one substantive change from upstream is a new pico target (below); everything else about apio — commands, project files, the ICE40/ECP5/GOWIN/Xilinx architectures — is unmodified.

The motivation: the class previously required an upduino3.1 FPGA board. To cut costs for students, this fork lets a project instead target a Raspberry Pi Pico, which runs a software interpretation of the same design instead of a synthesized bitstream. This is not a substitute for real FPGA hardware in general — it exists specifically so students in this class can do the same Verilog exercises on a $4 board instead of a $20+ one.

Raspberry Pi Pico target

Setting board = pico in a project's apio.ini makes apio build/apio upload target a Raspberry Pi Pico (RP2040) instead of an FPGA:

  • The Pico board, RP2040 target, and uploader definitions are bundled with this fork and automatically layered over Apio's installed definitions. Pico projects do not need their own boards.jsonc, fpgas.jsonc, or programmers.jsonc files.

  • apio build asks Yosys's CXXRTL backend to compile the selected Verilog top module into C++, adds a thin PCF-driven GPIO wrapper, and compiles it against pico-sdk with cmake/arm-none-eabi-g++ into a .uf2. Using Yosys's maintained backend avoids a narrow, hand-written list of supported internal cells, so ordinary inferred memories, variable indexing, and multi-module designs are handled by Yosys itself.

  • The generated firmware loops as fast as it can (no fixed rate — simple designs run far faster than 1kHz, complex ones slower), each iteration reading all input pins, evaluating combinational logic, checking for a clock edge, committing register updates, and writing all output pins — the same settle-then-commit model an event-driven Verilog simulator uses, just running continuously on real I/O instead of stepping through simulation time.

  • Pin mapping uses the same .pcf file format apio already uses for ice40 boards, just reinterpreting the pin number as an RP2040 GPIO instead of an FPGA package pin. Mapping a port to the reserved pin number -1 (INTERNAL_PIN) gets it a signal with no physical GPIO attached at all — for clk, this means a genuine 1kHz square wave generated by a hardware timer interrupt, so a design can be tested with no external clock source and without spending one of the Pico's comparatively scarce GPIOs on it.

  • apio upload flashes over USB. The very first flash of a given board needs the standard manual step (hold BOOTSEL while plugging in USB), since a blank board has no code running yet to talk to. After that, every upload is a normal one-command flash with no physical button press (confirmed on Linux and macOS). It tries three things in order, stopping at the first that works: copying the .uf2 onto the bootloader's RPI-RP2 volume, if a board is already sitting in BOOTSEL; picotool load -f, which can reboot a running board into its bootloader on its own; and finally a small listener built into the generated firmware, which reboots the board into its bootloader when it receives a byte over the board's USB serial port. The middle step needs a udev rule on Linux (or a Zadig-installed WinUSB driver on Windows) that students are unlikely to have — without it, it fails instantly and silently and the firmware listener does the job instead. macOS needs no such setup: picotool works there out of the box, and does every upload on its own in about two seconds.

  • The toolchain (arm-none-eabi-gcc, cmake, ninja, picotool, pico-sdk, tinyusb) is installed by apio packages install, fetched directly from each project's own official releases (ARM/xPack, Kitware, Ninja, Raspberry Pi, and hathach respectively) rather than an apio-hosted mirror. Nothing is ever downloaded on its own — commands like apio build report what's missing instead of fetching it mid-build.

    The one exception is the examples package, which apio packages install deliberately does not install. It is marked on-demand and is downloaded only by apio examples fetch, the single command that cannot do its job without it. Upstream instead refreshed the examples as a side effect of unrelated commands. apio examples list and apio boards report zero examples until something has fetched one, rather than reaching for the network. TinyUSB is a separate package because the pico-sdk release tarball ships without its git submodules, leaving its bundled lib/tinyusb empty — and the SDK reacts to that by warning and silently disabling USB support, which yields firmware that runs correctly but never enumerates over USB, breaking the remote reboot-to-bootloader. apio build now fails outright rather than producing such a binary.

See experimental/pico-hello/ for a minimal working example project.

Usage

Standard apio workflow, from within a project directory containing an apio.ini:

apio build    # synthesize/compile
apio upload   # flash the board

For the pico target, try the included example first:

cd experimental/pico-hello
apio build
apio upload

The first apio upload to a given physical board needs it held in BOOTSEL mode (hold the BOOTSEL button while plugging in USB) — a factory-fresh board has no code running yet to receive the normal reboot signal. Every apio upload after that is hands-off.

About

🌱 Open source ecosystem for open FPGA boards

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages