Spicy Expressions
The expressions discussed in the previous sections should feel familiar to hardware developers and software developers alike, but Spade also has a few expressions that are more unusual. Rust users can probably skip ahead, since these expressions are basically the same as in Rust. For everyone else, let’s talk about the more spicy 🌶️ expressions in Spade.
If Expressions
“Control flow” in Spade is handled a little bit different than what you may be used to, unless you’re coming from Rust or a functional programming background. In most languages you use an if expression to “conditionally” execute code if conditions happen. For example, an absolute value operation could be written as:
def abs(x):
result = x
if x < 0:
result = -x
return resultHowever, in hardware, there is no way to “conditionally execute” a block of code. Hardware can only compute all branches, and select the corresponding output at the end, typically using a multiplexer:
In order to reflect this, Spade is expression based and if expressions select values rather than conditionally execute branches. The above example would be written as:
Functions together with Entities together with fn and Defines a pipeline. The number in in the parentheses is input-to-output latency of the pipeline. are the basic building blocks of Spade circuits. Unlike fn, entity can contain registers and therefore have state and unlike Defines a pipeline. The number in in the parentheses is input-to-output latency of the pipeline., they do not have a statically known latency or Defines a pipeline. The number in in the parentheses is input-to-output latency of the pipeline. structure. and Defines a pipeline. The number in in the parentheses is input-to-output latency of the pipeline. are the basic building blocks of Spade circuits. Unlike entities and pipelines, functions have no internal state, they are combinational (pure). abs(x: Type used to represent signed integers. The generic parameter (<N>) specReturns the value of the first branch if the condition is true, otherwise the second branch.
Note that unlike software languages, Spade does not have conditional execution. You do not conditionally assign values inside if expressiosn, you compute a value and return it.ies the number of bits) -> Type used to represent signed integers. The generic parameter (<N>) specReturns the value of the first branch if the condition is true, otherwise the second branch.
Note that unlike software languages, Spade does not have conditional execution. You do not conditionally assign values inside if expressiosn, you compute a value and return it.ies the number of bits {
Returns the value of the first branch if the condition is true, otherwise the second branch.
Note that unlike software languages, Spade does not have conditional execution. You do not conditionally assign values inside if expressiosn, you compute a value and return it. x < 0 {
-x
} else {
x
}
}
where the output of the function is the result of the if expression, i.e. -x if x is negative, and x otherwise.
Conditionals being expressions means you can do some interesting things with them, for example, you can use them as parts of arithmetic:
let is used to define a variable. Spade infers the type of most variables from context, but you can also specReturns the value of the first branch if the condition is true, otherwise the second branch.
Note that unlike software languages, Spade does not have conditional execution. You do not conditionally assign values inside if expressiosn, you compute a value and return it.y the type with : <type> before the =. result = x + Returns the value of the first branch if the condition is true, otherwise the second branch.
Note that unlike software languages, Spade does not have conditional execution. You do not conditionally assign values inside if expressiosn, you compute a value and return it. add_one {1} else {0};This particular example is strange and probably ill-advised, but this sort of technique can come in handy.
Blocks
The other unusual expression Spade has is the block which we’ve seen some examples of already. The abs function above has 3 blocks but you may not have thought of them as blocks.
A block is written as {} which contains a list of statements (variables, assertions etc.), and an optional final expression as the value of the block itself.
For example:
let is used to define a variable. Spade infers the type of most variables from context, but you can also specReturns the value of the first branch if the condition is true, otherwise the second branch.
Note that unlike software languages, Spade does not have conditional execution. You do not conditionally assign values inside if expressiosn, you compute a value and return it.y the type with : <type> before the =. result = {
let is used to define a variable. Spade infers the type of most variables from context, but you can also specReturns the value of the first branch if the condition is true, otherwise the second branch.
Note that unlike software languages, Spade does not have conditional execution. You do not conditionally assign values inside if expressiosn, you compute a value and return it.y the type with : <type> before the =. sum = x + y;
sum * z
};This is effectively the same as writing let sum_prod = (x + y) * z but it allows you to break things into variables that are local to the block. This may seem strange at first, but hopefully makes more sense when you find out that these blocks are the bodies of both functions and if-expressions. For example you can of course define variables inside the body of if-expressions:
let is used to define a variable. Spade infers the type of most variables from context, but you can also specReturns the value of the first branch if the condition is true, otherwise the second branch.
Note that unlike software languages, Spade does not have conditional execution. You do not conditionally assign values inside if expressiosn, you compute a value and return it.y the type with : <type> before the =. result = Returns the value of the first branch if the condition is true, otherwise the second branch.
Note that unlike software languages, Spade does not have conditional execution. You do not conditionally assign values inside if expressiosn, you compute a value and return it. op1 {
let is used to define a variable. Spade infers the type of most variables from context, but you can also specReturns the value of the first branch if the condition is true, otherwise the second branch.
Note that unlike software languages, Spade does not have conditional execution. You do not conditionally assign values inside if expressiosn, you compute a value and return it.y the type with : <type> before the =. sum = x + y;
sum * z
} else {
x + z
};