Creating a Project.

It is strongly advised to use the Swim build tool to write Spade projects. It manages rebuilding the spade compiler, including the standard library and dependencies, testing and synthesis etc.

If you haven't installed swim already, do so by following the installation instructions.

After you have swim installed, we should create a new project. The easiest way to do this is to run swim init --board <fpga name>. To get a list of the boards we currently have templates for, run

swim init --list-boards

which should give you something like

Cloning into '/tmp/swim-templates'...
remote: Enumerating objects: 135, done.
remote: Counting objects: 100% (50/50), done.
remote: Compressing objects: 100% (49/49), done.
remote: Total 135 (delta 11), reused 0 (delta 0), pack-reused 85
Receiving objects: 100% (135/135), 30,73 KiB | 30,73 MiB/s, done.
Resolving deltas: 100% (37/37), done.
[INFO] Available boards:
ecpix5
go-board
icesugar-nano
tinyfpga-bx
ulx3s_85k

If your FPGA board is not on the list, you can also set up your project manually, but that's out of scope for this guide. Have a look at the templates repository for inspiration.

For this project, the exact board isn't super important. I like my ecpix5 so I will use that. Create the project using

swim init --board ecpix5 ws2812b

Note that it is likely that this project, being a library to drive specific hardware should be a library, not a standalone project, it is still useful to initialise it targeting a specific FPGA board in order to test in hardware it later.

Basic project layout

Inside the newly created directory we find the following files:

  • ecpix5.lpf
  • openocd-ecpix5.cfg
  • src
    • main.spade
    • top.v
  • swim.toml

FPGA specific files

The ecpix5.lpf file is a pin mapping file which tells the synthesis tool what physical pins correspond to the inputs and outputs from our top module.

If you are using a ice40 based FPGA, this file is instead a pcf file which has the same purpose but different syntax.

We'll get back to this file when it is time to test on hardware

The openocd-ecpix5.cfg file is a file needed to program the FPGA. It is specific to the ecpix5 programmer and you don't really have to care what it does or why it is needed.

Since spade is a very work in progress language with breaking changes being very common, it's easiest to have each project depend on a specific git version of the compiler. This is handled by swim, which will track a specific compiler version for us.1 The first time we build the project using swim, it will download and compile the compiler.

Since the compilation process takes quite a while the first time you run it, now is a good time to call swim build

The src directory contains our spade source code. Each file is given a unique namespace based on the name, so anything you define inside main.spade will be under the namespace ws2812b::main::<unit name>.

Finally, there is the swim.toml file which describes our project

name = "ws2812b"

[synthesis]
top = "top"
command = "synth_ecp5"

[board]
name = "ecpix-5"
pin_file = "ecpix5.lpf"
config_file = "openocd-ecpix5.cfg"

The name is, as you might expect, the name of your project. If another project depends on your project, this is the namespace at which your project will reside.

The synthesis, pnr, upload, and packing fields tell swim what tools to call to synthesise the project and upload it to the board. Most things can be ignored here, but the top field is worth knowing about, as that is how you specify the top module (roughly equivalent to main in most software languages).

1

You can read more about this in the swim README.

Basic swim usage

Swim has several subcommands which you can use. These commands call their prerequisites so you only have to call the one you actually want to run. I.e. you don't have to call swim build before swim test.

swim build

Compiles your spade code to verilog. The output ends up in build/spade.sv

swim synth, swim pnr

Call the synthesis tool and place and route tool respectively.

swim upload

Build the project and upload it to the board

swim test

Run simulation to test your code. Note that by default, your project does not contain any test benches, so this will complain. We'll write some later in the guide.

Aliases

Most of these commands have aliases that you can use to be lazy and avoid typing.

  • b: build
  • syn: synthesise
  • u: upload
  • t, sim: test

In the next section, we will start discussing how to talk to the LEDs.