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.

XXX: this section not yet implemented

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 foo. In other words, x is guaranteed to support all the operations supported by 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 M inputs and one output

// A skeleton
template<pint W, pint M>
defproc 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];

   // 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[i*M..(i+1)*M-1] = in[i*M..(i+1)*M-1];
          x[i].out=out[i] )
}

// A one-bit adder
defproc onebit (e1of2? in[2], rin[1]; e1of2! out, rout[1]) { ... }

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
}