\subsubsection{ZBus}
\index{ZBus@\te{ZBus} (package)}

{\bf Package}

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


{\bf Description}

BSV provides the \te{ZBus} library to allow users to implement and use
tri-state buses. Since BSV does not support high-impedance or
undefined values internally, the library encapsulates the tri-state
bus implementation in a module that can only be accessed through
predefined interfaces which do not allow direct access to internal
signals (which could potentially have high-impedance or undefined
values).

The Verilog implementation of the tri-state module includes a number
of primitive submodules that are implemented using Verilog tri-state
wires. The BSV representation of the bus, however, only models the
values of the bus at the associated interfaces and thus the need to
represent high-impedance or undefined values in BSV is avoided.

A ZBus consists of a series of clients hanging off of a bus.  The
combination of the client and the bus is provided by the
\te{ZBusDualIFC} interface which consists of 2 subinterfaces, the client
and the bus.  The client subinterface is provided by the
\te{ZBusClientIFC} interface.    The bus subinterface is provided by the
\te{ZBusBusIFC} interface.  The user never needs to manipulate the bus
side, this is all done internally.  The user builds the bus out of
\te{ZBusDualIFC}s and then drives values onto the bus and reads values
from the bus using the \te{ZBusClientIFC}.


{\bf Interfaces and Methods}

There are three interfaces are defined in this package;
\te{ZBusDualIFC}, \te{ZBusClientIFC}, and \te{ZBusBusIFC}.

The
\te{ZBusDualIFC} interface provides two subinterfaces; a
\te{ZBusBusIFC} and a \te{ZBusClientIFC}.
For a given bus, one \te{ZBusDualIFC} interface is associated with
each bus client.


\index{ZBusDualIFC@\te{ZBusDualIFC} (interface)}
\begin{center}
\begin{tabular}{|p{.9 in}|p{1.4 in}|p{3.0 in}|}
\hline
\multicolumn{3}{|c|}{ZBusDualIFC}\\
\hline
Name & Type & Description\\
\hline
\hline 
\te{busIFC}  & \te{ZBusBusIFC\#()} &The subinterface providing the
bus side of the ZBus. \\
\hline
\te{clientIFC}&\te{ZBusClientIFC\#(t)}&The subinterface providing the
client side to the ZBus. \\
\hline
\end{tabular}
\end{center}

\begin{libverbatim}
interface ZBusDualIFC #(type value_type) ;
   interface ZBusBusIFC#(value_type)    busIFC;
   interface ZBusClientIFC#(value_type) clientIFC;
endinterface
\end{libverbatim}


The \te{ZBusClientIFC} allows a BSV module to connect to the tri-state
bus.   The \te{drive} method is used to drive a value onto the bus.  The \te{get()} and \te{fromBusValid()} methods  allow
each  bus client to access the 
current value on the bus. If the bus is in an invalid state (i.e. has
a high-impedance value or an undefined value because it is being
driven by more than one client simultaneously), then the
\te{get()} method will return \te{0} and the
\te{fromBusValid()} method will return \te{False}.  In all other
cases, the \te{fromBusValid()} method will return \te{True} and the
\te{get()} method will return the current value of the bus.


\begin{center}
\begin{tabular}{|p{.9 in}|p{.7 in}|p{1.5 in}|p{.4in}|p{1.5 in}|}
\hline
\multicolumn{5}{|c|}{ZBusClientIFC}\\
\hline
\multicolumn{3}{|c|}{Method}&\multicolumn{2}{|c|}{Argument}\\
\hline
Name & Type & Description& Name &\multicolumn{1}{|c|}{Description} \\
\hline
\hline 
\te{drive}  & Action &Drives a current value on to the bus
&\te{value}&The value being put on the bus, datatype of \te{value\_type}.\\
\hline
\te{get}&\te{value\_type}&Returns the current value on
the bus.&&\\
\hline
\te{fromBusValid}&\te{Bool}&Returns \te{False}
if the bus has a high-impedance value or is undefined.&&\\
\hline
\end{tabular}
\end{center}

\index{ZBusClientIFC@\te{ZBusClientIFC} (interface)}
\begin{libverbatim}
interface ZBusClientIFC #(type value_type) ;
   method Action      drive(value_type value);
   method value_type  get();
   method Bool        fromBusValid();
endinterface
\end{libverbatim}

The \te{ZBusBusIFC} interface
connects to the bus structure itself using tri-state values.  This
interface is never accessed directly by the user.

\index{ZBusBusIFC@\te{ZBusBusIFC} (interface)}

% \begin{center}
% \begin{tabular}{|p{.9 in}|p{.4 in}|p{1.7 in}|p{.4in}|p{1.7 in}|}
% \hline
% \multicolumn{5}{|c|}{ZBusBusIFC}\\
% \hline
% \multicolumn{3}{|c|}{Method}&\multicolumn{2}{|c|}{Argument}\\
% \hline
% Name & Type & Description& Name &\multicolumn{1}{|c|}{Description} \\
% \hline
% \hline 
% \te{fromBusSample}  & Action &Reads a current value from the bus
% &\te{value}&The value being read on the bus, datatype of \te{t}.\\
% \cline{4-5}
% &&&\te{isValid}&If \te{False}, a high-impedance value is driven onto the bus.\\
% \hline
% \te{toBusValue}&\te{ZBit\#(t)}& Drives  a  current value on to
% the bus.&&\\
% \hline
% \te{fromBusCtl}&\te{Bool}&Indicates whether the current value is a
% high-impedance value.  &&\\
% \hline
% \end{tabular}
% \end{center}

\begin{libverbatim}
interface ZBusBusIFC #(type value_type) ;
   method Action      fromBusSample(ZBit#(value_type) value, Bool isValid);
   method ZBit#(t)    toBusValue();
   method Bool        toBusCtl();
endinterface
\end{libverbatim}

 

{\bf Modules and Functions}

The library  provides a module constructor function,
\te{mkZBusBuffer}, which allows the user to create a module which
provides the \te{ZBusDualIFC} interface.  This module provides
  the functionality of a tri-state buffer.  

\index{mkZBusBuffer@\te{mkZBusBuffer} (function)}
\begin{center}
\begin{tabular}{|p{1 in}|p{4.5 in}|}
 \hline
&\\
\te{mkZBusBuffer}  & Creates a module which provides the
\te{ZBusDualIFC} interface.\\
\cline{2-2}
&\begin{libverbatim}
module mkZBusBuffer (ZBusDualIFC #(value_type)) 
   provisos (Eq#(value_type), Bits#(value_type, size_value));
\end{libverbatim}
\\
\hline
\end{tabular}
\end{center}


The \te{mkZBus} module
constructor function takes a list of \te{ZBusBusIFC}
interfaces as arguments and creates a module which ties them all
together  in a bus.

\index{mkZBus@\te{mkZBus} (function)}
\begin{center}
\begin{tabular}{|p{1 in}|p{4.5 in}|}
 \hline
&\\
\te{mkZBus}  & Ties a list of \te{ZBusBusIFC} interfaces
together in a bus.\\
\cline{2-2}
&\begin{libverbatim}
module mkZBus#(List#(ZBusBusIFC#(value_type)) ifc_list)(Empty)
   provisos (Eq#(value_type), Bits#(value_type, size_value));
\end{libverbatim}
\\
\hline
\end{tabular}
\end{center}




{\bf Examples - ZBus}

Creating a tri-state buffer for a 32 bit signal.  The interface is  named \te{buffer\_0}.
\begin{libverbatim}
   ZBusDualIFC#(Bit#(32)) buffer_0(); 
   mkZBusBuffer inst_buffer_0(buffer_0);
\end{libverbatim}

Drive a value of \te{12} onto the associated bus.
\begin{libverbatim}
   buffer_0.clientIFC.drive(12);
\end{libverbatim}


The following code fragment demonstrates the use of the module \te{mkZBus}.
\begin{libverbatim}
   ZBusDualIFC#(Bit#(32)) buffer_0();
   mkZBusBuffer inst_buffer_0(buffer_0);

   ZBusDualIFC#(Bit#(32)) buffer_1();
   mkZBusBuffer inst_buffer_1(buffer_1);

   ZBusDualIFC#(Bit#(32)) buffer_2();
   mkZBusBuffer inst_buffer_2(buffer_2);

   List#(ZBusIFC#(Bit#(32))) ifc_list;

   bus_ifc_list = cons(buffer_0.busIFC,
                        cons(buffer_1.busIFC,
                             cons(buffer_2.busIFC,
                                       nil)));

   Empty bus_ifc();
   mkZBus#(bus_ifc_list) inst_bus(bus_ifc);
\end{libverbatim}
