Spade 0.19.0
Posted 2026-05-28 by The Spade Developers
Today we release Spade v0.19.0, a release which contains a lot of small improvements to the language along with the launch of https://reef.spade-lang.org/, a package index for Spade libraries.
Reef
Spade has accumulated quite a few libraries, from essentials like ready/valid handshaking to common protocols like UART, SPI and I2C, to whole Risc-V cores. However, discovery of these libraries has been hard as they are simply spread out across random git repositories.
https://reef.spade-lang.org/ solves this by being a searchable central index of Spade packages. In addition, we build documentation for all the packages using spadedoc to make it easier to understand and use the packages.
Copy views
If you have worked with inv wires or ports in Spade before, you may have noticed that there was no way to receive a value containing inv without also consuming it, making inspecting values difficult. With copy views (&T) you can accept a read-only version of the non-inverted wires in T.
You can read the underlying values with *, analogous to references in Rust.
include_bytes! and macro foundations
With the newly introduced include_bytes! macro, you can define the value of a [uint<8>; N] array from an external file, improving readability and making it easier to generate ROM content.
With include! you can include a Spade code from another file, which is also helpful when generating code externally. It is worth noting that you normally want to use mod and use for importing files in order to have proper namespacing, include! should only be used in rare cases.
These two constructs are macros, denoted by !. For now, we do not support user generated macros, but these changes lay the foundation for a macro system in Spade.
Better inv generics
We have lifted a few restrictions on primitive functions operating on inv wires which means that std::conv::transmute can now transmute between ports. [T;N]::concat now works when T is a port, and we have added a transpose method to [inv T; N] which transforms it into inv [T; N] and the other way around.
Default (hacky edition)
We have added a new Default trait which you can implement to specify what a default value for a type is. This is useful for generic code where you need a placeholder default fallback value.
Note that this is currently implemented as a member method that gets called on undef(), until we add support for static methods which is planned for the next release
port is dead, long live port()
The old port keyword has been replaced with an intrinsic function with the same name. This is more consistent with the rest of the language.
Octal literals
In addition to hexadecimal and decimal literals, you can now write octal literals as 0o...
Swim improvements
Finally, swim has also received some improvements
- There is now a
flake.nixfor the nix users among us. - Added an
extra_argsfield to the pnr section to allow specifying arguments tonextpnr - There is now a
test_apidirectory which gets imported by all cocotb testbenches, allowing you to re-use test infrastructure