CreateRealRegArray:
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 = {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);
-- Vars
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;
-- 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];
rd1addr: Wire ← CoreCreate.Seq["RD1addr", 4];
rd2addr: Wire ← CoreCreate.Seq["RD2addr", 4];
-- Cells
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] = {
-- Make a Tap Column
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] = {
-- Make a Tap Column
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
-- 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"]]
]];
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
-- 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"],
["RD1addr", rd1addr],
["RD2addr", rd2addr],
["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"]]
]];
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
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),
flatten: FALSE,
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"]]
]];
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
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"]]
]];
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]];
-- Make 1st Tap at Begining of row
MakeLeftColumn[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, (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;
};
-- Start of CreateRegArray procedure
TerminalIO.PutF["Creating RegisterFileTile %g x %g \n",IO.int[nbrBanks],IO.int[regLength]];
-- Error Checking
IF (busSize MOD segments) # 0 THEN ERROR;
IF (regLength MOD 8) # 0 THEN ERROR;
-- Build each bank of the Reg Array
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
];
};