package RAM(RAM, RAMclient, RAMreq(..)) where import ClientServer --@ \subsubsection{\te{RAM} and \te{TRAM}} --@ \index{RAM@\te{RAM} (package)|textbf} --@ --@ The \te{RAM} type is used for various types of memories. --@ The memory is a \te{Server} which accepts read or write requests. --@ A read request will generate a response containing the read data. --@ The latency for a \te{RAM} is arbitrary, it does not even have to --@ be a fixed latency. --@ --@ Note, the types of the address and data are arbitrary. --@ \index{RAM@\te{RAM} (type)|textbf} --@ \begin{libverbatim} --@ typedef Server#(RAMreq#(adr, dta), dta) RAM #(type adr, type dta); --@ \end{libverbatim} type RAM adr dta = Server (RAMreq adr dta) dta --@ \index{RAMclient@\te{RAMclient} (type)|textbf} --@ \begin{libverbatim} --@ typedef Client#(RAMreq#(adr, dta), dta) RAMclient #(type adr, type dta); --@ \end{libverbatim} type RAMclient adr dta = Client (RAMreq adr dta) dta --@ \index{RAMreq@\te{RAMreq} (type)|textbf} --@ \begin{libverbatim} --@ typedef union tagged { --@ adr Read; --@ Tuple2#(adr, dta) Write; --@ } RAMreq #(type adr, type dta) deriving (Eq, Bits); --@ \end{libverbatim} data RAMreq adr dta = Read adr | Write (adr, dta) deriving (Eq) instance (Bits adr sa, Bits dta sd, Add sa sd sz1, Add sz1 1 sz) => Bits (RAMreq adr dta) sz where pack (Read adr) = (0 :: Bit 1) ++ (pack adr) ++ _ pack (Write (adr, dta)) = (1 :: Bit 1) ++ (pack adr) ++ (pack dta) unpack bits = let (first, rest) = (split bits) :: (Bit 1, Bit sz1) (adr, dta) = (split rest) :: (Bit sa, Bit sd) in if (first == (0 :: Bit 1)) then Read (unpack adr) else Write (unpack adr, unpack dta)