DIRECTORY CD, CDSequencer, Core USING [CellType], CoreCreate, CoreClasses, Ports, TerminalIO, IO, List, Sisyph USING [Context, ES], Tam, TamarinUtil, TilingClass USING [CreateTiling, SchematicsNeighborX, SchematicsNeighborY, TileArray, TileArrayRec, TileRec, TileRowRec]; TamarinRegFileImpl: CEDAR PROGRAM IMPORTS CoreCreate, Sisyph, TamarinUtil, TilingClass, CoreClasses, Ports, TerminalIO, IO EXPORTS Tam = BEGIN LORA: TYPE = List.LORA; Wire: TYPE = CoreCreate.Wire; WR: TYPE = CoreCreate.WR; lastTile: TilingClass.TileArray _ NIL; extractRegFile: BOOL _ TRUE; CreateRealRegArray: PUBLIC PROC [tamarinCx: Sisyph.Context, nbrBanks, regLength, segments: NAT] RETURNS [cellType: Core.CellType] = { RowType: TYPE = {Top, MemUp, MemDown, SenseDrive, DMap}; busSize: NAT = 34; bankDecoderSize: NAT = 4; addrDecoderSize: NAT = 5; decoderSize: NAT = bankDecoderSize+addrDecoderSize; totalColumns: NAT = 1+busSize+(busSize / segments)+2+(decoderSize-2); totalRows: NAT _ (IF nbrBanks=5 AND regLength>31 THEN (nbrBanks-1) * (regLength / 4) + 3 + 4 ELSE nbrBanks * (regLength / 4) + 3); 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]; rd1addr: Wire _ CoreCreate.Seq["RD1addr", 4]; rd2addr: Wire _ CoreCreate.Seq["RD2addr", 4]; regMemCellLeftTop: Core.CellType _ Sisyph.ES["RegMemCellLeftTop.sch", tamarinCx]; regMemCellTapTop: Core.CellType _ Sisyph.ES["RegMemCellTapTop.sch", tamarinCx]; regMemQuadTop: Core.CellType _ Sisyph.ES["RegMemQuadTop.sch", tamarinCx]; regMemDriverTop: Core.CellType _ Sisyph.ES["RegDriverTop.sch", tamarinCx]; regMemCellDecodeTop: Core.CellType _ Sisyph.ES["RegDecodeTop.sch", tamarinCx]; regMemCellPullupTop: Core.CellType _ Sisyph.ES["RegDecPullupTop.sch", tamarinCx]; regMemCellLeftUp: Core.CellType _ Sisyph.ES["RegMemCellLeftUp.sch", tamarinCx]; regMemCellTapUp: Core.CellType _ Sisyph.ES["RegMemCellTapUp.sch", tamarinCx]; regMemQuadUp: Core.CellType _ Sisyph.ES["RegMemQuadUp.sch", tamarinCx]; 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]; regMemCellLeftDown: Core.CellType _ Sisyph.ES["RegMemCellLeftDown.sch", tamarinCx]; regMemCellTapDown: Core.CellType _ Sisyph.ES["RegMemCellTapDown.sch", tamarinCx]; regMemQuadDown: Core.CellType _ Sisyph.ES["RegMemQuadDown.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]; regSenseDriveLeft: Core.CellType _ Sisyph.ES["RegSenseDriveLeft.sch", tamarinCx]; regSenseDriveTap: Core.CellType _ Sisyph.ES["RegSenseDriveTap.sch", tamarinCx]; regSenseDriveQuad: Core.CellType _ Sisyph.ES["RegSenseDriveQuad.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]; regDMapperLeft: Core.CellType _ Sisyph.ES["DMapperLeft.sch", tamarinCx]; regDMapperTap: Core.CellType _ Sisyph.ES["DMapperTap.sch", tamarinCx]; regDMapperQuad: Core.CellType _ Sisyph.ES["DMapperQuad.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]; MakeRow: PROC [type: RowType, rowIndex, bankAddr, rowAddr: NAT] RETURNS [] = { MakeLeftColumn: PROC [type: RowType, rowIndex, colIndex: NAT] = { tileArray[rowIndex][colIndex] _ NEW[TilingClass.TileRec _ [ type: (SELECT type FROM DMap => regDMapperLeft, SenseDrive => regSenseDriveLeft, MemUp => regMemCellLeftUp, MemDown => regMemCellLeftDown, Top => regMemCellLeftTop, ENDCASE => ERROR), renaming: LIST[["Vdd", "Vdd"], ["Gnd", "Gnd"]] ]]; }; 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, Top => regMemCellTapTop, 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"]] ]]; Top => tileArray[rowIndex][colIndex] _ NEW[TilingClass.TileRec _ [ type: regMemQuadTop, renaming: LIST[["Vdd", "Vdd"], ["Gnd", "Gnd"]] ]]; ENDCASE => ERROR; }; MakeDriverColumn: PROC [type: RowType, rowIndex, colIndex: NAT] = { SELECT type FROM 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"], ["RD1addr", rd1addr], ["RD2addr", rd2addr], ["NextRegAddrNextLsb", nextRegAddr[decoderSize-2]], ["NextRegAddrLsb", nextRegAddr[decoderSize-1]]] ]]; SenseDrive => tileArray[rowIndex][colIndex] _ NEW[TilingClass.TileRec _ [ type: regSenseDriveDriver, renaming: LIST[ ["Vdd", "Vdd"], ["Gnd", "Gnd"]] ]]; 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"]] ]]; Top => tileArray[rowIndex][colIndex] _ NEW[TilingClass.TileRec _ [ type: regMemDriverTop, renaming: LIST[["Vdd", "Vdd"], ["Gnd", "Gnd"]] ]]; ENDCASE => ERROR; }; MakeDecodeColumn: PROC [type: RowType, rowIndex, colIndex: NAT, polFlag: BOOLEAN, wire: WR, lsbpos: BOOLEAN _ FALSE] = { SELECT type FROM DMap => tileArray[rowIndex][colIndex] _ NEW[TilingClass.TileRec _ [ type: regDMapperDecode, renaming: LIST[["Vdd", "Vdd"], ["Gnd", "Gnd"], ["NextRegAddr", wire]] ]]; SenseDrive => tileArray[rowIndex][colIndex] _ NEW[TilingClass.TileRec _ [ type: (IF lsbpos THEN regSenseDriveDecodeLsb ELSE regSenseDriveDecode), flatten: FALSE, renaming: LIST[ ["Vdd", "Vdd"], ["Gnd", "Gnd"]] ]]; MemUp => tileArray[rowIndex][colIndex] _ NEW[TilingClass.TileRec _ [ type: (IF polFlag THEN regMemCellDecode1Up ELSE regMemCellDecode0Up), renaming: LIST[["Vdd", "Vdd"], ["Gnd", "Gnd"]] ]]; MemDown => tileArray[rowIndex][colIndex] _ NEW[TilingClass.TileRec _ [ type: (IF polFlag THEN regMemCellDecode1Down ELSE regMemCellDecode0Down), renaming: LIST[["Vdd", "Vdd"], ["Gnd", "Gnd"]] ]]; Top => tileArray[rowIndex][colIndex] _ NEW[TilingClass.TileRec _ [ type: regMemCellDecodeTop, renaming: LIST[["Vdd", "Vdd"], ["Gnd", "Gnd"]] ]]; ENDCASE => ERROR; }; MakePullupColumn: PROC [type: RowType, rowIndex, colIndex: NAT] = { SELECT type FROM DMap => tileArray[rowIndex][colIndex] _ NEW[TilingClass.TileRec _ [ type: regDMapperPullup, renaming: LIST[["Vdd", "Vdd"], ["Gnd", "Gnd"]] ]]; SenseDrive => tileArray[rowIndex][colIndex] _ NEW[TilingClass.TileRec _ [ type: regSenseDrivePullup, renaming: LIST[["Vdd", "Vdd"], ["Gnd", "Gnd"]] ]]; MemUp => tileArray[rowIndex][colIndex] _ NEW[TilingClass.TileRec _ [ type: regMemCellPullupUp, renaming: LIST[["Vdd", "Vdd"], ["Gnd", "Gnd"]] ]]; MemDown => tileArray[rowIndex][colIndex] _ NEW[TilingClass.TileRec _ [ type: regMemCellPullupDown, renaming: LIST[["Vdd", "Vdd"], ["Gnd", "Gnd"]] ]]; Top => tileArray[rowIndex][colIndex] _ NEW[TilingClass.TileRec _ [ type: regMemCellPullupTop, renaming: LIST[["Vdd", "Vdd"], ["Gnd", "Gnd"]] ]]; ENDCASE => ERROR }; colIndex: NAT _ 0; tileArray[rowIndex] _ NEW[TilingClass.TileRowRec[totalColumns]]; MakeLeftColumn[type, rowIndex, 0]; colIndex _ 1; FOR i: NAT IN [0..busSize) DO MakeMemColumn[type, rowIndex, colIndex, (IF i>31 THEN i-32 ELSE i+2)]; colIndex _ colIndex + 1; IF ((i+1) MOD segments) = 0 THEN { MakeTapColumn[type, rowIndex, colIndex]; colIndex _ colIndex + 1 }; ENDLOOP; -- Add Drivers & Decoders 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; IF colIndex # totalColumns THEN ERROR; }; TerminalIO.PutF["Creating RegisterFileTile %g x %g \n",IO.int[nbrBanks],IO.int[regLength]]; IF (regLength MOD 8) # 0 THEN ERROR; MakeRow[DMap, 0, 0, 0]; MakeRow[SenseDrive, 1, 0, 0]; rowIndex _ 2; 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; IF bank=4 AND regLength>31 AND counter=1 THEN EXIT; ENDLOOP; ENDLOOP; MakeRow[Top, rowIndex, 0, 0]; rowIndex _ rowIndex + 1; IF rowIndex # totalRows THEN ERROR; lastTile _ tileArray; cellType _ TilingClass.CreateTiling[ name: "RegFile", public: CoreCreate.WireList[LIST["Vdd", "Gnd", d1, d2, rbus, nextRegAddr, rd1addr, rd2addr, "DSwap", "WriteOk", "WriteBack", "WriteOctal", "nClock2", "nClock"]], tileArray: tileArray, neighborX: TilingClass.SchematicsNeighborX, neighborY: TilingClass.SchematicsNeighborY ]; }; CreateRegArray: PUBLIC PROC [tamarinCx: Sisyph.Context, nbrBanks, regLength, segments: NAT] RETURNS [cellType: Core.CellType] = { IF extractRegFile THEN cellType _ CreateRealRegArray[tamarinCx, nbrBanks, regLength, segments] ELSE { cellType _ CoreClasses.CreateUnspecified[ CoreCreate.WireList[LIST[CoreCreate.Seq["D1", 34], CoreCreate.Seq["D2", 34], CoreCreate.Seq["R", 34], "WriteBack", "WriteOk", CoreCreate.Seq["NextRegAddr", 9], "nClock2", "nClock", "WriteOctal", "DSwap", CoreCreate.Seq["RD1addr", 4], CoreCreate.Seq["RD2addr", 4], "Vdd", "Gnd"]], "RegisterFileTile"]; [] _ Ports.InitPorts[cellType, ls, none, "R", "NextRegAddr", "RD1addr", "RD2addr"]; [] _ Ports.InitPorts[cellType, l, none, "WriteOctal", "DSwap", "WriteBack", "WriteOk", "nClock2", "nClock"]; [] _ Ports.InitPorts[cellType, ls, drive, "D1", "D2"]; TerminalIO.PutRope["Creating Behavioral Proc for RegisterFileTile \n"]; }; }; END. ͺTamarinRegFileImpl .mesa Copyright c 1987 by Xerox Corporation. All rights reserved. Last Edited by: Alan Bell October 1, 1987 10:57:45 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 -- Vars -- Wire Sequences -- Cells -- Make a Tap Column -- Make a Tap Column -- DMapper Row -- Sense & Drive Row -- Ram Row -- DMapper Row -- Sense & Drive Row -- Memory Row DMapper Row Sense & Drive Row Memory Row DMapper Row Sense & Drive Row Memory Row -- Make 1st Tap at Begining of row -- Loop through the Row Entries, Making taps on the way. -- Start of CreateRegArray procedure -- Error Checking IF (busSize MOD segments) # 0 THEN ERROR; -- Build each bank of the Reg Array [] _ Rosemary.BindCellType[cellType: cellType, roseClassName: regFileName]; [] _ CoreFlat.CellTypeCutLabels[ct, Logic.logicCutSet]; [] _ Ports.InitPorts[ct, l, none, "Vdd", "Gnd"]; Κ – "cedar" style˜codešœ™Kšœ Οmœ1™