Zucker is an experimental System-on-a-Chip (SOC) designed for Machdyne / Lone Dynamics FPGA computers that provides a RISC-V CPU (PicoRV32), a simple GPU, memory controllers, a keyboard controller and a UART. This repo also contains firmware, a minimal OS and example applications.
Zucker was originally created as a demo platform and a starting point for developing gateware and apps on the Riegel FPGA computer and it now supports most of our other FPGA computers as well. The goal of Zucker is to allow FPGA computers to be used as stand-alone timeless personal computer systems when attached to a keyboard and a monitor.
Building Zucker requires Yosys, nextpnr-ice40, IceStorm and a RV32I toolchain.
After everything is installed, to build the SOC:
make BOARD=<board>
For example:
make BOARD=eis
This will build the firmware and FPGA configuration image and write them to output/soc.bin
. It will also build the demo apps.
Once the gateware, firmware and demo apps are built, you can use ldprog to write everything to the MMOD:
make BOARD=<board> flash
For example:
make BOARD=eis flash
Enable USB HID Host Support
$ cd ext
$ git clone https://github.com/nand2mario/usb_hid_host
$ cd ..
$ make USB=1 BOARD=obst
The default configuration assumes that a UART PMOD is connected to PMODB (or PMODA if there's only one PMOD on the device).
If for example your USB-UART PMOD is on /dev/ttyUSB0 you can access the serial console using minicom:
$ minicom -D /dev/ttyUSB0 -b 115200
Ensure that hardware flow control is enabled. In minicom this is under CTRL-A O, Serial port setup, Hardware Flow Control.
- USB Bootloader (optional)
- Zucker Bootloader (ZBL)
- LIX
- Apps
See the Riegel repo for details on setting up a USB bootloader. Eis, Keks and Bonbon are programmable over USB with the onboard RP2040, and don't need an FPGA-based USB bootloader.
The ZBL bootloader firmware is inside the FPGA configuration image. Its primary purpose is to load the next stage (LIX) from the MMOD flash. ZBL can also perform some basic system diagnostics.
The source code for ZBL is located in firmware.c and it's called by boot_picorv32.S.
LIX is a minimal OS and second stage bootloader. LIX is capable of loading and booting apps from a FAT-formatted SD card. LIX is programmed onto the flash MMOD after the FPGA configuration image.
The source code for LIX is located in apps/lix.
Type help
to see a list of commands.
LIX loads user apps into memory at 0x40100000.
See apps/hello for an example application. You can create your own apps by making a copy of the apps/hello directory.
After compiling your app you can copy it to an SD card and run it from LIX:
lix> run myapps/hello.bin
You can also upload apps to LIX over the UART using the xfer utility.
If a file named BOOT.BIN is located in the root directory of the SD card it will be loaded into main memory and run automatically at boot time.
LIX also includes a simple Lisp interpreter.
Some usage examples:
lix> (+ 1 2 3 4 5)
[num:15.000000]
lix> (map (lambda (x) (* 2 x)) (list 1 2 3 4))
[list: [num:2.000000] [num:4.000000] [num:6.000000] [num:8.000000] ]
Display the environment:
lix> (dump)
Load a LISP program from the SD card:
lix> (load myfiles/lisp/hello.l)
The default configuration assumes that a USB-UART PMOD is connected to PMODB (or PMODA if the device only has one PMOD).
Begin | End | Size | Description |
---|---|---|---|
00000000 |
000017ff |
5120 - 6144 | BRAM (ZBL firmware) |
10000000 |
100007cf |
2000 | BRAM (video text memory) |
20000000 |
2fffffff |
38.4KB - 512KB | SRAM/SPRAM/BSRAM (framebuffer) |
40000000 |
4fffffff |
8MB - 64MB | HRAM/QQSPI/SDRAM (main memory) |
80000000 |
8fffffff |
- | MMOD (read-only flash memory) |
a0000000 |
afffffff |
- | Cartridge memory (Keks PMODA) |
e0000000 |
efffffff |
- | RPMEM |
f0000000 |
f0000000 |
1 | UART0 data register |
f0000004 |
f0000004 |
1 | UART0 control register |
f0001000 |
f0001000 |
1 | LED control register |
f0001100 |
f0001103 |
4 | RTC seconds counter register |
f0002000 |
f0002000 |
1 | SD card SPI register |
f0003000 |
f0003000 |
1 | PS/2 data register |
f0003004 |
f0003004 |
1 | PS/2 control register |
f0004000 |
f0004000 |
1 | UART1 data register |
f0004004 |
f0004004 |
1 | UART1 control register |
f0005000 |
f0005000 |
1 | left gamepad |
f0005004 |
f0005004 |
1 | right gamepad |
f0006000 |
f0006004 |
1 | delay for 1uS |
f000f000 |
f000ffff |
- | config registers |
When EN_GPU_FB
is enabled there is a 640x480 or 320x240 framebuffer at the beginning of the SRAM, depending on whether or not pixel doubling EN_GPU_FB_PIXEL_DOUBLING
is enabled.
Each byte in the framebuffer contains two pixels: XRGBXRGB. X is an unused bit.
The remaining SRAM is currently unused and available.
There is also an experimental 1bpp monochrome mode EN_GPU_FB_MONO
with a 1024x768 framebuffer.
There is a 80x25 character buffer in BRAM at 0x10000000. In monochrome mode, the character buffer is 128x48.
Writing an ASCII character to this video text memory will display it on the screen.
Text and graphics can be displayed at the same time.
Zucker is released under the Lone Dynamics Open License. This repo contains code from the PicoRV32 project, you can find its license in the rtl/cpu/picorv32 directory.