logo Spade Blog

Spade 0.3.0

Posted 2023-06-01 by Frans Skarman

Today, we release Spade version 0.3.0. It comes with a few small fixes, and some major new features:

Dynamic Pipelining🔗

The biggest new feature is native support for stalling pipelines. Pipelines can be stalled by adding a condition for stalling to a stage as shown below:


If should_stall is true, the registers corresponding to this reg-statement will hold their current value, instead of getting a new one. Additionally, all stages before it will also stall, in order to not throw away any data.

When interacting with the outside world, it is of course important to know if a stage is ready to receive data, and if data in a stage is valid. This can be done using stage.valid and stage.ready.

For a full description of the feature, see https://docs.spade-lang.org/language_reference/dynamic_pipelines.html

Inverted Ports🔗

It is now possible to create inverted versions of port types, i.e. ports where mut wires non-mut wires are switched.

This is useful when wanting to create a port somewhere in between two units communicating with ports, and passing each end to one unit. To create such a port combination, the new port expression can be used.

As an example, here a port pair connecting a producer and a consumer is created:

entity top() {
    let (p, p_inv) = port;

    let _ = inst consumer(p);
    let _ = inst producer(p_inv)

entity consumer(p: P) -> bool {
    // ...

entity producer(p: ~P) -> bool {
    // ...

Experimental Word Length Inference🔗

The past few months, a master student has been working on adding better handling of word lengths to Spade, and with 0.3.0, an experimental version of that feature is included.

The new word length inference can be turned on using --infer-method to the compiler, or by setting the environment variable SPADE_INFER_METHOD. There are three word length inference methods available: Interval Arithmetic (IA), Affine Arithmetic (AA), and a mix of the two: (AAIA)

With one of these flags enabled, the compiler should infer tighter bounds on word lengths, and will require far trunc and sext calls. For example, it is now possible to write

a + b + c

without manual intervention.

More predictable names🔗

The last major change in this release is improvements to the names used in the output Verilog.

First, you can now use #[no_mangle] on unit arguments in addition to on the whole unit, allowing interop with more Verilog modules.

The names of signals being generated have also been improved. They are no longer globally unique, but this means that the names correspond more closely to the corresponding name in the source code. In fact, variables with no shadowing have the exact same name in the generated Verilog as they do in the source code.