\subsubsection{UniqueWrappers}
\index{Wrapper@\te{Wrapper} (interface type)}
%\index{func@\te{func} (\te{UniqueWrapper} interface method)}
\index{mkUniqueWrapper@\te{mkUniqueWrappers} (\te{UniqueWrappers} module)}

{\bf Package}

\begin{verbatim}
import UniqueWrappers :: * ;
\end{verbatim}


{\bf Description}

The \te{UniqueWrappers} package takes a piece of combinational logic which is to be
shared and puts it into its own protective shell or  \emph{wrapper} to
prevent  its
duplication.   This is used in instances where a separately synthesized
 module is not possible.   It
 allows the designer to use a piece of logic at several places in a
 design without duplicating it at each site.  

There are times where it is desired to use a piece of logic at several places in a design,
but it is too bulky or otherwise expensive to duplicate at each site.
Often the right thing to do is to make the piece of logic into a
separately synthesized module -- then, if this module is instantiated only
once, it will not be duplicated, and the tool will automatically generate the
scheduling and multiplexing logic to share it among the sites which use its
methods.  Sometimes, however, this is not convenient.  One reason might be
that the logic is to be incorporated into a submodule of the design which is
itself polymorphic -- this will probably cause difficulties in observing the
constraints necessary for a module which is to be separately synthesized.  And
if a module is \emph{not} separately synthesized, the tool will inline its logic
freely wherever it is used, and thus duplication will not be prevented as
desired. 

This package covers the case where the logic to be shared is
combinational and cannot be put into a separately synthesized module.
It may be thought of as surrounding this combinational function with a
protective shell, a \emph{unique wrapper}, which will prevent its duplication.  The
module \te{mkUniqueWrapper} takes a one-argument function as a parameter; both the
argument type \te{a} and the result type \te{b} must be representable
as bits,  that is,
they must both be in the \te{Bits} typeclass.  

{\bf Interfaces}


% \begin{center}
% \begin{tabular}{|p{.5in}|p{.7in}|p{1.5 in}|p{.4in}|p{1 in}|}
% \hline
% \multicolumn{5}{|c|}{\te{Wrapper} Interface}\\
% \hline
% \multicolumn{3}{|c|}{Method}&\multicolumn{2}{|c|}{Arguments}\\
% \hline
% Name & Type & Description& Name &\multicolumn{1}{|c|}{Description} \\
% \hline
% \hline 
% \te{func}&\te{ActionValue}&\\
% \hline
% \end{tabular}
% \end{center}

The \te{UniqueWrappers} package provides an interface, \te{Wrapper}, with one
actionvalue method, \te{func}, which takes an argument of type \te{a} and
produces  a
method of type \te{ActionValue\#(b)}.  If the module is instantiated only once,
the logic implementing its parameter will be instantiated just once; the
module's method may, however, be used freely at several places.

Although the function supplied as the parameter is purely combinational and does
not change state, the method is of type \te{ActionValue}.  This is
because  actionvalue methods have \te{enable} signals and these
signals are needed to organize the scheduling and multiplexing
between the calling sites.

Variants of the interface \te{Wrapper}  are also provided for handling
 functions of two or three arguments; the interfaces have one and two
extra parameters respectively.  In each case the result type is the final
parameter, following however many argument type parameters are required.


% It might be wondered why the method is an actionvalue: after all, actionvalues
% usually involve side-effects, and the logic of the parameter function is
% purely combinational.  But claiming, and then releasing, a unique resource is
% a form of side-effect, albeit a temporary one.  Another way of looking at it
% is to observe that actionvalue methods have \te{ENABLE} signals; and such a signal
% is needed by the tool for organizing the scheduling and multiplexing between
% the calling sites.

% \begin{center}
% \begin{tabular}{|p{1.2 in}|p{4 in}|}
% \hline
% \multicolumn{2}{|c|}{Wrapper Interfaces}\\
% \hline
% Name& Description\\
% \hline
% \hline
% \te{Wrapper}&Takes a single argument type parameter and provides an
% interface with a single \te{ActionValue} method. \\
% \hline
% \te{Wrapper2}&Takes two parameters as arguments and provides an
% interface  with a single \te{ActionValue} method with a single parameter.\\
% \hline
% \te{Wrapper3}& Takes  three parameters as arguments and provides an
% interface  with a single \te{ActionValue} method with a single parameter.\\
% \hline
% \end{tabular}
% \end{center}


\begin{tabular}{|p{.6 in}|p{5.0 in}|}
\hline
\multicolumn{2}{|c|}{Wrapper Interfaces}\\
\hline
&\\
\te{Wrapper}& This interface has one
actionvalue method, \te{func}, which takes an argument of type \te{a\_type}
and produces an actionvalue of type \te{ActionValue\#(b\_type)}. \\
\cline{2-2}
&\begin{libverbatim}
interface Wrapper#(type a_type, type b_type);
  method ActionValue#(b_type) func (a_type x);
\end{libverbatim}
\\
\hline
\end{tabular}

\begin{tabular}{|p{.6 in}|p{5 in}|}
\hline
&\\
\te{Wrapper2}& Similar to the \te{Wrapper} interface,
but it takes two arguments.  \\
\cline{2-2}
& \begin{libverbatim}
interface Wrapper2#(type a1_type, type a2_type, type b_type);
  method ActionValue#(b_type) func (a1_type x, a2_type y);
\end{libverbatim}
\\
\hline
\end{tabular}

\begin{tabular}{|p{.6 in}|p{5 in}|}
\hline
&\\
\te{Wrapper3}&  Similar to the \te{Wrapper} interface,
but it takes three arguments. \\
\cline{2-2}
&\begin{libverbatim}
interface Wrapper3#(type a1_type, type a2_type, type a3_type, 
                    type b_type);
  method ActionValue#(b_type) func (a1_type x, a2_type y, a3_type z);
\end{libverbatim} 
\\
\hline
\end{tabular}


{\bf Modules}

The interfaces \te{Wrapper},
\te{Wrapper2}, and \te{Wrapper3} are provided by the modules
\te{mkUniqueWrapper}, \te{mkUniqueWrapper2}, and
\te{mkUniqueWrapper3}.  These modules vary only in the number of
aguments in  the parameter function.

If a function has more than three arguments, it can always be
rewritten or wrapped as one which takes the arguments as a single tuple; thus
the one-argument version \te{mkUniqueWrapper} can be used with this function. 



\begin{tabular}{|p{.5 in}|p{5.1 in}|}
\hline
\multicolumn{2}{|l|}{}\\
\multicolumn{2}{|l|}{\te{mkUniqueWrapper} }\\
\hline
&\\
& Takes a function, \te{func}, with a single parameter \te{x} and provides
the  interface \te{Wrapper}. \\
\cline{2-2}
& \begin{libverbatim}
module mkUniqueWrapper#(function b_type func(a_type x))
                       (Wrapper#(a_type, b_type))
   provisos (Bits#(a_type, sizea), Bits#(b_type, sizeb));
\end{libverbatim}
\\
\hline
\end{tabular}



\begin{tabular}{|p{.5 in}|p{5.1 in}|}
\hline
\multicolumn{2}{|l|}{}\\
\multicolumn{2}{|l|}{\te{mkUniqueWrapper2} }\\
\hline
&\\
&  Takes a function, \te{func}, with a two parameters,  \te{x} and \te{y}, and provides
the  interface \te{Wrapper2}. \\
\cline{2-2}
& \begin{libverbatim}
module mkUniqueWrapper2#(function b_type func(a1_type x, a2_type y))
                        (Wrapper2#(a1_type, a2_type, b_type))
   provisos (Bits#(a1_type, sizea1), Bits#(a2_type, sizea2), 
             Bits#(b_type, sizeb));
\end{libverbatim}
\\
\hline
\end{tabular}


\begin{tabular}{|p{.5in}|p{5.1in}|}
\hline
\multicolumn{2}{|l|}{}\\
\multicolumn{2}{|l|}{\te{mkUniqueWrapper3}}\\
\hline
&\\
&Takes a function, \te{func}, with a three parameters,  \te{x}, \te{y}, and
\te{z}, and provides the  interface \te{Wrapper3}. \\
\cline{2-2}
& \begin{libverbatim}
module mkUniqueWrapper3#(function b_type 
                           func(a1_type x, a2_type y, a3_type z))
                        (Wrapper3#(a1_type, a2_type, a3_type, b_type))
   provisos (Bits#(a1_type, sizea1), Bits#(a2_type, sizea2), 
             Bits#(a3_type, sizea3), Bits#(b_type, sizeb));
\end{libverbatim}
\\
\hline
\end{tabular}

{\bf Example: Complex Multiplication}
\begin{verbatim}
// This module defines a single hardware multiplier, which is then
// used by multiple method calls to implement complex number
// multiplication (a + bi)(c + di)

typedef Int#(18) CFP;

module mkComplexMult1Fifo( ArithOpGP2#(CFP) ) ;
  FIFO#(ComplexP#(CFP))  infifo1 <- mkFIFO;
  FIFO#(ComplexP#(CFP))  infifo2 <- mkFIFO;
  let arg1 = infifo1.first ;
  let arg2 = infifo2.first ;

  FIFO#(ComplexP#(CFP))  outfifo <- mkFIFO;

  Reg#(CFP)  rr <- mkReg(0) ;
  Reg#(CFP)  ii <- mkReg(0) ;
  Reg#(CFP)  ri <- mkReg(0) ;
  Reg#(CFP)  ir <- mkReg(0) ;

  // Declare and instantiate an interface that takes 2 arguments, multiplies them
  // and returns the result.  It is a Wrapper2 because there are 2 arguments.
  Wrapper2#(CFP,CFP, CFP) smult <- mkUniqueWrapper2( \* ) ;

  // Define a sequence of actions
  // Since smult is a UnqiueWrapper the method called is smult.func 
  Stmt multSeq =
  seq
     action
        let mr <- smult.func( arg1.rel,  arg2.rel ) ;
        rr <= mr ;
     endaction
     action
        let mr <- smult.func( arg1.img, arg2.img ) ;
        ii <= mr ;
     endaction
     action
        // Do the first add in this step
        let mr <- smult.func( arg1.img,  arg2.rel ) ;
        ir <= mr ;
        rr <= rr - ii ;
     endaction
     action
        let mr <- smult.func( arg1.rel, arg2.img );
        ri <= mr ;
        // We are done with the inputs so deq the in fifos
        infifo1.deq ;
        infifo2.deq ;
     endaction
     action
        let ii2 = ri + ir ;
        let res = Complex{ rel: rr , img: ii2 } ;
        outfifo.enq( res ) ;
     endaction
  endseq;

  // Now convert the sequence into a FSM ;
  //  Bluespec can assign the state variables, and pick up implict
  //  conditions of the actions
  FSM multfsm <- mkFSM(multSeq);
  rule startFSM;
     multfsm.start;
  endrule
endmodule 
\end{verbatim}
