package FIFOF (FIFOF(..), mkFIFOF, mkFIFOF1, mkSizedFIFOF, mkLFIFOF, mkLSizedFIFOF, mkUGFIFOF, mkUGFIFOF1, mkUGSizedFIFOF, mkUGLFIFOF, mkUGLSizedFIFOF, mkGFIFOF, mkGFIFOF1, mkGSizedFIFOF, mkGLFIFOF, mkGLSizedFIFOF, mkDepthParamFIFOF, mkUGDepthParamFIFOF, mkGDepthParamFIFOF, mkDepthParamLFIFOF, mkUGDepthParamLFIFOF, mkGDepthParamLFIFOF ) where import FIFOF_ --@ \subsubsection{FIFOF} --@ --@ \index{FIFOF@\te{FIFOF} (package)|textbf} --@ The \te{FIFOF} interface is for FIFOs with explicit full and empty --@ signals. The standard version of FIFOF has FIFOs with the enq, --@ deq and first methods guarded by the appropriate (notFull or notEmpty) --@ implicit condition for safety and improved scheduling. Unguarded (UG) --@ versions of FIFOF are available for the rare cases when implicit conditions are --@ not desired. --@ \index{FIFOF@\te{FIFOF} (type)|textbf} --@ \begin{libverbatim} --@ interface FIFOF #(type a); --@ method Action enq(a x1); --@ method Action deq(); --@ method a first(); --@ method Bool notFull(); --@ method Bool notEmpty(); --@ method Action clear(); --@ endinterface: FIFOF --@ \end{libverbatim} interface FIFOF a = enq :: a -> Action deq :: Action first :: a notFull :: Bool notEmpty :: Bool clear :: Action instance (FShow a) => FShow (FIFOF a) where fshow ifc = case (ifc.notEmpty, ifc.notFull) of ( True, True) -> fshow ifc.first; ( True, False) -> (fshow ifc.first) + (fshow " ") + (fshow "FULL") (False, _) -> $format "EMPTY" fifof_ToFifof :: FIFOF_ a -> FIFOF a fifof_ToFifof f = interface FIFOF enq x = f.enq x when f.i_notFull deq = f.deq when f.i_notEmpty first = f.first when f.i_notEmpty clear = f.clear notFull = f.notFull notEmpty = f.notEmpty fifof_ToUGFifof :: FIFOF_ a -> FIFOF a fifof_ToUGFifof f = interface FIFOF enq x = f.enq x deq = f.deq first = f.first clear = f.clear notFull = f.i_notFull notEmpty = f.i_notEmpty fifof_ToGFifof :: Bool -> Bool -> FIFOF_ a -> FIFOF a fifof_ToGFifof ugenq ugdeq f = interface FIFOF enq x = f.enq x when ugenq || f.i_notFull deq = f.deq when ugdeq || f.i_notEmpty first = f.first when ugdeq || f.i_notEmpty clear = f.clear notFull = f.i_notFull notEmpty = f.i_notEmpty --@ Make a FIFO of the default depth (currently 2). --@ Note: when the FIFO is full it does {\em not} allow simultaneous enqueue --@ and dequeue operations. --@ \index{mkFIFOF@\te{mkFIFOF} (module)|textbf} --@ \begin{libverbatim} --@ module mkFIFOF(FIFOF#(a)) --@ provisos (Bits#(a, as)); --@ \end{libverbatim} mkFIFOF :: (IsModule m c, Bits a as) => m (FIFOF a) mkFIFOF = do {-# hide #-} _f :: FIFOF_ a <- mkFIFOF_ True return (fifof_ToFifof _f) --@ Make a FIFO of depth 1. --@ Note: when the FIFO is full it does {\em not} allow simultaneous enqueue --@ and dequeue operations (nor, of course, when it is empty). --@ \index{mkFIFOF1@\te{mkFIFOF1} (module)|textbf} --@ \begin{libverbatim} --@ module mkFIFOF1(FIFOF#(a)) --@ provisos (Bits#(a, as)); --@ \end{libverbatim} mkFIFOF1 :: (IsModule m c, Bits a as) => m (FIFOF a) mkFIFOF1 = do {-# hide #-} _f :: FIFOF_ a <- mkFIFOF1_ True return (fifof_ToFifof _f) --@ Make a FIFO of the given depth --@ Note: when the FIFO is full it does {\em not} allow simultaneous enqueue --@ and dequeue operations. The FIFO depth argument should be $> 0$. --@ \index{mkSizedFIFOF@\te{mkSizedFIFOF} (module)|textbf} --@ \begin{libverbatim} --@ module mkSizedFIFOF#(Integer n)(FIFOF#(a)) --@ provisos (Bits#(a, as)); --@ \end{libverbatim} mkSizedFIFOF :: (IsModule m c, Bits a as) => Integer -> m (FIFOF a) mkSizedFIFOF 0 = error "mkSizedFifo called with depth 0!" mkSizedFIFOF n = do {-# hide #-} _f :: FIFOF_ a <- mkSizedFIFOF_ n True return (fifof_ToFifof _f) --@ Make a ``loopy'' FIFO of the default depth (currently 1). --@ Note: With this FIFO, dequeue and enqueue can be simultaneously --@ applied in the same clock cycle when the FIFO is full. --@ (This is because of the feedthrough from the \te{deq} enable signal to the --@ \te{enq} ready signal.) --@ The dequeue operation makes room for the enqueue. --@ As a result, deq sequences before enq. --@ \index{mkLFIFOF@\te{mkLFIFOF} (module)|textbf} --@ \begin{libverbatim} --@ module mkLFIFOF(FIFOF#(a)) --@ provisos (Bits#(a, as)); --@ \end{libverbatim} mkLFIFOF :: (IsModule m c, Bits a as) => m (FIFOF a) mkLFIFOF = do {-# hide #-} _f :: FIFOF_ a <- mkLFIFOF_ return (fifof_ToFifof _f) --@ Make a ``loopy'' FIFO of the given depth --@ Note: With this FIFO, dequeue and enqueue can be simultaneously --@ applied in the same clock cycle when the FIFO is full. --@ (This is because of the feedthrough from the \te{deq} enable signal to the --@ \te{enq} ready signal.) --@ The dequeue operation makes room for the enqueue. --@ As a result, deq sequences before enq. --@ \index{mkLSizedFIFOF@\te{mkLSizedFIFOF} (module)|textbf} --@ \begin{libverbatim} --@ module mkLSizedFIFOF#(Integer n)(FIFOF#(a)) --@ provisos (Bits#(a, as)); --@ \end{libverbatim} mkLSizedFIFOF :: (IsModule m c, Bits a as) => Integer -> m (FIFOF a) mkLSizedFIFOF 0 = error "mkLSizedFIFOF called with depth 0!" mkLSizedFIFOF n = do {-# hide #-} _f :: FIFOF_ a <- mkLSizedFIFOF_ n return (fifof_ToFifof _f) --@ Make an ``Un-Guarded'' fifo of default size 2. During rule and --@ method processing the implicit conditions for correct fifo operation --@ are NOT considered. That is, with an unguared fifo, it is --@ possible to enqueue when full, and to dequeue when empty. Three --@ variations are given which parallel the modules above. --@ \index{mkUGFIFOF@\te{mkUGFIFOF} (module)|textbf} --@ \begin{libverbatim} --@ module mkUGFIFOF(FIFOF#(a)) --@ provisos (Bits#(a, as)); --@ \end{libverbatim} mkGFIFOF :: (IsModule m c, Bits a as) => Bool -> Bool -> m (FIFOF a) mkGFIFOF ugenq ugdeq = do {-# hide #-} _f :: FIFOF_ a <- mkFIFOF_ True return (fifof_ToGFifof ugenq ugdeq _f) --@ \index{mkUGFIFOF1@\te{mkUGFIFOF1} (module)|textbf} --@ \begin{libverbatim} --@ module mkUGFIFOF1(FIFOF#(a)) --@ provisos (Bits#(a, as)); --@ \end{libverbatim} mkGFIFOF1 :: (IsModule m c, Bits a as) => Bool -> Bool -> m (FIFOF a) mkGFIFOF1 ugenq ugdeq = do _f :: FIFOF_ a <- mkFIFOF1_ True return (fifof_ToGFifof ugenq ugdeq _f) --@ \index{mkUGSizedFIFOF@\te{mkUGSizdeFIFOF} (module)|textbf} --@ \begin{libverbatim} --@ module mkUGSizeFIFOF(FIFOF#(a)) --@ provisos (Bits#(a, as)); --@ \end{libverbatim} mkGSizedFIFOF :: (IsModule m c, Bits a as) => Bool -> Bool -> Integer -> m (FIFOF a) mkGSizedFIFOF ugenq ugdeq n = do {-# hide #-} _f :: FIFOF_ a <- mkSizedFIFOF_ n True return (fifof_ToGFifof ugenq ugdeq _f) --@ \index{mkUGLFIFOF@\te{mkUGLFIFOF} (module)|textbf} --@ \begin{libverbatim} --@ module mkUGLFIFOF(FIFOF#(a)) --@ provisos (Bits#(a, as)); --@ \end{libverbatim} mkGLFIFOF :: (IsModule m c, Bits a as) => Bool -> Bool -> m (FIFOF a) mkGLFIFOF ugenq ugdeq = do {-# hide #-} _f :: FIFOF_ a <- mkLFIFOF_ return (fifof_ToGFifof ugenq ugdeq _f) --@ \index{mkGLSizedFIFOF@\te{mkGLSizedFIFOF} (module)|textbf} --@ \begin{libverbatim} --@ module mkGLSizedFIFOF#(Integer n)(FIFOF#(a)) --@ provisos (Bits#(a, as)); --@ \end{libverbatim} mkGLSizedFIFOF :: (IsModule m c, Bits a as) => Bool -> Bool -> Integer -> m (FIFOF a) mkGLSizedFIFOF _ _ 0 = error "mkGLSizedFIFOF called with depth 0!" mkGLSizedFIFOF ugenq ugdeq n = do {-# hide #-} _f :: FIFOF_ a <- mkLSizedFIFOF_ n return (fifof_ToGFifof ugenq ugdeq _f) --@ \index{mkUGFIFOF@\te{mkUGFIFOF} (module)|textbf} --@ \begin{libverbatim} --@ module mkUGFIFOF(FIFOF#(a)) --@ provisos (Bits#(a, as)); --@ \end{libverbatim} mkUGFIFOF :: (IsModule m c, Bits a as) => m (FIFOF a) mkUGFIFOF = do {-# hide #-} _f :: FIFOF_ a <- mkFIFOF_ False return (fifof_ToUGFifof _f) --@ \index{mkUGFIFOF1@\te{mkUGFIFOF1} (module)|textbf} --@ \begin{libverbatim} --@ module mkUGFIFOF1(FIFOF#(a)) --@ provisos (Bits#(a, as)); --@ \end{libverbatim} mkUGFIFOF1 :: (IsModule m c, Bits a as) => m (FIFOF a) mkUGFIFOF1 = do {-# hide #-} _f :: FIFOF_ a <- mkFIFOF1_ False return (fifof_ToUGFifof _f) --@ \index{mkUGSizedFIFOF@\te{mkUGSizdeFIFOF} (module)|textbf} --@ \begin{libverbatim} --@ module mkUGSizeFIFOF(FIFOF#(a)) --@ provisos (Bits#(a, as)); --@ \end{libverbatim} mkUGSizedFIFOF :: (IsModule m c, Bits a as) => Integer -> m (FIFOF a) mkUGSizedFIFOF n = do {-# hide #-} _f :: FIFOF_ a <- mkSizedFIFOF_ n False return (fifof_ToUGFifof _f) --@ \index{mkUGLFIFOF@\te{mkUGLFIFOF} (module)|textbf} --@ \begin{libverbatim} --@ module mkUGLFIFOF(FIFOF#(a)) --@ provisos (Bits#(a, as)); --@ \end{libverbatim} mkUGLFIFOF :: (IsModule m c, Bits a as) => m (FIFOF a) mkUGLFIFOF = do {-# hide #-} _f :: FIFOF_ a <- mkLFIFOF_ return (fifof_ToUGFifof _f) --@ \index{mkUGLSizedFIFOF@\te{mkUGLSizedFIFOF} (module)|textbf} --@ \begin{libverbatim} --@ module mkUGLSizedFIFOF#(Integer n)(FIFOF#(a)) --@ provisos (Bits#(a, as)); --@ \end{libverbatim} mkUGLSizedFIFOF :: (IsModule m c, Bits a as) => Integer -> m (FIFOF a) mkUGLSizedFIFOF 0 = error "mkUGLSizedFIFOF called with depth 0!" mkUGLSizedFIFOF n = do {-# hide #-} _f :: FIFOF_ a <- mkLSizedFIFOF_ n return (fifof_ToUGFifof _f) mkDepthParamFIFOF :: (IsModule m c, Bits a as) => UInt 32 -> m (FIFOF a) mkDepthParamFIFOF n = do {-# hide #-} _f :: FIFOF_ a <- mkDepthParamFIFOF_ n True return (fifof_ToFifof _f) mkUGDepthParamFIFOF :: (IsModule m c, Bits a as) => UInt 32 -> m (FIFOF a) mkUGDepthParamFIFOF n = do {-# hide #-} _f :: FIFOF_ a <- mkDepthParamFIFOF_ n False return (fifof_ToUGFifof _f) mkGDepthParamFIFOF :: (IsModule m c, Bits a as) => Bool -> Bool -> UInt 32 -> m (FIFOF a) mkGDepthParamFIFOF ugenq ugdeq n = do {-# hide #-} _f :: FIFOF_ a <- mkDepthParamFIFOF_ n True return (fifof_ToGFifof ugenq ugdeq _f) mkDepthParamLFIFOF :: (IsModule m c, Bits a as) => UInt 32 -> m (FIFOF a) mkDepthParamLFIFOF n = do {-# hide #-} _f :: FIFOF_ a <- mkDepthParamLFIFOF_ n return (fifof_ToFifof _f) mkUGDepthParamLFIFOF :: (IsModule m c, Bits a as) => UInt 32 -> m (FIFOF a) mkUGDepthParamLFIFOF n = do {-# hide #-} _f :: FIFOF_ a <- mkDepthParamLFIFOF_ n return (fifof_ToUGFifof _f) mkGDepthParamLFIFOF :: (IsModule m c, Bits a as) => Bool -> Bool -> UInt 32 -> m (FIFOF a) mkGDepthParamLFIFOF ugenq ugdeq n = do {-# hide #-} _f :: FIFOF_ a <- mkDepthParamLFIFOF_ n return (fifof_ToGFifof ugenq ugdeq _f)