package FIFOF_ (FIFOF_(..), mkFIFOF_, mkFIFOF1_, mkSizedFIFOF_, mkLFIFOF_) where import Environment --@ This is an internal, undocumented package --@ To use FIFOs in BSV use the \te{FIFO} or \te{FIFOF} packages interface FIFOF_ a = enq :: a -> Action deq :: Action first :: a clear :: Action notFull :: Bool i_notFull :: Bool notEmpty :: Bool i_notEmpty :: Bool -- the i_ versions of the notFull and notEmpty signals are conflict-free -- with enq and deq so that the implicit conditions in a guarded FIFO -- (with or without explicit full and empty signals) -- do not create a conflict between enq and deq interface VFIFOF_ n = enq_ :: Bit n -> PrimAction deq_ :: PrimAction first_ :: Bit n clear_ :: PrimAction notFull_ :: Bit 1 i_notFull_ :: Bit 1 notEmpty_ :: Bit 1 i_notEmpty_ :: Bit 1 interface VFIFOF0_ = enq_ :: PrimAction deq_ :: PrimAction clear_ :: PrimAction notFull_ :: Bit 1 i_notFull_ :: Bit 1 notEmpty_ :: Bit 1 i_notEmpty_ :: Bit 1 -- Depth 1, width > 0 vMk1FIFOF :: Module (VFIFOF_ n) vMk1FIFOF = module verilog "FIFO1" (("depth",valueOf n)) "CLK" "RST_N" { enq_ = "D_IN"{reg} "ENQ"; deq_ = "DEQ"; first_ = "D_OUT"{reg}; notFull_ = "FULL_N"; i_notFull_ = "FULL_N"; notEmpty_ = "EMPTY_N"{reg}; i_notEmpty_ = "EMPTY_N"{reg}; clear_ = "CLR"; } [ enq_ <> [deq_, first_, i_notFull_, i_notEmpty_], deq_ <> [enq_, i_notFull_, i_notEmpty_], first_ < deq_, [notFull_, notEmpty_] < [enq_, deq_], [first_, notFull_, i_notFull_, notEmpty_, i_notEmpty_] <> [first_, notFull_, i_notFull_, notEmpty_, i_notEmpty_], [enq_, deq_, first_, notFull_, notEmpty_, clear_] < clear_, [i_notFull_, i_notEmpty_] <> clear_ ] -- Depth 1, width == 0 vMk1FIFOF0 :: Module VFIFOF0_ vMk1FIFOF0 = module verilog "FIFO10" "CLK" "RST_N" { enq_ = "ENQ"; deq_ = "DEQ"; notFull_ = "FULL_N"; i_notFull_ = "FULL_N"; notEmpty_ = "EMPTY_N"{reg}; i_notEmpty_ = "EMPTY_N"{reg}; clear_ = "CLR"; } [ enq_ <> [deq_, i_notFull_, i_notEmpty_], deq_ <> [enq_, i_notFull_, i_notEmpty_], [notFull_, notEmpty_] < [enq_, deq_], [notFull_, i_notFull_, notEmpty_, i_notEmpty_] <> [notFull_, i_notFull_, notEmpty_, i_notEmpty_], [enq_, deq_, notFull_, notEmpty_, clear_] < clear_, [i_notFull_, i_notEmpty_] <> clear_ ] -- Depth 1 mkFIFOF1_ :: (IsModule m, Bits a sa) => m (FIFOF_ a) mkFIFOF1_ = liftModule $ if valueOf sa == 0 && genVerilog then module _f :: VFIFOF0_ _f <- vMk1FIFOF0 interface enq x = fromPrimAction _f.enq_ deq = fromPrimAction _f.deq_ first = _ notFull = unpack _f.notFull_ i_notFull = unpack _f.i_notFull_ notEmpty = unpack _f.notEmpty_ i_notEmpty = unpack _f.i_notEmpty_ clear = fromPrimAction _f.clear_ else module _f :: VFIFOF_ sa _f <- vMk1FIFOF interface enq x = fromPrimAction (_f.enq_ (pack x)) deq = fromPrimAction _f.deq_ first = unpack _f.first_ notFull = unpack _f.notFull_ i_notFull = unpack _f.i_notFull_ notEmpty = unpack _f.notEmpty_ i_notEmpty = unpack _f.i_notEmpty_ clear = fromPrimAction _f.clear_ -- Depth 2, width > 0. vMk2FIFOF :: Module (VFIFOF_ n) vMk2FIFOF = module verilog "FIFO2" (("width",valueOf n)) "CLK" "RST_N" { enq_ = "D_IN" "ENQ"; deq_ = "DEQ"; first_ = "D_OUT"{reg}; notFull_ = "FULL_N"{reg}; i_notFull_ = "FULL_N"{reg}; notEmpty_ = "EMPTY_N"{reg}; i_notEmpty_ = "EMPTY_N"{reg}; clear_ = "CLR"; } [ enq_ <> [deq_, first_, i_notFull_, i_notEmpty_], deq_ <> [enq_, i_notFull_, i_notEmpty_], first_ < deq_, [notFull_, notEmpty_] < [enq_, deq_], [first_, notFull_, i_notFull_, notEmpty_, i_notEmpty_] <> [first_, notFull_, i_notFull_, notEmpty_, i_notEmpty_], [enq_, deq_, first_, notFull_, notEmpty_, clear_] < clear_, [i_notFull_, i_notEmpty_] <> clear_ ] -- Depth 2, width == 0. vMk2FIFOF0 :: Module VFIFOF0_ vMk2FIFOF0 = module verilog "FIFO20" "CLK" "RST_N" { enq_ = "ENQ"; deq_ = "DEQ"; notFull_ = "FULL_N"{reg}; i_notFull_ = "FULL_N"{reg}; notEmpty_ = "EMPTY_N"{reg}; i_notEmpty_ = "EMPTY_N"{reg}; clear_ = "CLR"; } [ enq_ <> [deq_, i_notFull_, i_notEmpty_], deq_ <> [enq_, i_notFull_, i_notEmpty_], [notFull_, notEmpty_] < [enq_, deq_], [notFull_, i_notFull_, notEmpty_, i_notEmpty_] <> [notFull_, i_notFull_, notEmpty_, i_notEmpty_], [enq_, deq_, notFull_, notEmpty_, clear_] < clear_, [i_notFull_, i_notEmpty_] < clear_ ] -- Depth 2. mkFIFOF2_ :: (IsModule m, Bits a sa) => m (FIFOF_ a) mkFIFOF2_ = liftModule $ if valueOf sa == 0 && genVerilog then module _f :: VFIFOF0_ _f <- vMk2FIFOF0 interface enq x = fromPrimAction _f.enq_ deq = fromPrimAction _f.deq_ first = _ notFull = unpack _f.notFull_ i_notFull = unpack _f.i_notFull_ notEmpty = unpack _f.notEmpty_ i_notEmpty = unpack _f.i_notEmpty_ clear = fromPrimAction _f.clear_ else module _f :: VFIFOF_ sa _f <- vMk2FIFOF interface enq x = fromPrimAction (_f.enq_ (pack x)) deq = fromPrimAction _f.deq_ first = unpack _f.first_ notFull = unpack _f.notFull_ i_notFull = unpack _f.i_notFull_ notEmpty = unpack _f.notEmpty_ i_notEmpty = unpack _f.i_notEmpty_ clear = fromPrimAction _f.clear_ -- default depth is 2 mkFIFOF_ :: (IsModule m, Bits a sa) => m (FIFOF_ a) mkFIFOF_ = mkFIFOF2_ -- Depth n, width > 0 -- log2 (n-1) is allowed since the Verilog model has a registered output -- which is not considered in the head/tail pointers size. vMkSizedNFIFOF :: Integer -> Module (VFIFOF_ sa) vMkSizedNFIFOF n = module verilog "SizedFIFO" (("width",valueOf sa),("depth", n), ("cntr_width",log2 (n-1))) "CLK" "RST_N" { enq_ = "D_IN" "ENQ"; deq_ = "DEQ"; first_ = "D_OUT"{reg}; notFull_ = "FULL_N"{reg}; i_notFull_ = "FULL_N"{reg}; notEmpty_ = "EMPTY_N"{reg}; i_notEmpty_ = "EMPTY_N"{reg}; clear_ = "CLR"; } [ enq_ <> [deq_, first_, i_notFull_, i_notEmpty_], deq_ <> [enq_, i_notFull_, i_notEmpty_], first_ < deq_, [notFull_, notEmpty_] < [enq_, deq_], [first_, notFull_, i_notFull_, notEmpty_, i_notEmpty_] <> [first_, notFull_, i_notFull_, notEmpty_, i_notEmpty_], [enq_, deq_, first_, notFull_, notEmpty_, clear_] < clear_, [i_notFull_, i_notEmpty_] <> clear_ ] -- Depth n, width == 0 vMkSizedNFIFOF0 :: Integer -> Module VFIFOF0_ vMkSizedNFIFOF0 n = module verilog "SizedFIFO0" (("depth",n), ("cntr_width",log2 (n+1))) "CLK" "RST_N" { enq_ = "ENQ"; deq_ = "DEQ"; notFull_ = "FULL_N"{reg}; i_notFull_ = "FULL_N"{reg}; notEmpty_ = "EMPTY_N"{reg}; i_notEmpty_ = "EMPTY_N"{reg}; clear_ = "CLR"; } [ enq_ <> [deq_, i_notFull_, i_notEmpty_], deq_ <> [enq_, i_notFull_, i_notEmpty_], [notFull_, notEmpty_] < [enq_, deq_], [notFull_, i_notFull_, notEmpty_, i_notFull_] <> [notFull_, i_notFull_, notEmpty_, i_notFull_], [enq_, deq_, notFull_, notEmpty_, clear_] < clear_, [i_notFull_, i_notEmpty_] <> clear_ ] -- Depth n mkSizedNFIFOF_ :: (IsModule m, Bits a sa) => Integer -> m (FIFOF_ a) mkSizedNFIFOF_ n = liftModule $ if valueOf sa == 0 && genVerilog then module _f :: VFIFOF0_ _f <- vMkSizedNFIFOF0 n interface enq x = fromPrimAction _f.enq_ deq = fromPrimAction _f.deq_ first = _ notFull = unpack _f.notFull_ i_notFull = unpack _f.i_notFull_ notEmpty = unpack _f.notEmpty_ i_notEmpty = unpack _f.i_notEmpty_ clear = fromPrimAction _f.clear_ else module _f :: VFIFOF_ sa _f <- vMkSizedNFIFOF n interface enq x = fromPrimAction (_f.enq_ (pack x)) deq = fromPrimAction _f.deq_ first = unpack _f.first_ notFull = unpack _f.notFull_ i_notFull = unpack _f.i_notFull_ notEmpty = unpack _f.notEmpty_ i_notEmpty = unpack _f.i_notEmpty_ clear = fromPrimAction _f.clear_ mkSizedFIFOF_ :: (IsModule m, Bits a sa) => Integer -> m (FIFOF_ a) mkSizedFIFOF_ 0 = error "sized fifo created with depth 0!" mkSizedFIFOF_ 1 = mkFIFOF1_ mkSizedFIFOF_ 2 = mkFIFOF_ mkSizedFIFOF_ n = mkSizedNFIFOF_ n -- XXX loopy FIFOs need to be thought through more carefully -- one attempt below -- Depth 1, width > 0, loopy vMkL1FIFOF :: Module (VFIFOF_ n) vMkL1FIFOF = module verilog "FIFOL1" (("depth",valueOf n)) "CLK" "RST_N" { enq_ = "D_IN"{reg} "ENQ"; deq_ = "DEQ"; first_ = "D_OUT"{reg}; notFull_ = "FULL_N"; i_notFull_ = "FULL_N"; notEmpty_ = "EMPTY_N"{reg}; i_notEmpty_ = "EMPTY_N"{reg}; clear_ = "CLR"; } [ enq_ <> [first_, deq_, i_notFull_, i_notEmpty_], deq_ <> [enq_, i_notEmpty_], first_ < deq_, [enq_, deq_] < [notEmpty_, notFull_], deq_ < i_notFull_, [first_, notFull_, i_notFull_, notEmpty_, i_notEmpty_] <> [first_, notFull_, i_notFull_, notEmpty_, i_notEmpty_], [enq_, deq_, first_, notFull_, i_notFull_, notEmpty_, clear_] < clear_, i_notEmpty_ <> clear_ ] -- Depth 1, width == 0, loopy vMkL1FIFOF0 :: Module VFIFOF0_ vMkL1FIFOF0 = module verilog "FIFOL10" "CLK" "RST_N" { enq_ = "ENQ"; deq_ = "DEQ"; notFull_ = "FULL_N"; i_notFull_ = "FULL_N"; notEmpty_ = "EMPTY_N"{reg}; i_notEmpty_ = "EMPTY_N"{reg}; clear_ = "CLR"; } [ enq_ <> [deq_, i_notFull_, i_notEmpty_], deq_ <> [enq_, i_notEmpty_], [enq_, deq_] < [notFull_, notEmpty_], deq_ < i_notFull_, [notFull_, i_notFull_, notEmpty_, i_notEmpty_] <> [notFull_, i_notFull_, notEmpty_, i_notEmpty_], [enq_, deq_, notFull_, i_notFull_, notEmpty_, clear_] < clear_, i_notEmpty_ <> clear_ ] -- Depth 1, loopy mkLFIFOF_ :: (IsModule m, Bits a sa) => m (FIFOF_ a) mkLFIFOF_ = liftModule $ if valueOf sa == 0 && genVerilog then module _f :: VFIFOF0_ _f <- vMkL1FIFOF0 interface enq x = fromPrimAction _f.enq_ deq = fromPrimAction _f.deq_ first = _ notFull = unpack _f.notFull_ i_notFull = unpack _f.i_notFull_ notEmpty = unpack _f.notEmpty_ i_notEmpty = unpack _f.i_notEmpty_ clear = fromPrimAction _f.clear_ else module _f :: VFIFOF_ sa _f <- vMkL1FIFOF interface enq x = fromPrimAction (_f.enq_ (pack x)) deq = fromPrimAction _f.deq_ first = unpack _f.first_ notFull = unpack _f.notFull_ i_notFull = unpack _f.i_notFull_ notEmpty = unpack _f.notEmpty_ i_notEmpty = unpack _f.i_notEmpty_ clear = fromPrimAction _f.clear_