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