package DPSRAM(mkDPSRAM) where import RegFile import GetPut import ClientServer import SyncSRAM --@ \subsubsection{\te{DPSRAM}} --@ \index{DPSRAM@\te{DPSRAM} (package)|textbf} --@ --@ The \te{DPSRAM} package contains is used to generate --@ internal dual ported SRAMs (for the LSI libraries). --@ The argument specifies the size of the SRAM. --@ \index{mkDPSRAM@\te{mkDPSRAM} (module)|textbf} --@ \begin{libverbatim} --@ module mkDPSRAM#(Integer nwords)(Tuple2 #(SyncSRAMS#(1, adrs, dtas), --@ SyncSRAMS#(1, adrs, dtas))); --@ \end{libverbatim} mkDPSRAM :: (IsModule m c) => Integer -> m (SyncSRAMS 1 adrs dtas, SyncSRAMS 1 adrs dtas) mkDPSRAM nwords = liftModule $ if ((2 ** (valueOf adrs)) < nwords) then error "address width too small" else if genC then mkDPSRAM_C nwords else module vram :: VSyncSRAM adrs dtas <- mkDPSRAM_V nwords let name = Valid (primGetModuleName vram) let adrst = typeOf (_ :: Bit adrs) let dtast = typeOf (_ :: Bit dtas) let bit1t = typeOf (_ :: Bit 1) primSavePortType name "ADRA" adrst primSavePortType name "DIA" dtast primSavePortType name "WEA" bit1t primSavePortType name "ENA" bit1t primSavePortType name "DOA" dtast primSavePortType name "ADRB" adrst primSavePortType name "DIB" dtast primSavePortType name "WEB" bit1t primSavePortType name "ENB" bit1t primSavePortType name "DOB" dtast interface -- Pair (interface Server request = interface Put put req = fromPrimAction (vram.execA req.addr req.wdata req.we req.ena) response = interface Get get = return vram.rdataA , interface Server request = interface Put put req = fromPrimAction (vram.execB req.addr req.wdata req.we req.ena) response = interface Get get = return vram.rdataB ) mkDPSRAM_C :: Integer -> Module (SyncSRAMS 1 adrs dtas, SyncSRAMS 1 adrs dtas) mkDPSRAM_C nwords = module arr :: RegFile (Bit adrs) (Bit dtas) <- mkRegFileWCF 0 (fromInteger (nwords-1)) outA :: Reg (Bit dtas) <- mkRegU outB :: Reg (Bit dtas) <- mkRegU interface -- Pair (interface Server request = interface Put put req = if req.ena == 1 then if req.we == 1 then do arr.upd req.addr req.wdata outA := req.wdata else outA := arr.sub req.addr else outA := 0 response = interface Get get = return outA , interface Server request = interface Put put req = if req.ena == 1 then if req.we == 1 then do arr.upd req.addr req.wdata outB := req.wdata else outB := arr.sub req.addr else outB := 0 response = interface Get get = return outB ) interface VSyncSRAM adrs dtas = execA :: Bit adrs -> Bit dtas -> Bit 1 -> Bit 1 -> PrimAction rdataA :: Bit dtas execB :: Bit adrs -> Bit dtas -> Bit 1 -> Bit 1 -> PrimAction rdataB :: Bit dtas mkDPSRAM_V :: Integer -> Module (VSyncSRAM adrs dtas) mkDPSRAM_V nwords = do let name = "RRDPSRAM_" +++ integerToString nwords +++ "_" +++ integerToString (valueOf dtas) +++ "_bussed" messageM ("Used SRAM: " +++ name) module verilog name "CLKA","CLKB" { execA = "ADRA" "DIA" "WEA" "ENA" "?"{inhigh}; rdataA = "DOA"; execB = "ADRB" "DIB" "WEB" "ENB" "?"{inhigh}; rdataB = "DOB"; } [ [execA,rdataA,execB,rdataB] <> [execA,rdataA,execB,rdataB] ]