Package import"zappem.net/pub/io/pico2ice"
Documentationhttps://pkg.go.dev/zappem.net/pub/io/pico2ice
Sourceshttps://github.com/tinkerator/pico2ice

pico2ice - a tinygo package to support pico2ice features

Overview

The pico2-ice board features a RP2350B microcontroller and a iCE40UP5K FPGA. This package provides some APIs for setting up these devices.

Example program

Light up the pico2-ice onboard LEDs including the use of the hello.bin FPGA bitstream logic.

Perform the following:

$ git clone https://github.com/tinkerator/pico2ice.git
$ cd pico2ice/examples
$ ~/go/bin/tinygo flash -target=pico2-ice -scheduler tasks cram.go && ~/go/bin/tinygo monitor
Connected to /dev/ttyACM0. Press Ctrl-C to exit.
Hello, World!
FPGA program running (flashing FPGA Blue LED)
Blinking the RP Tricolor LEDs randomly

Once flashed, the RP2350B starts running and briefly flashes the Red RP LED while the cram-load of the hello.bin FPGA bitstream is injected into the FPGA. When this is successful, a Green LED illuminates to indicate that the FPGA is programmed. The cram.go program then lets the FPGA logic run causing it to rapidly flash its Blue LED. After this, and indefinitely, the cram.go code randomly flashes one color at a time of the RP2350B connected Tricolor LED.

The pio.go file

Part of the pico2ice package is generated code. The input for this generation is the collection of .pio files in the pio/ directory:

To rebuild the pio.go file (assuming that you are in the pico2ice/examples directory), do the following:

$ cd ../../
$ git clone https://github.com/tinkerator/pious.git
$ cd pious
$ go install examples/piocli.go

This downloads the pious package sources and installs the built tool in ~/go/bin/piocli. Go back to the pico2ice sources and run this tool:

$ cd ../pico2ice
$ ~/go/bin/piocli --src=pio/spi.pio,pio/clock.pio --name pico2ice --tinygo > pio.go

This shouldn’t cause the file to change, but you can review if it has with:

$ git diff pio.go

The hello.bin file

The examples/hello.bin file is an FPGA bitfile for the ice40 chip on the pico2-ice board. It is built from a verilog file present in the v/ directory.

Generating the hello.bin file

To convert v/hello.v into a hello.bin file we use the yosys toolchain. Specifically the tools yosys, nextpnr-ice40 and icepack.

NOTE on Fedora, these tools are to be found in the yosys, icestorm and nextpnr packages. On Debian, these tools are to be found in the yosys, fpga-icestorm and nextpnr packages.

In the v/ working directory do the following to rebuild the hello.bin file:

$ yosys -p "synth_ice40 -top top -json hello.json" hello.v
$ nextpnr-ice40 --up5k  --package sg48 --json hello.json --pcf hello.pcf --asc hello.asc
$ icepack hello.asc hello.bin

If you want to replace the default build of this file with the one made above, you can do this:

$ cp hello.bin ../examples

comm.v

A more ambitious verilog file is v/comm.v. This pays attention to runtime attempts by the cram.go code to control the FPGA LED from the RP2350B microcontroller program. Namely, its attempts to set the FPGA LED with an SPI command from the microcontroller code. To build and install this FPGA bitfile, cd v/ and run the following commands:

$ yosys -p "synth_ice40 -top top -json hello.json" comm.v
$ nextpnr-ice40 --up5k  --package sg48 --json hello.json --pcf hello.pcf --asc hello.asc
$ icepack hello.asc hello.bin
$ cp hello.bin ../examples

Then, from the ../examples directory, this command will generate some output like this (9 wrote + read values will be displayed):

$ ~/go/bin/tinygo flash -target=pico2-ice -scheduler tasks cram.go && ~/go/bin/tinygo monitor
Connected to /dev/ttyACM0. Press Ctrl-C to exit.
Hello, World!
FPGA program running (flashing FPGA Blue LED)
Blinking the RP Tricolor LEDs randomly
wrote: 2  read: 0
wrote: 4  read: 2
wrote: 1  read: 4
wrote: 2  read: 1
wrote: 4  read: 2
wrote: 1  read: 4
wrote: 2  read: 1
wrote: 4  read: 2
wrote: 1  read: 4

and will cause the FPGA to mirror the last set microcontroller LED color. The 9 read values here should match the prior line’s write value. The 0 initially read value is just reflecting the fact that the reset value is 0 for the 3 bit FPGA LED setting.

Simulating the hello.v logic

Typically, to simulate logic, you have some test wrapper for that logic. In the hello.v case we have included the hello_test.v file. To perform that test, we use the Icarus Verilog suite. Most specifically, the iverilog and vvp tools. We can also use GTKWave (the gtkwave tool).

NOTE on Fedora and Debian, these tools are to be found in the iverilog and gtkwave packages.

To build the test binary (generate a.out) and run it do the following:

$ iverilog hello_test.v hello.v
$ ./a.out
VCD info: dumpfile dump.vcd opened for output.
end of test

You can view this dump.vcd file with GTKWave, and also with the twave tool. To only look at the top level signals with that text based tool we can do the following:

$ ~/go/bin/twave --file dump.vcd --syms hello_test.top.clk,hello_test.reset,hello_test.red,hello_test.green,hello_test.blue
[] : [$version Icarus Verilog $end]
                hello_test.green-+
                  hello_test.red-|-+
                 hello_test.blue-|-|-+
                hello_test.reset-|-|-|-+
              hello_test.top.clk-|-|-|-|-+
                                 | | | | |
2025-11-08 15:29:26.000000000000 1 1 x x x
2025-11-08 15:29:26.000000010000 1 1 x 1 0
2025-11-08 15:29:26.000000020000 1 1 x 1 0
2025-11-08 15:29:26.000000030000 1 1 x 1 1
2025-11-08 15:29:26.000000040000 1 1 x 0 1
2025-11-08 15:29:26.000000050000 1 1 x 0 0
2025-11-08 15:29:26.000000060000 1 1 x 0 0
2025-11-08 15:29:26.000000070000 1 1 0 0 1
2025-11-08 15:29:26.000000080000 1 1 0 0 1
2025-11-08 15:29:26.000000090000 1 1 0 1 0
2025-11-08 15:29:26.000000100000 1 1 0 1 0
2025-11-08 15:29:26.000000110000 1 1 0 1 1
2025-11-08 15:29:26.000000120000 1 1 0 1 1
2025-11-08 15:29:26.000000130000 1 1 0 1 0
2025-11-08 15:29:26.000000140000 1 1 0 1 0
2025-11-08 15:29:26.000000150000 1 1 0 1 1
2025-11-08 15:29:26.000000160000 1 1 0 1 1
2025-11-08 15:29:26.000000170000 1 1 0 1 0
2025-11-08 15:29:26.000000180000 1 1 0 1 0
2025-11-08 15:29:26.000000190000 1 1 0 1 1
2025-11-08 15:29:26.000000200000 1 1 0 1 1
2025-11-08 15:29:26.000000210000 1 1 0 1 0
2025-11-08 15:29:26.000000220000 1 1 0 1 0
2025-11-08 15:29:26.000000230000 1 1 1 1 1
2025-11-08 15:29:26.000000240000 1 1 1 1 1
2025-11-08 15:29:26.000000250000 1 1 1 1 0
2025-11-08 15:29:26.000000260000 1 1 1 1 0
2025-11-08 15:29:26.000000270000 1 1 1 1 1
2025-11-08 15:29:26.000000280000 1 1 1 1 1
2025-11-08 15:29:26.000000290000 1 1 1 1 0
2025-11-08 15:29:26.000000300000 1 1 1 1 0
2025-11-08 15:29:26.000000310000 1 1 1 1 1
2025-11-08 15:29:26.000000320000 1 1 1 1 1
2025-11-08 15:29:26.000000330000 1 1 1 1 0
2025-11-08 15:29:26.000000340000 1 1 1 1 0
2025-11-08 15:29:26.000000350000 1 1 1 1 1
2025-11-08 15:29:26.000000360000 1 1 1 1 1
2025-11-08 15:29:26.000000370000 1 1 1 1 0
2025-11-08 15:29:26.000000380000 1 1 1 1 0
2025-11-08 15:29:26.000000390000 1 1 0 1 1
2025-11-08 15:29:26.000000400000 1 1 0 1 1

This list of bit values over time tracks the clock starting up, the logic reset and eventually the Blue LED starting to toggle on and off.

Installing the developer version of tinygo

The default tinygo package might be very old, and not include support for the pico2-ice board. To remedy this, you can install a fresh compile of the tinygo dev branch.

On Fedora install some packages (the first expands to most of the needed dependencies):

$ sudo dnf install tinygo clang-devel

On Debian, any go version older than 1.22 will not build. In truth, I’ve not yet been able to build tinygo on a Debian system (have only tried Bookworm 12). My best guess is. Install a better go revision. Also, install these dependencies:

$ sudo apt install llvm-dev libclang-dev

Then:

$ git clone https://github.com/tinygo-org/tinygo.git
$ cd tinygo/
$ git checkout dev
$ git submodule update --init --recursive
$ make llvm-source
$ make gen-device

The final step depends on which Linux distribution version you have:

Linux distribution command
Fedora 41 $ go install --tags llvm19
Fedora 42 $ go install --tags llvm20
Fedora 43 $ go get tinygo.org/x/go-llvm && go install --tags llvm21
Debian 12 (bookworm) ? $ go install --tags llvm20

Then, to verify that the program installed correctly:

$ ~/go/bin/tinygo

TODO

Nothing planned. Currently, the tinygo code cannot take advantage of the dual core nature of the RP2350B chip because of tinygo bug 4974 there is also some issue with llvm21. At some point those problems will be fixed and these instructions will drop the use of the -scheduler tasks compilation flags.

Support

This is a personal project aiming at exploring the capabilities of the pico2-ice board. As such, no support can be expected. That being said, if you find a bug, or want to request a feature, use the github pico2ice bug tracker.

License information

See the LICENSE file: the same BSD 3-clause license as that used by golang itself.


Markdown rendering courtesy of gomarkdown/markdown.