Functions
Virdant allows you to define functions.
Functions are reusable snippets of combinational logic. They may be used anywhere in a design.
Functions are declared with the fn keyword:
fn max(x : Word[8], y : Word[8]) -> Word[8] {
if x->lt(y) {
x
} else {
y
}
}
The name and type of each parameter is given in a comma-separated list, and the return type is given after the arrow.
The body of the function definition is a single expression which may make use of the parameters.
To call a function, we do so as you would in math class: max(a, b),
where a and b can be any two expressions of the proper type.
Even when a function is only used in one place, it still provides two key benefits. First, they allow you to name a piece of logic in a way that is meaningful to anyone who reads your code. And second, it can be used to guarantee that a given result depends only on the arguments you pass to it. This is especially useful when both the module definition and the function body grow large and complicated.
Here is a complete example that shows a module that always outputs the larger byte it has seen on its input:
1fn max(x : Word[8], y : Word[8]) -> Word[8] {
2 if x->lt(y) {
3 x
4 } else {
5 y
6 }
7}
8
9mod Top {
10 incoming clock : Clock;
11 incoming reset : Bit;
12 incoming inp : Word[8];
13 outgoing max_seen : Word[8];
14
15 reg max_seen_reg : Word[8] on clock;
16
17 max_seen_reg <= if reset {
18 0
19 } else {
20 max(max_seen_reg, inp)
21 };
22
23 max_seen := max_seen_reg;
24}