Compile time constants can also be passed as parameters to modules. This allows us to write a generic n-bit counter module, which takes n as a parameter:
MODULE nbit_counter(n,carry_in,clear,count,carry_out)
{
INPUT carry_in, clear : boolean;
OUTPUT count (n - 1)..0 : boolean;
OUTPUT carry_out : boolean;
bits : array (n - 1)..0;
carry : array n .. 0 of boolean;
for(i = 0; i < n; i = i + 1)
bits[i] : counter_bit(carry[i],clear,count[i],carry[i+1]);
carry_out := carry[n];
}
The ability to nest module instances inside conditionals even makes it possible to write recursively defined modules. For example, the following code builds an n-input ``or'' gate as a balanced tree of 2-input ``or'' gates:
MODULE or_n(n,inp,out)
{
INPUT inp : array 0..(n - 1) of boolean;
OUTPUT out : boolean;
case{
n = 1 : out := inp[0];
n = 2 : or2(inp[0],inp[1],out);
default: {
x,y : boolean;
or_n(n / 2, inp[0 .. (n / 2 - 1)], x);
or_n(n - n / 2, inp[(n / 2) .. n], y);
or_2(x,y,out);
}
}
}