FPGA 101 workshop (mmicko__fpga101-workshop)
| Field | Value |
|---|---|
| Upstream | https://github.com/mmicko/fpga101-workshop |
| Reviewed at | 1f5d605 (upstream date 2019-03-17), reviewed 2026-09-28 |
| License | MIT (LICENSE, Copyright 2018 Miodrag Milanović); tutorials/11-Computer/i8080.v modified BSD (Dmitry Tselikov); tutorials/12-RiscV/z_picorv32.v ISC; MicroPython port MIT |
| HDL / framework | Verilog (82 files), C firmware and a MicroPython port, 2 IceStudio designs |
| Toolchain | open via apio: yosys + arachne-pnr + icepack (README test log); IceStudio; riscv64-unknown-elf-gcc |
| Programmer | apio (board fpga101) |
| Target FPGA(s) | iCE40 UP5K SG48 (NOT ECP5), 12 MHz clock (pinout.pcf) |
| Board revision(s) | FPGA101 badge of Hackaday Belgrade 2018 (parallel RGB LCD, RGB LED, buttons, audio out) |
| Activity | workshop held 2018-05-26; last commit 2019-03-17; author Miodrag Milanović (mmicko) |
What the gateware does
A progressive FPGA course in 20 exercises, each a small apio project (top.v + pinout.pcf + apio.ini), from a blinking LED to a RISC-V SoC running MicroPython, plus a complete Galaksija retro computer. It is the original of several ULX3S resources: the same author’s ULX3S workshop ulx3s__fpga-odysseus shares 10 identical files (grom CPU, i8080/Altair computer, UARTs), and the toy “grom” CPU found in lawrie’s ULX3S and ULX4M examples is this one (lawrie__ulx3s_examples review). The Galaksija project is the upstream of emard__galaksija and emard__ulx3s_galaksija.
Exercises
| # | Exercise | Path | What it teaches / builds | iCE40 primitives | Testbench |
|---|---|---|---|---|---|
| 0 | IceStudio | tutorials/00-IceStudio | Schematic design in IceStudio (led.ice, trigger.ice) | none | none |
| 1 | Basics | tutorials/01-Basics | First design: drive an LED (led.v) | none | none |
| 2 | LED | tutorials/02-LED | RGB LED with a counter (rgb.v) | none | rgb_tb.v (waveform) |
| 3 | Buttons | tutorials/03-Buttons | Buttons to RGB LED (button_rgb.v) | none | none |
| 4 | Audio | tutorials/04-Audio | Tone generation on the audio pin (audio.v) | none | none |
| 5a | Video: basic | tutorials/05-Video/00-Basic | Parallel RGB LCD timing and test pattern (video.v, lcd_pll.v) | SB_PLL40_CORE, SB_HFOSC | none |
| 5b | Video: key test | tutorials/05-Video/01-KeyTest | Buttons shown on the LCD | SB_PLL40_CORE, SB_HFOSC | none |
| 6 | State machine | tutorials/06-StateMachine | FSM driving the display | SB_PLL40_CORE, SB_HFOSC | none |
| 7a | Memory: basic | tutorials/07-Memory/00-Basic | Font ROM (font_rom.v), characters on the LCD | SB_PLL40_CORE, SB_HFOSC | none |
| 7b | Memory: buffer | tutorials/07-Memory/01-Buffer | Text buffer ROM generated by text.py | SB_PLL40_CORE, SB_HFOSC | none |
| 7c | Memory: terminal | tutorials/07-Memory/02-Terminal | Serial terminal: uart_rx.v into video RAM | SB_PLL40_CORE, SB_HFOSC | none |
| 8 | Moving sprite | tutorials/08-MovingSprite | Sprite ROM moved by the buttons | SB_PLL40_CORE, SB_HFOSC | none |
| 9a | Pong: move | tutorials/09-Pong/00-Move | Paddles | SB_PLL40_CORE, SB_HFOSC | none |
| 9b | Pong: ball | tutorials/09-Pong/01-Ball | Ball movement | SB_PLL40_CORE, SB_HFOSC | none |
| 9c | Pong: game | tutorials/09-Pong/02-Game | Collisions and game logic | SB_PLL40_CORE, SB_HFOSC | none |
| 9d | Pong: wall | tutorials/09-Pong/03-Wall | Single-player wall variant | SB_PLL40_CORE, SB_HFOSC | none |
| 10 | CPU | tutorials/10-CPU | The grom toy 8-bit CPU (grom_cpu.v, alu.v) and a minimal computer | none | grom_computer_tb.v (waveform) |
| 11 | Computer | tutorials/11-Computer | Altair 8800-style computer: i8080 core, MC6850 ACIA, ROM from rom.py, serial console | SB_HFOSC | none |
| 12a | RISC-V: SoC | tutorials/12-RiscV | PicoSoC (PicoRV32) with SPRAM (up_spram.v), XIP flash (spimemio.v), UART and LCD text console | SB_SPRAM256KA, SB_PLL40_CORE, SB_IO, SB_HFOSC | none |
| 12b | RISC-V: firmware | tutorials/12-RiscV/01-Simple | Bare-metal C firmware (firmware.c, Makefile) | n/a | none |
| 12c | RISC-V: MicroPython | tutorials/12-RiscV/02-Micropython | MicroPython port ports/picorv32 with LCD, LED and switch modules | n/a | none |
Also: tests/led and tests/riscv (toolchain checks; led_tb.v waveform-only), and projects/galaksija: the Galaksija Z80 computer (TV80 core, video on the LCD, SPRAM) with a prebuilt bitstream.
Structure
tutorials/: the 20 exercises above; each directory is a standalone apio project.projects/galaksija/: complete retro computer (tv80*.v,video.v,font_rom.v,rom_memory.v).tests/: environment checks from the README.presentation/: workshop slides (pptx/pdf, removed from the local clone by pruning; available upstream).
How to build
As found in the README (not run here):
cd tutorials/02-LED
apio build # yosys synth_ice40 -> arachne-pnr -d 5k -P sg48 -> icepack
apio sim # opens GTKWave on the testbench, where one exists
cd tutorials/12-RiscV/01-Simple && make # RISC-V firmware
The exercises assume the FPGA101 badge (apio.ini: board = fpga101); arachne-pnr is obsolete, nextpnr-ice40 (--up5k --package sg48) is the modern equivalent.
Reuse notes
| Block | Path | Top module | Language | Vendor primitives | License |
|---|---|---|---|---|---|
| grom toy CPU + computer | tutorials/10-CPU/ | grom_top | Verilog | none | MIT (repo) |
| i8080 Altair computer | tutorials/11-Computer/ | top (in top_altair.v) / altair | Verilog | SB_HFOSC (top only) | i8080 modified BSD; rest MIT |
| PicoSoC + LCD text console | tutorials/12-RiscV/ | top | Verilog | SB_SPRAM256KA, SB_PLL40_CORE, SB_IO, SB_HFOSC | MIT; PicoRV32 ISC |
| Parallel LCD video timing | tutorials/05-Video/00-Basic/video.v | video | Verilog | none (PLL in lcd_pll.v) | MIT (repo) |
| Galaksija | projects/galaksija/ | top | Verilog | SB_SPRAM256KA, SB_PLL40_CORE, SB_HFOSC | MIT; TV80 own license |
- For ULX3S, start from ulx3s__fpga-odysseus rather than porting: it is the same author’s ULX3S version of these exercises (DVI instead of the LCD, ECP5 PLL).
- Porting a single exercise: replace
SB_PLL40_CORE/SB_HFOSCwith the 25 MHzclk_25mhzand anEHXPLLL, andSB_SPRAM256KAwith block RAM or SDRAM (porting guide). - Cores recorded on the site: grom CPU, PicoSoC with MicroPython.
Open questions
- The i8080 exercise’s ROM content and licensing of the Altair ROM image are not checked.
- The FPGA101 badge schematic and LCD part number are not in the repo (unknown).