\subsubsection{ClientServer} \index{ClientServer@\te{ClientServer} (package)} \label{lib-clientserver} {\bf Package} \begin{verbatim} import ClientServer :: * ; \end{verbatim} {\bf Description} The \te{ClientServer} package provides two interfaces, \te{Client} and \te{Server} which can be used to define modules which have a request-response type of interface. The \te{GetPut} package must be imported when using this package because the \te{Get} and \te{Put} interface types are used. \index{Client@\te{Client} (interface)} {\bf Interfaces and methods} The interfaces \te{Client} and \te{Server} can be used for modules that have a request-response type of interface (e.g. a RAM). The server accepts requests and generates responses, the client accepts responces and generates requests. There are no assumptions about how many (if any) responses a request generates \begin{tabular}{|l|l|l|l|} \hline \multicolumn{4}{|c|}{Interfaces}\\ \hline Interface Name & Parameter name & Parameter Description & Restrictions \\ \hline \hline \te{Client}&\it{req\_type}&type of the client request &must be in the Bits class\\ \cline{2-4} &\it{resp\_type}&type of the client response &must be in the Bits class\\ \hline \te{Server}&\it{req\_type}&type of the server request &must be in the Bits class\\ \cline{2-4} &\it{resp\_type}&type of the server response &must be in the Bits class\\ \hline \end{tabular} {\tt Client} The \te{Client} interface provides two subinterfaces, \te{request} and \te{response}. From a \te{Client}, one \te{gets} a request and \te{puts} a response. \begin{center} \begin{tabular}{|p{1 in}|p{1.2 in}|p{2.9 in}|} \hline \multicolumn{3}{|c|}{Client SubInterface}\\ \hline Name & Type & Description \\ \hline \hline \te{request} &\te{Get\#(req\_type)} &the interface through which the outside world retrieves (gets) a request\\ \hline \te{response} &\te{Put\#(resp\_type)} &the interface through which the outside world returns (puts) a response\\ \hline \end{tabular} \end{center} \begin{libverbatim} interface Client#(type req_type, type resp_type); interface Get#(req_type) request; interface Put#(resp_type) response; endinterface: Client \end{libverbatim} {\tt Server} The \te{Server} interface provides two subinterfaces, \te{request} and \te{response}. From a \te{Server}, one \te{puts} a request and \te{gets} a response. \begin{center} \begin{tabular}{|p{1 in}|p{1.2 in}|p{2.9 in}|} \hline \multicolumn{3}{|c|}{Server SubInterface}\\ \hline Name & Type & Description \\ \hline \hline \te{request} &\te{Put\#(req\_type)} &the interface through which the outside world returns (puts) a request\\ \hline \te{response} &\te{Get\#(resp\_type)} &the interface through which the outside world retrieves (gets) a response\\ \hline \end{tabular} \end{center} \index{Server@\te{Server} (interface)} \begin{libverbatim} interface Server#(type req_type, type resp_type); interface Put#(req_type) request; interface Get#(resp_type) response; endinterface: Server \end{libverbatim} {\tt ClientServer} A \te{Client} can be connected to a \te{Server} and vice versa. The \te{request} (which is a \te{Get} interface) of the client will connect to \te{response} (which is a \te{Put} interface) of the \te{Server}. By making the \te{ClientServer} tuple an instance of the \te{Connectable} typeclass, you can connect the \te{Get} of the client to the \te{Put} of the server, and the \te{Put} of the client to the \te{Get} of the server. \begin{libverbatim} instance Connectable#(Client#(req_type, resp_type), Server#(req_type, resp_type)); instance Connectable#(Server#(req_type, resp_type), Client#(req_type, resp_type)); \end{libverbatim} This \te{Tuple2} can be redefined to be called \te{ClientServer} \begin{libverbatim} typedef Tuple2#(Client#(req_type, resp_type), Server#(req_type,resp_type)) ClientServer#(type req_type, type resp_type); \end{libverbatim} {\bf Example Connecting a bus to a target} \begin{libverbatim} interface Bus_Ifc; interface Server#(RQ, RS) to_initor ; interface Client#(RQ, RS) to_targ; endinterface typedef Server#(RQ, RS) Target_Ifc; typedef Client#(RQ, RS) Initiator_Ifc; module mkSys (Empty); // Instantiate subsystems Bus_Ifc bus <- mkBus; Target_Ifc targ <- mkTarget; Initiator_Ifc initor <- mkInitiator; // Connect bus and targ (to_targ is a Client ifc, targ is a Server ifc) Empty x <- mkConnection (bus.to_targ, targ); // Connect bus and initiator (to_initor is a Server ifc, initor is a Client ifc) mkConnection (bus.to_initor, initor); // Since mkConnection returns an interface of type Empty, it does // not need to be specified (but may be as above) ... endmodule: mkSys \end{libverbatim} {\bf Functions} The \te{ClientServer} package includes functions which return a \te{Client} interface or a \te{Server} interface from separate request and response interfaces taken as arguments. The argument interfaces must be able to be converted to \te{Get} and \te{Put} interfaces, as indicated by the \te{ToGet} and \te{ToPut} provisos. \index{toGPClient@\te{toGPClient} (function)} \index[function]{ClientServer!toGPClient} \begin{center} \begin{tabular}{|p{.7 in}|p{5.4 in}|} \hline & \\ \te{toGPClient}&Function that returns a \te{Client} interface from two arguments (request and response interfaces). The arguments must be able to be converted to \te{Get} and \te{Put} interfaces.\\ \cline{2-2} & \begin{libverbatim} function Client#(req_type, resp_type) toGPClient(req_ifc_type req_ifc, resp_ifc_type resp_ifc) provisos (ToGet#(req_ifc_type, req_type), ToPut#(resp_ifc_type, resp_type)); \end{libverbatim} \\ \hline \end{tabular} \end{center} \index{toGPServer@\te{toGPServer} (function)} \index[function]{ClientSefiforver!toGPServer} \begin{center} \begin{tabular}{|p{.7 in}|p{5.4 in}|} \hline & \\ \te{toGPServer}&Function that returns a \te{Server} interface from two arguments (request and response interfaces). The arguments must be able to be converted to \te{Get} and \te{Put} interfaces.\\ \cline{2-2} & \begin{libverbatim} function Server#(req_type, resp_type) toGPServer(req_ifc_type req_ifc, resp_ifc_type resp_ifc) provisos (ToPut#(req_ifc_type, req_type), ToGet#(resp_ifc_type,resp_type)); \end{libverbatim} \\ \hline \end{tabular} \end{center}