package TRAM(TRAM(..), TRAMclient(..), TRAMreq(..), TRAMresp(..), tagRAM) where import FIFO import ClientServer import GetPut import RAM --@ The \te{TRAM} type represents a tagged RAM. It is similar --@ to the \te{RAM} interface, but each read request has an --@ additional tag that will be part of the response for a read. --@ \index{TRAM@\te{TRAM} (package)|textbf} --@ \index{TRAM@\te{TRAM} (type)|textbf} --@ \begin{libverbatim} --@ typedef Server#(TRAMreq#(tag, adr, dta), TRAMresp#(tag, dta)) --@ TRAM #(type tag, type adr, type dta); --@ \end{libverbatim} type TRAM tag adr dta = Server (TRAMreq tag adr dta) (TRAMresp tag dta) --@ \index{TRAMclient@\te{TRAMclient} (type)|textbf} --@ \begin{libverbatim} --@ typedef --@ Client#(TRAMreq#(tag, adr, dta), TRAMresp#(tag, dta)) --@ TRAMclient #(type tag, type adr, type dta); --@ \end{libverbatim} type TRAMclient tag adr dta = Client (TRAMreq tag adr dta) (TRAMresp tag dta) --@ \index{TRAMreq@\te{TRAMreq} (type)|textbf} --@ \begin{libverbatim} --@ typedef tagged union { --@ TRAMreqRead#(tag, adr, dta) Read; --@ TRAMreqWrite#(tag, adr, dta) Write; --@ } TRAMreq #(type tag, type adr, type dta) deriving (Eq, Bits); --@ --@ typedef struct { --@ tg tag; --@ adr address; --@ } TRAMreqRead #(type tg, type adr, type dta) deriving (Eq, Bits); --@ --@ typedef struct { --@ dta value; --@ adr address; --@ } TRAMreqWrite #(type tg, type adr, type dta) deriving (Eq, Bits); --@ \end{libverbatim} data TRAMreq tg adr dta = Read (tg, adr) | Write (adr, dta) deriving (Eq, Bits) --@ \index{TRAMresp@\te{TRAMresp} (type)|textbf} --@ \begin{libverbatim} --@ typedef struct { --@ tg tag; --@ dta value; --@ } TRAMresp #(type tg, type dta) deriving (Eq, Bits); --@ \end{libverbatim} type TRAMresp tg dta = (tg, dta) -- deriving (Eq, Bits) --@ \index{tagRAM@\te{tagRAM} (function)|textbf} --@ The \te{tagRAM} function converts a RAM to a TRAM by putting --@ a tag FIFO next to it. The FIFO size is specified by the --@ first argument. --@ \begin{libverbatim} --@ module tagRAM#(Integer sz, Module#(RAM#(adr, dta)) mkRAM)(TRAM#(tg, adr, dta)) --@ provisos (Bits#(tg, stg)); --@ \end{libverbatim} tagRAM :: (IsModule m c, Bits tg stg) => Integer -> m (RAM adr dta) -> m (TRAM tg adr dta) tagRAM sz mkRAM = module ram :: RAM adr dta <- mkRAM fifo :: FIFO tg <- mkSizedFIFO sz interface -- Server request = interface Put put :: TRAMreq tg adr dta -> Action put (Read (tag, address)) = action fifo.enq tag ram.request.put (RAM.Read address) put (Write (address, value)) = ram.request.put (RAM.Write (address, value)) response = interface Get get = do value <- ram.response.get fifo.deq return (fifo.first, value)