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:
reg[should_stall];
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.