Using Swim

Run swim init <project name> to create a new project in a subdirectory named <project name>. It'll setup a basic project to serve as a jumping-off point.

To compile the Spade code to verilog, run swim build or swim b. This will build the Spade compiler and compile your code to build/spade.sv.

swim help will list the builtin swim subcommands. Here is a short excerpt:

Commands:
  build         [aliases: b]
  synth         [aliases: syn]
  pnr           [aliases: p]
  upload        [aliases: u]
  simulate      [aliases: sim, test, t]
  init          Initialise a new swim project in the specified directory. Optionally copies from a template
  update        Updates all external dependencies that either have a set branch or tag, or hasn't been downloaded locally
  update-spade
  restore       Restore (discard) changes made to git-dependencies (including the compiler)
  clean
  help          Print this message or the help of the given subcommand(s)

For reference projects for configuration see swim-templates.

Custom subcommands

swim also supports custom subcommands as follows: if there is a binary named swim-xxx in your path, then calling swim xxx arg1 arg2 will dispatch to swim-xxx arg1 arg2. We have a list of known community subcommands like cargo's own community subcommand wiki -- if you've made one, feel free to add it!

Simulation and test benches

Swim supports running test benches for your code. Before you do so, you must add a few lines to swim.toml

[simulation]
testbench_dir = "test"

Test benches are currently written in Verilog, place your test benches in a directory called test. Swim will build and run each Verilog file in that directory separately, and if the exit code of the simulator is 0, the test is considered successful.

Finally, run swim test to test your code.

For sample projects for configuration see swim-templates.

Synthesis, place and route

Swim can also simulate and synthesise your project using yosys and nextpnr. Ensure those are installled, then add sections for [synthesis] and [pnr] to your config file. The exact options you need to specify depend on the architecture, but swim should tell you which fields you need to set. As an example, here is the synthesis configuration for an ECP5 based FPGA

[synthesis]
top = "e_main"
verilog.source = []
command = "synth_ecp5"

[pnr]
architecture = "ecp5"
device = "LFE5UM-85F"
pin_file = "pins.lpf"
package = "CABGA381"

To synthesise your code, call swim synth and to place and route, call swim pnr. Swim will make sure the prerequisite steps are performed for you, so if your end goal is pnr, you can call swim pnr directly.

For sample projects for configuration, see swim-templates.

Upload

Swim can also upload your code for a few FPGAs. To get started, add an [upload] section to your config. Like synthesis, the exact options depend on your target, so let the error messages from swim guide the configuration.

To upload, call swim upload.

Templates

If you're using a supported board you can copy a template repository which contains a project that's ready to upload. Check available boards with swim init --list-boards and then swim init --board <board>.

A note on the Spade compiler and submodules

As Spade is still early in development, it is useful to have each project pinned to a specific compiler version, rather than having a global copy of the compiler. This means that it will still build in the future even if breaking changes are made to the language.

By default, Swim tracks the compiler version in a file called swim.lock that is created on the first build. It is probably a good idea to track this using git or another VCS. If you want to update to the newest version of the Spade compiler, run swim update-spade and commit the updated swim.lock.

If you prefer keeping your own submodule (perhaps you want to do your own changes to the compiler?), you can also setup a path dependency and track it like any other submodule. For example:

git submodule add https://gitlab.com/spade-lang/spade.git spade
git commit -m "Add Spade submodule"

And then, instruct Swim to use a path to the compiler instead by changing your swim.toml to this:

compiler = { path = "spade" }

Using another compiler branch

You can depend on a specific branch by setting the compiler-field in your swim.toml:

compiler = { git = "https://gitlab.com/spade-lang/spade.git", branch = "another-branch" }

After setting the field, run swim update-spade to update the pinned compiler.

You can also change the repository, if you wish.

Using a global Spade compiler

If you prefer using a global compiler, you can set the compiler field to point to an absolute path to the root directory for a local Spade compiler repository:

compiler = { path = "/path/to/spade-repo" }

You can read more about configurating Swim in the docs.

Debugging spadec

In rare cases where you want to attach a debugger to the Spade compiler, you can use --debug-spadec