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); } } }