ULX3S

The main board of this collection: 32 MB SDR SDRAM, GPDI (HDMI) port, ESP32, US1 FT231X + US2 direct USB, SD card, MAX11125 ADC, OLED header, 56 GPIO.

   
Board Radiona ULX3S
FPGA LFE5U-12F/25F/45F/85F, CABGA381
Evidence emard/ulx3s MANUAL + reference LPFs (doc/constraints)
Clock 25 MHz (clk_25mhz, reference LPF)
Catalogued repos 373

Board reference

A condensed reference for people writing new gateware for the ULX3S. Everything here comes from emard/ulx3s at 6a92cec (2025-04-27): the README, doc/MANUAL.md and the LPF constraint files. When in doubt, the manual and the LPF for your board revision are authoritative.

The board at a glance

Block Part Top-level signals (ulx3s_v20.lpf)
FPGA Lattice ECP5 LFE5U-12F/25F/45F/85F, CABGA381, -6 —
Clock 25 MHz oscillator (site G2) clk_25mhz
SDRAM 16-bit SDR, 32 MB typical (MT48LC16M16 / IS42S16160G / AS4C32M16SB) sdram_clk, cke, csn, rasn, casn, wen, ba[1:0], a[12:0], dqm[1:0], d[15:0]
Config flash QSPI 4–16 MB (IS25LP128F, W25Q128JV, …) flash_csn, flash_clk, flash_mosi, flash_miso, flash_wpn, flash_holdn (flash_clk is the dedicated config clock pin U3; ECP5 designs usually drive it through the USRMCLK primitive, which is general ECP5 knowledge and not stated in this repo)
USB US1 FT231X, JTAG + UART (0403:6015) ftdi_rxd, ftdi_txd, ftdi_nrts, ftdi_ndtr, ftdi_txden
USB US2 Direct to FPGA, 1.5/12 Mbps, host/device usb_fpga_dp/dn, usb_fpga_bd_dp/dn, usb_fpga_pu_dp/dn
Video GPDI connector (TMDS/LVDS, HDMI-compatible plug) gpdi_dp[3:0], gpdi_dn[3:0], gpdi_sda, gpdi_scl, gpdi_cec, gpdi_hpd
Audio 3.5 mm TRRS (OMTP): L, R, SPDIF/composite; 4-bit resistor DAC each audio_l[3:0], audio_r[3:0], audio_v[3:0]
ADC MAX11125, 8 ch, 12 bit, 1 MSa/s shared adc_csn, adc_sclk, adc_mosi, adc_miso
Display 7-pin header: ST7789 / SSD1331 / SSD1351 / SSD1306 oled_csn, oled_clk, oled_mosi, oled_dc, oled_resn
SD card micro-SD, 4-bit, shared with ESP32 sd_clk, sd_cmd, sd_d[3:0], sd_cdn, sd_wp
WiFi/BT ESP32 WROOM/WROVER (optional) wifi_en, wifi_rxd, wifi_txd, wifi_gpio*
User I/O 8 LEDs, 7 buttons, 4 DIP switches led[7:0], btn[6:0], sw[3:0]
GPIO J1/J2, 56 pins, 3.3 V, not 5 V tolerant gp[27:0], gn[27:0]
Power RTC MCP7940N wake-up, FPGA-driven power-off shutdown
RF PCB antenna trace, 88–108 / 433 MHz ant_433mhz

Buttons: btn[0] = PWR (active-low), btn[1..6] = FIRE1, FIRE2, UP, DOWN, LEFT, RIGHT (active-high).

GPIO details

  • gp/gn 0–7 (J1) and 22–27 (J2) are single-ended; 8–21 are true differential pairs.
  • Clock-capable: gp/gn 12 (differential primary clock), gp/gn 0,1 (primary), gp13, gn17 (general routing).
  • Shared: gp/gn 11–13 with ESP32 (v2.0+), gp/gn 14–17 with the onboard ADC.
  • 4 PMODs fit on J1/J2 with power and ground in the right places. J2 also carries 5 V in/out.

Choosing the constraint file

PCB revision LPF
v1.7 doc/constraints/prototype/ulx3s_v17patch.lpf
v2.x.x, v3.0.x (most boards in circulation) doc/constraints/ulx3s_v20.lpf
v3.1.4 doc/constraints/prototype/ulx3s_v314.lpf
v3.1.6, v3.1.7 (Mouser from 2022) doc/constraints/prototype/ulx3s_v316.lpf

The revision is printed on the PCB silkscreen. v3.1.x changed the ESP32 wiring (wifi_gpio16/17 removed, use wifi_gpio26/27), fixed GPDI hot-plug detect, and added SERDES RX pairs on an 8-pin OLED header.

Build and load (open-source flow)

yosys -p "synth_ecp5 -top top -json top.json" top.v
nextpnr-ecp5 --85k --package CABGA381 --lpf ulx3s_v20.lpf --json top.json --textcfg top.config
ecppack --compress top.config top.bit
openFPGALoader -b ulx3s top.bit          # to SRAM
openFPGALoader -b ulx3s -f top.bit       # to config flash

Use --12k, --25k or --45k to match your chip. Easiest install: YosysHQ oss-cad-suite-build. Alternatives: fujprog, OpenOCD with an FT2232 on the JTAG header (fastest), ESP32 over WiFi (esp32ecp5), or the US2 DFU bootloader (openFPGALoader -b ulx3s_dfu; user image at flash offset 0x200000).

Pitfalls

  • Max USB input voltage is 6 V. GPIOs are 3.3 V only.
  • In 1-bit SPI flash mode, drive flash_wpn/flash_holdn high (some ISSI parts fail otherwise).
  • To drive flash pins from the user design, set MASTER_SPI_PORT=DISABLE in the LPF SYSCONFIG line.
  • Leave wifi_en as input with pull-up unless you use the ESP32 on purpose. A bitstream holding the ESP32 enabled, combined with ESP32 firmware that grabs JTAG, can lock out JTAG (jumper J3 disables the ESP32).
  • Composite/SPDIF on Ring2 needs an OMTP (Apple/Nokia) 3-RCA cable. Sony-wired cables put GND there.
  • High-resolution GPDI video interferes with ESP32 WiFi on v3.0.x boards.
  • The RTC on v2/v3.0 runs about 30 ppm fast.

Constraint files (LPF)

Most-copied distinct LPFs for this board in the cloned repos (from the LPF catalogue).

LPF Revision Copies Peripherals constrained
ulx3s_v20.lpf (lawrie__ulx3s_examples) v2.x/v3.0.x (ulx3s_v20) 48 adc, audio, button, esp32-wifi, ftdi-uart, gpio-header, hdmi-dvi, led, oled-lcd, ps2, radio-antenna, rtc-power, sdcard, sdram, spi-flash, switch, usb
ulx3s.lpf (adrmcintyre__vixen) v2.x/v3.0.x (ulx3s_v20) 42 adc, audio, button, esp32-wifi, ftdi-uart, gpio-header, hdmi-dvi, led, oled-lcd, radio-antenna, rtc-power, sdcard, sdram, spi-flash, switch, usb
ulx3s_v20.lpf (ahamidi87__simpleblinky) v2.x/v3.0.x (ulx3s_v20) 40 adc, audio, button, esp32-wifi, ftdi-uart, gpio-header, hdmi-dvi, led, oled-lcd, radio-antenna, rtc-power, sdcard, sdram, spi-flash, switch, usb
ulx3s_v20.lpf (chiplet__ulx3s-blinky) v2.x/v3.0.x (ulx3s_v20) 20 adc, audio, button, esp32-wifi, ftdi-uart, gpio-header, hdmi-dvi, led, oled-lcd, radio-antenna, rtc-power, sdcard, sdram, spi-flash, switch, usb
ulx3s_v316.lpf (danodus__ecp5_hdmi_audio_video) v3.1.6/v3.1.7 (ulx3s_v316) 14 adc, audio, button, esp32-wifi, ftdi-uart, gpio-header, hdmi-dvi, led, oled-lcd, radio-antenna, rtc-power, sdcard, sdram, spi-flash, switch, usb
ulx3s_v20.lpf (emard__papilio-arcade) v2.x/v3.0.x (ulx3s_v20) 13 adc, audio, button, esp32-wifi, ftdi-uart, gpio-header, hdmi-dvi, led, oled-lcd, radio-antenna, rtc-power, sdcard, sdram, spi-flash, switch, usb
ulx3s_v20.lpf (diegob94__ulx3s_blink) v2.x/v3.0.x (ulx3s_v20) 12 adc, audio, button, esp32-wifi, ftdi-uart, gpio-header, hdmi-dvi, led, oled-lcd, radio-antenna, rtc-power, sdcard, sdram, spi-flash, switch, usb
ulx3s_v20_segpdi.lpf (circuit-killer__fpga-usbserial) v2.x/v3.0.x (ulx3s_v20) 11 adc, audio, button, esp32-wifi, ftdi-uart, gpio-header, hdmi-dvi, led, oled-lcd, radio-antenna, rtc-power, sdcard, sdram, spi-flash, switch, usb
ulx3s.lpf (danodus__msx_fpga) v2.x/v3.0.x (ulx3s_v20) 10 adc, audio, button, esp32-wifi, ftdi-uart, gpio-header, hdmi-dvi, led, oled-lcd, ps2, radio-antenna, rtc-power, sdcard, sdram, spi-flash, switch, usb
ulx3s_v20.lpf (danodus__ulx3s_sms) v2.x/v3.0.x (ulx3s_v20) 9 adc, audio, button, esp32-wifi, ftdi-uart, gpio-header, hdmi-dvi, led, oled-lcd, radio-antenna, rtc-power, sdcard, sdram, spi-flash, switch, usb
ulx3s_v20.lpf (f32c__f32c) v2.x/v3.0.x (ulx3s_v20) 9 adc, audio, button, esp32-wifi, ftdi-uart, gpio-header, hdmi-dvi, led, oled-lcd, radio-antenna, rtc-power, sdcard, sdram, spi-flash, switch, usb
ulx3s_v20.lpf (stereoninja__stereoninjafpga) v2.x/v3.0.x (ulx3s_v20) 8 adc, audio, button, esp32-wifi, ftdi-uart, gpio-header, hdmi-dvi, led, oled-lcd, radio-antenna, rtc-power, sdcard, sdram, spi-flash, switch, usb

Reusable cores seen on this board

Cores whose source repo, or a repo that copies/instantiates them, targets this board.

Core Function Source repo
Digital down-converter + AM/FM demod chain (post-ADC) adc emeb__orangecrab_adc
MAX1112x ADC reader (ulx3s-emi copy) adc emard__ulx3s-emi
MAX1112x ADC reader (ulx3s-misc) adc emard__ulx3s-misc
I2S audio interface (ulx3s-misc) audio-digital emard__ulx3s-misc
S/PDIF transmitter (f32c) audio-digital f32c__f32c
S/PDIF transmitter (synthowheel) audio-digital emard__synthowheel
Hazard3-Doom vendored DFU bootloader (ULX4M-LD validated) bootloader-dfu ulx3s__hazard3-doom
Machdyne tinydfu-bootloader (ECP5, TinyFPGA-derived USB core) bootloader-dfu machdyne__tinydfu-bootloader
TinyFPGA USB Bootloader (USB-serial-to-SPI-flash bridge) bootloader-dfu tinyfpga__tinyfpga-bootloader
ULX3S/ULX4M USB DFU bootloader (had2019-playground) bootloader-dfu emard__had2019-playground
no2bootloader (Nitro) iCE40 UP5K DFU bootloader bootloader-dfu no2fpga__no2bootloader
no2usb DFU runtime + dfu_helper.v (iCE40) bootloader-dfu smunaut__ice40-playground
AHB-Lite crossbar/arbiter/APB bridge bus-fabric ulx3s__hazard3
wb_intercon Wishbone mux/arbiter (olofk) bus-fabric kulp__tenyr
OV7670 RGB/YUV capture + color-filter + VGA preview (ULX3S apio) camera jderobot__fpga-robotics
OV7670 camera capture + SCCB config core camera msrraju07__iop
OV7670 capture + SCCB master (ulx3s-experiments) camera tucanae47__ulx3s-experiments
camera85 nMigen OV7670 capture + image pipeline camera lawrie__ulx3s-nmigen-examples
MiST composite/RGB scandoubler (composite-video input side) composite-video hoglet67__ice40beeb
f32c PAL composite video (CVBS) generator composite-video f32c__f32c
CDP1802-compatible core (SpinalHDL) cpu-retro lawrie__fpgacosmacelf
TMS9900-family CPU core (public domain) cpu-retro pnru__ti99
TV80 Z80-compatible core (emard__ulx3s_galaksija copy) cpu-retro emard__ulx3s_galaksija
cpu_6502 (Klaus Dormann-verified 6502 core) cpu-retro chrismoos__m6502
danielh186 6502-compatible CPU core (FPGA-proven) cpu-retro danielh186__6502-tapeout
fx68k 68000-compatible core (nullobject vendored copy) cpu-retro nullobject__m68k-ulx3s
grom toy 8-bit CPU + computer (FPGA 101 original) cpu-retro mmicko__fpga101-workshop
i8080-compatible core (Bashkiria-2M-derived) cpu-retro lawrie__ulx3s_examples
FPGA 101 PicoSoC with LCD text console and MicroPython cpu-riscv mmicko__fpga101-workshop
Hazard3 RV32IMAC core cpu-riscv wren6991__hazard3
KianV RV32IMA+Sv32 core (Linux-capable) cpu-riscv splinedrive__kianriscv
LUNA-SoC VexRiscv SoC framework (Moondancer’s CPU) cpu-riscv greatscottgadgets__luna-soc
PicoRV32 RISC-V core cpu-riscv yosyshq__picorv32
VexRiscv (SpinalHDL-generated Verilog) cpu-riscv rschlaikjer__fpga-3-softcores
f32c RISC-V/MIPS-compatible core cpu-riscv f32c__f32c
Pipelined double-SHA256 hasher crypto xtrinch__fpga-bitcoin-miner
Pruned 64-stage double-SHA256 miner pipeline crypto williamsharkey__pruned-sha256-miner
Ring-oscillator TRNG crypto krishkc5__trng-ring-oscillator
SRNG ring-oscillator TRNG + Blake2s DRBG crypto secworks__cryptkey
secworks AES-128/256 core (via ct-key) crypto assured__ct-key

Projects targeting this board

373 catalogued repos target this board; see the full catalogue. Those with a full review:


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.