package RegFile(RegFile(..), mkRegFile, mkRegFileFull, mkRegFileWCF, mkRegFileLoad, mkRegFileFullLoad, mkRegFileWCFLoad, mkRegFileLoadHex, mkRegFileFullLoadHex, mkRegFileWCFLoadHex, mkRegFileLoadBin, mkRegFileFullLoadBin, mkRegFileWCFLoadBin ) where import ConfigReg import List --@ \subsubsection{RegFile} --@ This package implements a 5-read-port 1-write-port array module. RegFiles --@ may be indexed by any type in the \te{Bits} class: since the package uses a --@ Verilog primitive module, the actual indexing is done with the bit --@ representations; thus the bit representation of the ``lower'' bound must be --@ less (in the sense of an unsigned bit-pattern) than that of the ``upper'' --@ bound. --@ --@ Note: In a design that uses RegFiles, some of the read ports may remain --@ unused. This may generate a warning in various downstream tools. These --@ should also be optimized away by downstream tools. --@ \index{RegFile@\te{RegFile} (interface type)} --@ \index{upd@\te{upd} (\te{RegFile} interface method)} --@ \index{sub@\te{sub} (\te{RegFile} interface method)} --@ \index{mkRegFile@\te{mkRegFile} (\te{RegFile} module)} --@ \index{mkRegFileFull@\te{mkRegFileFull} (\te{RegFile} module)} --@ \begin{libverbatim} --@ interface RegFile #(type index_t, type data_t); --@ method Action upd(index_t x1, data_t x2); --@ method data_t sub(index_t x1); --@ endinterface: RegFile --@ \end{libverbatim} interface RegFile i a = upd :: i -> a -> Action sub :: i -> a {- instance PrimSelectable (RegFile i a) i a where primSelectFn ar ix = ar.sub ix primUpdateFn ar ix va = noAction -} interface VRegFile ni na = upd :: Bit ni -> Bit na -> PrimAction sub :: Bit ni -> Bit na -- Only for i>0 and a>0 vMkRegFile :: Bit i -> Bit i -> Module (VRegFile i a) vMkRegFile lo hi = module verilog "RegFile" (("addr_width",valueOf i), ("data_width",valueOf a), ("lo",lo), ("hi",hi)) "CLK" { upd = "ADDR_IN" "D_IN"{reg} "WE"; sub[5] = "ADDR" "D_OUT"; } [ sub < upd, sub <> sub, upd >< upd ] saveRegFilePortTypes :: VRegFile ni na -> Type -> Type -> Module () saveRegFilePortTypes _a val_type idx_type = do let name = Valid (primGetModuleName _a) primSavePortType name "ADDR_IN" idx_type primSavePortType name "D_IN" val_type let saveSub n = do let s = integerToString n primSavePortType name ("ADDR_" +++ s) idx_type primSavePortType name ("D_OUT_" +++ s) val_type mapM saveSub (upto 1 5) return () --@ \begin{libverbatim} --@ module mkRegFile#( index_t lo, index_t hi ) --@ ( RegFile#(index_t, data_t) ) --@ provisos (Bits#(index_t, si), --@ Bits#(data_t, sa)); --@ \end{libverbatim} mkRegFile :: (IsModule m c, Bits i si, Bits a sa) => i -> i -> m (RegFile i a) mkRegFile = wrapRegFile "mkRegFile" False vMkRegFile -- Common wrapper for constructing the user-visible module from the -- bitified import wrapRegFile :: (IsModule m c, Bits i si, Bits a sa) => String -> Bool -> (Bit si -> Bit si -> Module (VRegFile si sa)) -> (i -> i -> m (RegFile i a)) wrapRegFile modname isWCF vMk l h = liftModule $ if valueOf sa == 0 then module interface upd _ _ = action { } sub _ = unpack 0 else if valueOf si == 0 then module _a :: Reg a {-# hide #-} _a <- if isWCF then mkConfigRegU else mkRegU interface upd _ x = _a := x sub _ = _a else module letseq lo = pack l hi = pack h _ <- if (hi < lo) then error ("bad indices for " +++ modname +++ ": [" +++ bitToString lo +++ ":" +++ bitToString hi +++ "]") else return () _a :: VRegFile si sa {-# hide #-} _a <- vMk lo hi saveRegFilePortTypes _a (typeOf (_ :: a)) (typeOf (_ :: i)) interface upd i x = fromPrimAction (_a.upd (pack i) (pack x)) sub i = unpack (_a.sub (pack i)) --@ \lineup --@ \begin{libverbatim} --@ module mkRegFileFull( RegFile#(index_t, data_t) ) --@ provisos (Bits#(index_t, si), --@ Bits#(data_t, sa), --@ Bounded#(index_t) ); --@ \end{libverbatim} mkRegFileFull :: (IsModule m c, Bounded i, Bits i si, Bits a sa) => m (RegFile i a) mkRegFileFull = mkRegFile minBound maxBound vMkRegFileWCF :: Bit i -> Bit i -> Module (VRegFile i a) vMkRegFileWCF lo hi = module verilog "RegFile" (("addr_width",valueOf i), ("data_width",valueOf a), ("lo",lo), ("hi",hi)) "CLK" { upd = "ADDR_IN" "D_IN"{reg} "WE"; sub[5] = "ADDR" "D_OUT"; } [ upd <> sub, sub <> sub, upd >< upd] --@ An array which for which the reads and the write are conflict-free. For --@ the implications of this, see the documentation for \te{ConfigReg}. --@ \begin{libverbatim} --@ module mkRegFileWCF#( index_t lo, index_t hi ) --@ ( RegFile#(index_t, data_t) ) --@ provisos (Bits#(index_t, si), --@ Bits#(data_t, sa)); --@ \end{libverbatim} mkRegFileWCF :: (IsModule m c, Bits i si, Bits a sa) => i -> i -> m (RegFile i a) mkRegFileWCF = wrapRegFile "mkRegFileWCF" True vMkRegFileWCF ----------------------------------------------------------------------------- -- mkRegFileLoadHex and friends --@ \index{RegFileLoad@\te{RegFileLoad} (package)} --@ \index{mkRegFileLoad@\te{mkRegFileLoad} (\te{RegFileLoad} function)} --@ \index{mkRegFileFullFile@\te{mkRegFileFullFile} (\te{RegFileLoad} function)} --@ The \te{RegFileLoad} variants provide the same functionality as --@ \te{RegFile}, but each constructor function takes an additional --@ file name argument. The file contains the initial contents of the array. --@ The file should use the {\veri} hex memory file syntax. --@ --@ The functions in this package cannot normally be used in synthesis. -- Only for i>0 and a>0 vMkRegFileLoad :: Bool -> String -> Bit i -> Bit i -> Module (VRegFile i a) vMkRegFileLoad isBin file lo hi = module verilog "RegFileLoad" (("file", file), ("addr_width",valueOf i), ("data_width",valueOf a), ("lo",lo), ("hi",hi), ("binary",pack isBin)) "CLK" { upd = "ADDR_IN" "D_IN"{reg} "WE"; sub[5] = "ADDR" "D_OUT"; } [ sub < upd, sub <> sub, upd >< upd ] --@ \begin{libverbatim} --@ module mkRegFileLoad#( String file, index_t lo, index_t hi ) --@ ( RegFile#(indedx_t, data_t) ) --@ provisos (Bits#(index_t, si), --@ Bits#(data_t, sa)); --@ \end{libverbatim} mkRegFileLoadHex :: (IsModule m c, Bits i si, Bits a sa) => String -> i -> i -> m (RegFile i a) mkRegFileLoadHex file = wrapRegFile "mkRegFileLoadHex" False (vMkRegFileLoad False file) --@ \lineup --@ \begin{libverbatim} --@ module mkRegFileFullLoad#( String file) --@ ( RegFile#(index_t, data_t)) --@ provisos (Bits#(index_t, si), --@ Bits#(data_t, sa), --@ Bounded#(index_t) ); --@ \end{libverbatim} mkRegFileFullLoadHex :: (IsModule m c, Bounded i, Bits i si, Bits a sa) => String -> m (RegFile i a) mkRegFileFullLoadHex file = mkRegFileLoadHex file minBound maxBound vMkRegFileWCFLoad :: Bool -> String -> Bit i -> Bit i -> Module (VRegFile i a) vMkRegFileWCFLoad isBin file lo hi = module verilog "RegFileLoad" (("file", file), ("addr_width",valueOf i), ("data_width",valueOf a), ("lo",lo), ("hi",hi), ("binary",pack isBin)) "CLK" { upd = "ADDR_IN" "D_IN"{reg} "WE"; sub[5] = "ADDR" "D_OUT"; } [ upd <> sub, sub <> sub, upd >< upd ] --@ \begin{libverbatim} --@ module mkRegFileWCFLoad#( String file, index_t lo, index_t hi ) --@ ( RegFile#(index_t, data_t) ) --@ provisos (Bits#(index_t, si), --@ Bits#(data_t, sa)); --@ \end{libverbatim} mkRegFileWCFLoadHex :: (IsModule m c, Bits i si, Bits a sa) => String -> i -> i -> m (RegFile i a) mkRegFileWCFLoadHex file = wrapRegFile "mkRegFileWCFLoadHex" True (vMkRegFileWCFLoad False file) ----------------------------------------------------------------------------- -- mkRegFileLoadBin and friends mkRegFileLoadBin :: (IsModule m c, Bits i si, Bits a sa) => String -> i -> i -> m (RegFile i a) mkRegFileLoadBin file = wrapRegFile "mkRegFileLoadBin" False (vMkRegFileLoad True file) mkRegFileFullLoadBin :: (IsModule m c, Bounded i, Bits i si, Bits a sa) => String -> m (RegFile i a) mkRegFileFullLoadBin file = mkRegFileLoadBin file minBound maxBound mkRegFileWCFLoadBin :: (IsModule m c, Bits i si, Bits a sa) => String -> i -> i -> m (RegFile i a) mkRegFileWCFLoadBin file = wrapRegFile "mkRegFileWCFLoadBin" True (vMkRegFileWCFLoad True file) ----------------------------------------------------------------------------- -- mkRegFileLoad for backward compatibility mkRegFileLoad :: (IsModule m c, Bits i si, Bits a sa) => String -> i -> i -> m (RegFile i a) mkRegFileLoad file l h = mkRegFileLoadHex file l h mkRegFileFullLoad :: (IsModule m c, Bounded i, Bits i si, Bits a sa) => String -> m (RegFile i a) mkRegFileFullLoad file = mkRegFileFullLoadHex file mkRegFileWCFLoad :: (IsModule m c, Bits i si, Bits a sa) => String -> i -> i -> m (RegFile i a) mkRegFileWCFLoad file l h = mkRegFileWCFLoadHex file l h