This is an old revision of the document!
Constructors for Types
There are cases when it is useful to be able to build more complex types from existing types. ACT provides a mechanism to do so via interfaces and parameter types.
Interfaces
An interface is defined in the following way:
interface linearchain (bool? in; bool! out);
This defines linearchain
to be an interface definition, where the interface has two ports: in
and out
.
Any process can export a list of interfaces. When a process exports an interface, it means that it has I/O ports that correspond to the names in the interface. The port names within the process need not match the port names in the interface; when an interface is exported, a mapping must be provided as part of the interface export specification.
defproc proc1 (bool? a; bool! b) :> linearchain { in -> a, out -> b } { ... }
In this definition, proc1
exports the linearchain
interface, except that the in
port of the interface is mapped to a
, and the out
port of the interface is mapped to b
. If multiple interfaces are exported, they are simply separated by commas.
Parameter types
Needs to be updated
The special ptype
meta-parameter type is used to pass in types
into a process definition. These types can be used to build a process
using other processes as building blocks. The syntax for using a
ptype
is the following:
ptype(foo) x;
This says that x
is a variable that is a type, with the
constraint that x
must satisfy the type signature specified by
interface foo
. In other words, x
is guaranteed to have the
ports corresponding to interface type foo
.
ptype
parameters can also be used in templates. Consider the
following example:
// A constructor for a datapath with W-bit ripple connections, and // where each component has an additional M inputs and one output // Interface definition template<pint W, pint M> interface bitslice (e1of2? rin[W]; e1of2! rout[W]; e1of2? in[M]; e1of2! out); // the constructor template<pint N, pint M, pint W, ptype(bitslice<W,M>) t> defproc build_dpath (e1of2? rin[W]; e1of2! rout[W]; e1of2? in[M*N]; e1of2! out[N]) { t x[N]; // array of type "t" that exports a bitslice<W,M> interface // ripple connections (i:N-1: x[i].rout=x[i+1].rin;) x[0].rin=rin; x[N-1].rout=rout; // i/o connections (i:N: x[i].in = in[i*M..(i+1)*M-1]; x[i].out=out[i]; ) } // A one-bit adder, that exports the bitslice interface defproc onebit (e1of2? in[2], rin[1]; e1of2! out, rout[1]) :> bitslice<1,2> { in -> in, rin -> rin, out -> out, rout -> rout } { ... } defproc ripple_adder (e1of2? a[32], b[32], cin; e1of2! out[32], cout) { build_dpath<32,2,1,@onebit> dp; (i : 32 : dp.in[2*i] = a[i]; dp.in[2*i+1] = b[i];) dp.out = out; dp.rin[0] = cin; dp.rout[0] = cout; }
Process type (ptype
) parameters for templates use the @
character (as in @onebit
) in the example above.