DIRECTORY CD, CDSequencer, Core USING [CellType], CoreCreate, List, Sisyph USING [Context, ES], Tam, TamarinUtil, TilingClass USING [CreateTiling, SchematicsNeighborX, SchematicsNeighborY, TileArray, TileArrayRec, TileRec, TileRowRec]; NewTamarinRegFileImpl: CEDAR PROGRAM IMPORTS CoreCreate, Sisyph, TamarinUtil, TilingClass EXPORTS Tam = BEGIN LORA: TYPE = List.LORA; Wire: TYPE = CoreCreate.Wire; WR: TYPE = CoreCreate.WR; lastTile: TilingClass.TileArray _ NIL; CreateRegArray: PUBLIC PROC [tamarinCx: Sisyph.Context, nbrBanks, regLength, segments: NAT] RETURNS [cellType: Core.CellType] = { RowType: TYPE = {MemUp, MemDown, SenseDrive, DMap}; busSize: NAT = 34; bankDecoderSize: NAT = 4; addrDecoderSize: NAT = 5; decoderSize: NAT = bankDecoderSize+addrDecoderSize; totalColumns: NAT = 1+busSize+(busSize / segments); totalRows: NAT _ nbrBanks * (regLength / 4) + 1; tileArray: TilingClass.TileArray _ NEW[TilingClass.TileArrayRec[totalRows]]; rowIndex: NAT _ 0; nextRegAddr: Wire _ CoreCreate.Seq["NextRegAddr", decoderSize]; rbus: Wire _ CoreCreate.Seq["R", busSize]; d1: Wire _ CoreCreate.Seq["D1", busSize]; d2: Wire _ CoreCreate.Seq["D2", busSize]; regMemCellTapUp: Core.CellType _ Sisyph.ES["RegMemCellTapUp.sch", tamarinCx]; regMemQuadUp: Core.CellType _ Sisyph.ES["RegMemQuadCellUp.sch", tamarinCx]; regMemCellTapDown: Core.CellType _ Sisyph.ES["RegMemCellTapDown.sch", tamarinCx]; regMemQuadDown: Core.CellType _ Sisyph.ES["RegMemQuadCellDown.sch", tamarinCx]; regSenseDriveTap: Core.CellType _ Sisyph.ES["RegSenseDriveTap.sch", tamarinCx]; regSenseDriveQuad: Core.CellType _ Sisyph.ES["RegSenseDriveQuad.sch", tamarinCx]; regDMapperQuad: Core.CellType _ Sisyph.ES["DMapperQuad.sch", tamarinCx]; regDMapperTap: Core.CellType _ Sisyph.ES["DMapperTap.sch", tamarinCx]; MakeRow: PROC [type: RowType, rowIndex, bankAddr, rowAddr: NAT] RETURNS [] = { MakeTapColumn: PROC [type: RowType, rowIndex, colIndex: NAT] = { tileArray[rowIndex][colIndex] _ NEW[TilingClass.TileRec _ [ type: (SELECT type FROM DMap => regDMapperTap, SenseDrive => regSenseDriveTap, MemUp => regMemCellTapUp, MemDown => regMemCellTapDown, ENDCASE => ERROR), renaming: LIST[["Vdd", "Vdd"], ["Gnd", "Gnd"]] ]]; }; MakeMemColumn: PROC [type: RowType, rowIndex, colIndex, bit: NAT] = { SELECT type FROM DMap => tileArray[rowIndex][colIndex] _ NEW[TilingClass.TileRec _ [ type: regDMapperQuad, renaming: LIST[ ["Vdd", "Vdd"], ["Gnd", "Gnd"], ["R", rbus[bit]], ["D1", d1[bit]], ["D2", d2[bit]]] ]]; SenseDrive => tileArray[rowIndex][colIndex] _ NEW[TilingClass.TileRec _ [ type: regSenseDriveQuad, renaming: LIST[["Vdd", "Vdd"], ["Gnd", "Gnd"]] ]]; MemUp => tileArray[rowIndex][colIndex] _ NEW[TilingClass.TileRec _ [ type: regMemQuadUp, renaming: LIST[["Vdd", "Vdd"], ["Gnd", "Gnd"]] ]]; MemDown => tileArray[rowIndex][colIndex] _ NEW[TilingClass.TileRec _ [ type: regMemQuadDown, renaming: LIST[["Vdd", "Vdd"], ["Gnd", "Gnd"]] ]]; ENDCASE => ERROR; }; MakeDriverColumn: PROC [type: RowType, rowIndex, colIndex: NAT] = { SELECT type FROM ENDCASE => ERROR; }; MakeDecodeColumn: PROC [type: RowType, rowIndex, colIndex: NAT, polFlag: BOOLEAN, wire: WR, lsbpos: BOOLEAN _ FALSE] = { SELECT type FROM ENDCASE => ERROR; }; MakePullupColumn: PROC [type: RowType, rowIndex, colIndex: NAT] = { SELECT type FROM ENDCASE => ERROR }; colIndex: NAT _ 0; tileArray[rowIndex] _ NEW[TilingClass.TileRowRec[totalColumns]]; MakeTapColumn[type, rowIndex, 0]; colIndex _ 1; FOR i: NAT IN [0..busSize) DO MakeMemColumn[type, rowIndex, colIndex, i]; colIndex _ colIndex + 1; IF ((i+1) MOD segments) = 0 THEN { MakeTapColumn[type, rowIndex, colIndex]; colIndex _ colIndex + 1 }; ENDLOOP; -- Add Drivers & Decoders IF colIndex # totalColumns THEN ERROR; }; IF (regLength MOD 4) # 0 THEN ERROR; MakeRow[SenseDrive, 0, 0, 0]; rowIndex _ 1; FOR bank: NAT IN [0..nbrBanks) DO FOR counter: NAT IN [0..regLength/8) DO MakeRow[MemDown, rowIndex, bank, counter*8]; MakeRow[MemUp, rowIndex+1, bank, counter*8+4]; rowIndex _ rowIndex + 2; ENDLOOP; ENDLOOP; IF rowIndex # totalRows THEN ERROR; lastTile _ tileArray; cellType _ TilingClass.CreateTiling[ name: "RegFile", public: CoreCreate.WireList[LIST["Vdd", "Gnd"]], tileArray: tileArray, neighborX: TilingClass.SchematicsNeighborX, neighborY: TilingClass.SchematicsNeighborY ]; }; END. ’NewTamarinRegFileImpl.mesa Copyright c 1987 by Xerox Corporation. All rights reserved. Last Edited by: Alan Bell August 29, 1987 7:37:47 pm PDT Krivacic June 26, 1987 10:02:31 am PDT Create the Internal RegFile Array. Build the Reg Array such that there are 34 MemQuad cells across (which makes 4 words per row). Divide these cells into segments and place taps between them based on segments. regLength is the number of words per register bank, and banks is the # of register banks to create. -- Constants totalColumns: NAT = 1+busSize+(busSize / segments)+2+(decoderSize-2); -- Vars totalRows: NAT _ nbrBanks * (regLength / 4) + 2; -- Wire Sequences -- Cells regMemDriverUp: Core.CellType _ Sisyph.ES["RegDriverUp.sch", tamarinCx]; regMemCellDecode0Up: Core.CellType _ Sisyph.ES["RegDecode0Up.sch", tamarinCx]; regMemCellDecode1Up: Core.CellType _ Sisyph.ES["RegDecode1Up.sch", tamarinCx]; regMemCellPullupUp: Core.CellType _ Sisyph.ES["RegDecPullupUp.sch", tamarinCx]; regMemDriverDown: Core.CellType _ Sisyph.ES["RegDriverDown.sch", tamarinCx]; regMemCellDecode0Down: Core.CellType _ Sisyph.ES["RegDecode0Down.sch", tamarinCx]; regMemCellDecode1Down: Core.CellType _ Sisyph.ES["RegDecode1Down.sch", tamarinCx]; regMemCellPullupDown: Core.CellType _ Sisyph.ES["RegDecPullupDown.sch", tamarinCx]; regSenseDriveDriver: Core.CellType _ Sisyph.ES["RegSenseDriveDriver.sch", tamarinCx]; regSenseDriveDecode: Core.CellType _ Sisyph.ES["RegSenseDriveDecode.sch", tamarinCx]; regSenseDriveDecodeLsb: Core.CellType _ Sisyph.ES["RegSenseDriveDecodeLsb.sch", tamarinCx]; regSenseDrivePullup: Core.CellType _ Sisyph.ES["RegSenseDrivePullup.sch", tamarinCx]; regDMapperDriver: Core.CellType _ Sisyph.ES["DMapperDriver.sch", tamarinCx]; regDMapperDecode: Core.CellType _ Sisyph.ES["DMapperDecode.sch", tamarinCx]; regDMapperPullup: Core.CellType _ Sisyph.ES["DMapperPullup.sch", tamarinCx]; -- Make a Tap Column -- DMapper Row -- Sense & Drive Row -- Ram Row -- DMapper Row DMap => tileArray[rowIndex][colIndex] _ NEW[TilingClass.TileRec _ [ type: regDMapperDriver, renaming: LIST[ ["Vdd", "Vdd"], ["Gnd", "Gnd"], ["WriteBack", "WriteBack"], ["WriteOk", "WriteOk"], ["WriteOctal", "WriteOctal"], ["DSwap", "DSwap"], ["nClock", "nClock"], ["nClock2", "nClock2"], ["MemtoD1", "MemtoD1"], ["MemtoD2", "MemtoD2"], ["NextRegAddrNextLsb", nextRegAddr[decoderSize-2]], ["NextRegAddrLsb", nextRegAddr[decoderSize-1]]] ]]; -- Sense & Drive Row SenseDrive => tileArray[rowIndex][colIndex] _ NEW[TilingClass.TileRec _ [ type: regSenseDriveDriver, renaming: LIST[ ["Vdd", "Vdd"], ["Gnd", "Gnd"]] ]]; -- Memory Row MemUp => tileArray[rowIndex][colIndex] _ NEW[TilingClass.TileRec _ [ type: regMemDriverUp, renaming: LIST[["Vdd", "Vdd"], ["Gnd", "Gnd"]] ]]; MemDown => tileArray[rowIndex][colIndex] _ NEW[TilingClass.TileRec _ [ type: regMemDriverDown, renaming: LIST[["Vdd", "Vdd"], ["Gnd", "Gnd"]] ]]; DMapper Row DMap => tileArray[rowIndex][colIndex] _ NEW[TilingClass.TileRec _ [ type: regDMapperDecode, renaming: LIST[["Vdd", "Vdd"], ["Gnd", "Gnd"], ["NextRegAddr", wire]] ]]; Sense & Drive Row SenseDrive => tileArray[rowIndex][colIndex] _ NEW[TilingClass.TileRec _ [ type: (IF lsbpos THEN regSenseDriveDecodeLsb ELSE regSenseDriveDecode), renaming: LIST[ ["Vdd", "Vdd"], ["Gnd", "Gnd"]] ]]; Memory Row MemUp => tileArray[rowIndex][colIndex] _ NEW[TilingClass.TileRec _ [ type: (IF polFlag THEN regMemCellDecode1Up ELSE regMemCellDecode0Up), renaming: LIST[["Vdd", "Vdd"], ["Gnd", "Gnd"]] ]]; DMapper Row DMap => tileArray[rowIndex][colIndex] _ NEW[TilingClass.TileRec _ [ type: regDMapperPullup, renaming: LIST[["Vdd", "Vdd"], ["Gnd", "Gnd"]] ]]; Sense & Drive Row SenseDrive => tileArray[rowIndex][colIndex] _ NEW[TilingClass.TileRec _ [ type: regSenseDrivePullup, renaming: LIST[["Vdd", "Vdd"], ["Gnd", "Gnd"]] ]]; Memory Row MemUp => tileArray[rowIndex][colIndex] _ NEW[TilingClass.TileRec _ [ type: regMemCellPullupUp, renaming: LIST[["Vdd", "Vdd"], ["Gnd", "Gnd"]] ]]; -- Make 1st Tap at Begining of row -- Loop through the Row Entries, Making taps on the way. MakeDriverColumn[type, rowIndex, colIndex]; colIndex _ colIndex + 1; FOR i: NAT IN [0..bankDecoderSize) DO MakeDecodeColumn[type, rowIndex, colIndex, TamarinUtil.BitOnP[bankAddr, bankDecoderSize - 1 - i], nextRegAddr[i]]; colIndex _ colIndex + 1; ENDLOOP; FOR i: NAT IN [0..addrDecoderSize-2) DO MakeDecodeColumn[type, rowIndex, colIndex, TamarinUtil.BitOnP[rowAddr, addrDecoderSize - 1 - i], nextRegAddr[bankDecoderSize+i], i = (addrDecoderSize - 3)]; colIndex _ colIndex + 1; ENDLOOP; MakePullupColumn[type, rowIndex, colIndex]; colIndex _ colIndex + 1; -- Start of CreateRegArray procedure -- Error Checking IF (busSize MOD segments) # 0 THEN ERROR; -- Build each bank of the Reg Array MakeRow[DMap, 0, 0, 0]; MakeRow[SenseDrive, 1, 0, 0]; rowIndex _ 2; public: CoreCreate.WireList[LIST["Vdd", "Gnd", d1, d2, rbus, nextRegAddr, "MemtoD1", "MemtoD2", "DSwap", "WriteOk", "WriteBack", "WriteOctal", "nClock2", "nClock"]], Κ ύ– "cedar" style˜codešœ™Kšœ Οmœ1™