Bootloaders and DFU

USB DFU and other FPGA bootloaders, multiboot.

Core Repository Language License FPGA Used by
ULX3S/ULX4M USB DFU bootloader (had2019-playground) ★ emard__had2019-playground Verilog, C per file: bootloader RTL BSD-3-Clause, USB core +… ECP5 0
Fomu foboot DFU bootloader (LiteX/VexRiscv + ValentyUSB eptri) im-tomu__foboot Verilog (SpinalHDL-generated VexRiscv… foboot itself Apache-2.0 iCE40 2
Hazard3-Doom vendored DFU bootloader (ULX4M-LD validated) ulx3s__hazard3-doom Verilog, C provenance in… ECP5 0
Machdyne tinydfu-bootloader (ECP5, TinyFPGA-derived USB core) machdyne__tinydfu-bootloader Verilog Apache-2.0 ECP5 0
no2bootloader (Nitro) iCE40 UP5K DFU bootloader no2fpga__no2bootloader Verilog, C HDL CERN-OHL-P-2.0 iCE40 0
no2usb DFU runtime + dfu_helper.v (iCE40) smunaut__ice40-playground Verilog mixed CERN-OHL-P-2.0/LGPL-3.0-or-later/MIT per… iCE40 4
TinyFPGA USB Bootloader (USB-serial-to-SPI-flash bridge) tinyfpga__tinyfpga-bootloader Verilog Apache-2.0 iCE40 (also ported to ECP5 12F via Lattice Diamond in boards/TinyFPGA_EX, and to Xilinx Artix-7) 8

Cores

ULX3S/ULX4M USB DFU bootloader (had2019-playground) (best)

The gateware ULX3S/ULX4M ship from flash address 0: PicoRV32 + no2usb-derived USB device core enumerating as DFU 1d50:614b, writing the user bitstream to flash 0x200000 via a QSPI master, with a 6-zone alt-setting layout. Fully documented in docs/DFUs.md.

   
Repository emard__had2019-playground: HAD2019 badge playground
Files projects/bootloader/rtl, projects/bootloader/fw, cores/usb/rtl
Top module top
Language Verilog, C
License per file: bootloader RTL BSD-3-Clause, USB core + DFU firmware LGPL-3.0-or-later, picorv32.v ISC (see docs/DFUs.md)
FPGA / primitives ECP5: TRELLIS_IO, OFS1P3DX, IDDRX1F, USRMCLK
Tests none found (cores/usb/sim + project tbs are waveform-only, never run to a pass/fail check)

On ULX3S: USER_BITSTREAM_ADDR, dfu_zones[0] (fw/usb_dfu.c) and ecpmulti –address must all agree; PROGRAMN (LPF site M4) must loop back for hand-off.

Fomu foboot DFU bootloader (LiteX/VexRiscv + ValentyUSB eptri)

LiteX/Migen-generated SoC on a VexRiscv CPU with ValentyUSB’s eptri (TriEndpointInterface) USB device peripheral providing the DFU class in a single alt-0 interface; boots the flashed user image after a timeout unless the two Fomu touch pads are bridged to force staying in DFU.

   
Repository im-tomu__foboot: Foboot: the Fomu iCE40 UP5K failsafe USB DFU bootloader, LiteX/Migen SoC
Files hw/rtl/VexRiscv_Fomu.v, hw/rtl/spimemio.v, hw/deps/valentyusb/valentyusb/usbcore
Top module VexRiscv
Language Verilog (SpinalHDL-generated VexRiscv core), Python/Migen (SoC + USB peripheral, hw/*.py), C (sw/)
License foboot itself Apache-2.0 (LICENSE); ValentyUSB submodule BSD-3-Clause (hw/deps/valentyusb/LICENSE)
FPGA / primitives iCE40: none (portable)
Tests hw/deps/valentyusb/sim (cocotb, test-eptri.py/cocotb-eptri.py): self-checking, raises TestFailure/uses assertEqual; none found for the SoC or bootloader firmware itself

On ULX3S: Architecturally unlike every other bootloader-dfu entry here: a LiteX/Migen SoC generated by Python, not hand-written RTL, needing the LiteX build flow rather than a plain yosys+nextpnr Makefile. Its migen/litex/litedram/litex-boards/spibone/compiler_rt submodules were deliberately not fetched in this clone (only hw/deps/valentyusb was), so it cannot be rebuilt from this clone.

Used by 2 other catalogued repos (file copies or module instances found by scan_core_usage.py; heuristic):

Hazard3-Doom vendored DFU bootloader (ULX4M-LD validated)

Self-contained fork of the had2019 bootloader (own mk/, cores/, no external Makefile deps), remapped buttons, validated on real ULX4M-LD v0.0.3 (LFE5UM-85F) hardware, with a byte-for-byte readback recovery procedure documented in README_ULX4M_BOOTLOADER.md.

   
Repository ulx3s__hazard3-doom: ulx3s/Hazard3-Doom: Doom
Files bootloader/rtl, bootloader/fw, bootloader/cores
Top module top
Language Verilog, C
License provenance in LICENSES/HAD2019-Bootloader-NOTICE.md; per-file licenses match the emard original (BSD-3/LGPL-3.0+/ISC)
FPGA / primitives ECP5: TRELLIS_IO, OFS1P3DX, IDDRX1F, USRMCLK
Tests none found (same iverilog-compile-only sim rule as the original)

On ULX3S: Prefer this copy over the emard original for a self-contained tree; same USER_BITSTREAM_ADDR/dfu_zones agreement rule applies.

Machdyne tinydfu-bootloader (ECP5, TinyFPGA-derived USB core)

Per-board ECP5 DFU bootloader (Lakritz/Obst/Konfekt/etc.), always resident at flash 0 and auto-booting the user partition after a timer unless DFU activity intervenes. USB device core is a bit-banged full-speed PHY+SIE (usb_fs_*.v) plus usb_dfu_core.v, adapted by Lawrie Griffiths/Owen Kirby from Luke Valenti’s original TinyFPGA bootloader core (per usb_dfu_core.v header) - a third, independent USB-device lineage distinct from no2usb and ValentyUSB.

   
Repository machdyne__tinydfu-bootloader: TinyDFU Bootloader: multi-board USB DFU bootloader
Files usb/usb_dfu_core.v, usb/usb_dfu_ctrl_ep.v, boards/lakritz/tinydfu_lakritz.v, boards/lakritz/boardinfo.vh
Top module tinydfu_lakritz
Language Verilog
License Apache-2.0 (LICENSE.txt)
FPGA / primitives ECP5: USRMCLK
Tests testbenches/i2c_master_tb.v only (unrelated I2C helper); no USB/DFU-core testbench found

On ULX3S: Not ULX3S; fills the ECP5 gap in this list with a bootloader that is neither no2usb- nor ValentyUSB-derived. VID:PID 0x16d0:0x116d is per-board, hardcoded in each boards//boardinfo.vh (BOARD_VID/BOARD_PID localparams). Flash split varies by board: 1 MB boot/0x100000 user on kaugummi/klinge/konfekt/kopflos/minze/schoko, 256 KB boot/0x040000 user on lakritz and obst.

no2bootloader (Nitro) iCE40 UP5K DFU bootloader

Complete multi-board iCE40 UP5K DFU bootloader (PicoRV32 SoC + no2usb device core): alt 0 = iCE40 bitstream, alt 1 = RISC-V firmware; SB_WARMBOOT cycles between a boot stub (0x004000), the DFU image (0x040000) and two app images (0x080000/0x0c0000). Used by iCEBreaker-bitsy, reDIP-SID, icE1usb.

   
Repository no2fpga__no2bootloader: Nitro Bootloader: iCE40 UP5K DFU bootloader
Files gateware/ice40/rtl, gateware/cores/no2usb, firmware/fw_dfu.c
Top module top
Language Verilog, C
License HDL CERN-OHL-P-2.0 (own RTL in gateware/ice40/rtl and gateware/cores/no2usb, per LICENSE.md); this repo’s firmware GPL-3.0-or-later (LICENSE.md); no2usb stack LGPL-3.0-or-later, MIT for the tinyusb-driver-reused parts (gateware/cores/no2usb/LICENSE.md)
FPGA / primitives iCE40: SB_PLL40_2F_CORE, SB_PLL40_2F_PAD, SB_IO, SB_WARMBOOT, SB_HFOSC, SB_GB
Tests gateware/ice40/sim/{top_tb.v,dfu_helper_tb.v} + cores/{no2usb,no2misc,no2ice40}/sim: iverilog compile only, no vvp run found in the Makefiles - waveform-only

On ULX3S: iCE40 UP5K only (SB_WARMBOOT/SB_PLL40_2F); no ECP5 port in this collection. gateware/build (no2build) submodule was deliberately not fetched here, so this clone cannot actually be synthesized or simulated.

no2usb DFU runtime + dfu_helper.v (iCE40)

Button debouncer that reboots into the no2bootloader DFU image via SB_WARMBOOT (long press) or resets the app (short press); the DFU class firmware itself (usb_dfu.c/usb_dfu_rt.c) lives in the fetched no2usb submodule.

   
Repository smunaut__ice40-playground: iCEBreaker: collection of iCE40 UP5K IP cores
Files projects/riscv_usb/rtl/dfu_helper.v
Top module dfu_helper
Language Verilog
License mixed CERN-OHL-P-2.0/LGPL-3.0-or-later/MIT per file (doc/LICENSE-*.txt)
FPGA / primitives iCE40: SB_WARMBOOT
Tests none found for dfu_helper.v itself

On ULX3S: iCE40-only (SB_WARMBOOT multiboot); porting to ECP5 needs a different warm-boot mechanism plus the no2bootloader project, which is not in this collection.

Full review: smunaut__ice40-playground.

Used by 4 other catalogued repos (file copies or module instances found by scan_core_usage.py; heuristic):

TinyFPGA USB Bootloader (USB-serial-to-SPI-flash bridge)

Full-speed USB device MAC/PHY presenting a virtual serial port bridged to SPI-flash read/write/erase commands, so a host programmer can reflash the FPGA’s config/user images with no separate USB-JTAG chip; common/ core has no vendor primitives, only the per-board top does.

   
Repository tinyfpga__tinyfpga-bootloader: TinyFPGA USB Bootloader: USB virtual-serial-to-SPI-flash-bridge gateware bootloader;
Files common/usb_fs_rx.v, common/usb_fs_tx.v, common/usb_fs_pe.v, common/usb_serial_ctrl_ep.v, common/usb_spi_bridge_ep.v, common/tinyfpga_bootloader.v
Top module tinyfpga_bootloader
Language Verilog
License Apache-2.0 (LICENSE)
FPGA / primitives iCE40 (also ported to ECP5 12F via Lattice Diamond in boards/TinyFPGA_EX, and to Xilinx Artix-7): none (portable)
Tests self-checking (29 tests/*/test.v via iverilog, TAP-style asserts in expect_usb_ack() etc., tests/test.mk)

On ULX3S: Not proven on ULX3S; the fielded ULX3S US2 DFU bootloader (had2019-dfu-bootloader) is unrelated (no2usb-derived). An older ULX3S bootloader, emard__tinyfpga-bootloader-ulx3s, was a direct fork of a 60MHz variant of this exact core.

Used by 8 other catalogued repos (file copies or module instances found by scan_core_usage.py; heuristic):

Other catalogued projects

Catalogued repos tagged bootloader (39) are listed in the full catalogue.


Back to top

Generated from the JSON in data/ by the scripts in .claude/skills. Facts cite the upstream file at the reviewed commit; verify before reuse.

This site uses Just the Docs, a documentation theme for Jekyll.