NewTamarinRegFileImpl.mesa
Copyright © 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
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] = {
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
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)+2+(decoderSize-2);
totalColumns: NAT = 1+busSize+(busSize / segments);
-- Vars
totalRows: NAT ← nbrBanks * (regLength / 4) + 2;
totalRows: NAT ← nbrBanks * (regLength / 4) + 1;
tileArray: TilingClass.TileArray ← NEW[TilingClass.TileArrayRec[totalRows]];
rowIndex: NAT ← 0;
-- Wire Sequences
nextRegAddr: Wire ← CoreCreate.Seq["NextRegAddr", decoderSize];
rbus: Wire ← CoreCreate.Seq["R", busSize];
d1: Wire ← CoreCreate.Seq["D1", busSize];
d2: Wire ← CoreCreate.Seq["D2", busSize];
-- Cells
regMemCellTapUp: Core.CellType ← Sisyph.ES["RegMemCellTapUp.sch", tamarinCx];
regMemQuadUp: Core.CellType ← Sisyph.ES["RegMemQuadCellUp.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];
regMemCellTapDown: Core.CellType ← Sisyph.ES["RegMemCellTapDown.sch", tamarinCx];
regMemQuadDown: Core.CellType ← Sisyph.ES["RegMemQuadCellDown.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];
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];
regDMapperQuad: Core.CellType ← Sisyph.ES["DMapperQuad.sch", tamarinCx];
regDMapperTap: Core.CellType ← Sisyph.ES["DMapperTap.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 [] = {
MakeTapColumn: PROC [type: RowType, rowIndex, colIndex: NAT] = {
-- Make a Tap Column
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
-- DMapper Row
DMap => 
tileArray[rowIndex][colIndex] ← NEW[TilingClass.TileRec ← [
type: regDMapperQuad,
renaming: LIST[
["Vdd", "Vdd"], ["Gnd", "Gnd"],
["R", rbus[bit]],
["D1", d1[bit]],
["D2", d2[bit]]]
]];
-- Sense & Drive Row
SenseDrive =>
tileArray[rowIndex][colIndex] ← NEW[TilingClass.TileRec ← [
type: regSenseDriveQuad,
renaming: LIST[["Vdd", "Vdd"], ["Gnd", "Gnd"]]
]];
-- Ram Row
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
-- 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"]]
]];
ENDCASE => ERROR;
};
MakeDecodeColumn: PROC [type: RowType, rowIndex, colIndex: NAT, polFlag: BOOLEAN, wire: WR, lsbpos: BOOLEANFALSE] = {
SELECT type FROM
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"]]
]];
ENDCASE => ERROR;
};
MakePullupColumn: PROC [type: RowType, rowIndex, colIndex: NAT] = {
SELECT type FROM
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"]]
]];
ENDCASE => ERROR
};
colIndex: NAT ← 0;
tileArray[rowIndex] ← NEW[TilingClass.TileRowRec[totalColumns]];
-- Make 1st Tap at Begining of row
MakeTapColumn[type, rowIndex, 0];
-- Loop through the Row Entries, Making taps on the way.
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
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;
};
-- Start of CreateRegArray procedure
-- Error Checking
IF (busSize MOD segments) # 0 THEN ERROR;
IF (regLength MOD 4) # 0 THEN ERROR;
-- Build each bank of the Reg Array
MakeRow[DMap, 0, 0, 0];
MakeRow[SenseDrive, 1, 0, 0];
MakeRow[SenseDrive, 0, 0, 0];
rowIndex ← 1;
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;
ENDLOOP;
ENDLOOP;
IF rowIndex # totalRows THEN ERROR;
lastTile ← tileArray;
cellType ← TilingClass.CreateTiling[
name: "RegFile",
public: CoreCreate.WireList[LIST["Vdd", "Gnd", d1, d2, rbus, nextRegAddr, "MemtoD1", "MemtoD2", "DSwap", "WriteOk", "WriteBack", "WriteOctal", "nClock2", "nClock"]],
public: CoreCreate.WireList[LIST["Vdd", "Gnd"]],
tileArray: tileArray,
neighborX: TilingClass.SchematicsNeighborX,
neighborY: TilingClass.SchematicsNeighborY
];
};
END.