CrossRAMGen.mesa
Copyright © 1985 by Xerox Corporation. All rights reserved.
Last Edited by: Barth, July 2, 1985 12:48:01 pm PDT
Last Edited by: Gasbarro, June 20, 1985 6:35:50 pm PDT
DIRECTORY
CD, CMos, CMosContacts, PW, PWPins, Onion, Rope;
CrossRAMGen: CEDAR PROGRAM
IMPORTS CMos, CMosContacts, PW, PWPins, Onion, Rope =
BEGIN OPEN PW;
ROPE: TYPE = Rope.ROPE;
MakeCrossRAM: UserProc = {
SetDefaultSource[design, OpenDesign["///Users/Barth.pa/CrossRAM/CrossRAMCellLibrary.dale"]];
RETURN[MakeRAM[design]];
};
MakeRAM: PROC [design: Design] RETURNS [crossRAM: ObPtr]= {
rowQuads: INT = 60;
columnOcts: INT = 15;
decoder, array, right, top: ObPtr;
CrossRamPadFrame: ObPtr ← PW.Get[design, "CrossRamPadFrame"];
RightPower: ObPtr ← PW.Get[design, "RightPower"];
result: ObPtr;
params: Onion.LayersParameters ← NEW[Onion.LayersParametersRec ← [radialLayer: CMos.met, ringLayer: CMos.met2, ringWidth: Onion.RingWidthIs8, contact: CMosContacts.CreateMmCon[10], ringRingDist: 8, wireExtendProc: Onion.WireExtendMetToMet]];
rows: INT = 4*rowQuads;
ndecoderCols: INTIF rows=TwoToTheLog2[rows] THEN Log2[rows] ELSE Log2[rows]+1;
ndecoderCols ← ndecoderCols-1; -- one bit goes to tree decoder
IF EVEN[ndecoderCols] THEN ERROR; -- decoder drivers always come in pairs
decoder ← MakeDecoder[design, rowQuads, ndecoderCols];
array ← RAMArray[design, rowQuads, columnOcts];
right ← ArrayY[design, RightPower, 2*rowQuads];
top ← MakeTop[design, ndecoderCols, columnOcts];
result ← Onion.MakeInner[design, AbutListY[design, LIST[MakeBottom[design, ndecoderCols, columnOcts], AbutX[design, decoder, array, right], top]]];
crossRAM ← Onion.LRSRoute[design, result, CrossRamPadFrame, Onion.Center[result, CrossRamPadFrame], params].cell;
};
MakeDecoder: PROC [design: Design, rowQuads, decoderCols: INT] RETURNS [decoder: ObPtr] = {
DecoderLogic: ObPtr← Get[design, "DecoderLogic"];
DecoderLeft: ObPtr← Get[design, "DecoderLeft"];
DecoderZero: ObPtr← Get[design, "DecoderZero"];
DecoderOne: ObPtr← Get[design, "DecoderOne"];
DecoderRight: ObPtr← Get[design, "DecoderRight"];
flipDecoderZero: ObPtr← FlipY[design, DecoderZero];
flipDecoderOne: ObPtr← FlipY[design, DecoderOne];
leftColumn, rightColumn, driverColumn: ObPtr;
rowPairs: INT = 2*rowQuads;
DecoderFunction: XYFunction = {
flip: BOOL = ODD[y];
IF XthBitOfN[decoderCols-1-x, y]
THEN RETURN[IF flip THEN flipDecoderOne ELSE DecoderOne]
ELSE RETURN[IF flip THEN flipDecoderZero ELSE DecoderZero];
};
leftColumn ← ArrayY[design, AbutY[design, DecoderLeft, FlipY[design, DecoderLeft]], rowQuads];
rightColumn ← ArrayY[design, AbutY[design, DecoderRight, FlipY[design, DecoderRight]], rowQuads];
driverColumn ← ArrayY[design, AbutY[design, DecoderLogic, FlipY[design, DecoderLogic]], rowQuads];
decoder ← AbutListX[design, LIST[leftColumn, MapFunction[design, DecoderFunction, 0, decoderCols, 0, rowPairs], rightColumn, driverColumn]];
};
RAMArray: PROC [design: Design, rowQuads, columnOcts: INT] RETURNS [array: ObPtr] = {
SubArray: PROC [dataName, stitchName: ROPE] RETURNS [array: ObPtr] = {
dataCell: ObPtr← Get[design, dataName];
stitchCell: ObPtr← Get[design, stitchName];
column: ObPtr ← ArrayY[design, dataCell, rowQuads];
oct: ObPtr ← AbutX[design, ArrayX[design, column, 8], ArrayY[design, stitchCell, rowQuads]];
array ← ArrayX[design, oct, columnOcts];
prestitch: ObPtr ← ArrayX[design, ArrayY[design, ArrayX[design, ArrayY[design, ArrayX[design, dataCell, 2], 2], 2], 2], 2];
withstitch: ObPtr ← AbutX[design, prestitch, ArrayY[design, stitchCell, 4]];
array ← ArrayX[design, ArrayY[design, ArrayX[design, ArrayY[design, withstitch, 3], 3], 5], 5];
};
IF rowQuads#60 OR columnOcts#15 THEN ERROR;
array ← AbutY[design, SubArray["SRamTwoBits", "SRamStitch"], SubArray["DRamTwoBits", "DRamStitch"]];
};
MakeBottom: PROC [design: Design, decoderCols, dataOcts: INT] RETURNS [bottom: ObPtr] = {
PrechargeSlice: ObPtr ← Get[design, "PrechargeSlice"];
PrechargeStich: ObPtr ← Get[design, "PrechargeStich"];
BottomDecoderLeft: ObPtr ← Get[design, "BottomDecoderLeft"];
BottomDecoder: ObPtr ← Get[design, "BottomDecoder"];
BottomDecoderRight: ObPtr ← Get[design, "BottomDecoderRight"];
BottomRight: ObPtr ← Get[design, "BottomRight"];
precharge: ObPtr ← ArrayX[design, AbutX[design, ArrayX[design, PrechargeSlice, 8], PrechargeStich], dataOcts];
bottomDecoder: ObPtr ← ArrayX[design, BottomDecoder, decoderCols];
bottom ← AbutListX[design, LIST[BottomDecoderLeft, bottomDecoder, BottomDecoderRight, precharge, BottomRight]];
};
MakeTop: PROC [design: Design, decoderCols, dataOcts: INT] RETURNS [top: ObPtr] = {
listOb: PW.ListOb ← NIL;
DecoderDriverLeft: ObPtr← Get[design, "DecoderDriverLeft"];
DecoderDriver: ObPtr← Get[design, "DecoderDriver"];
DecoderLogicDriver: ObPtr← Get[design, "DecoderLogicDriver"];
dataBuffer: ObPtr← MakeDataBuffer[design, dataOcts];
DataBufferRight: ObPtr← Get[design, "DataBufferRight"];
stackDriverCount: INT ← (decoderCols+1)/2-1;
stackDriver: ObPtr ← Inst[design, DecoderDriver, LIST["RemoveForStackDecoderBit"]];
treeDriver: ObPtr ← Inst[design, DecoderDriver, LIST["RemoveForTreeDecoderBit"]];
drivers: ObPtr ← treeDriver;
IF stackDriverCount>0 THEN {
listOb ← CONS[drivers, listOb];
FOR i: INT ← 0, i+2 UNTIL i>=2*stackDriverCount DO
RenameData: PWPins.RenameProc = {
IF Rope.Equal[oldRope, "add[3]"] THEN newRope ← PWPins.Index["add", i+5];
IF Rope.Equal[oldRope, "add[4]"] THEN newRope ← PWPins.Index["add", i+6];
};
listOb ← CONS[PWPins.RenamePins[design, stackDriver, RenameData], listOb];
ENDLOOP;
drivers ← AbutListX[design, listOb];
};
top ← AbutListX[design, LIST[DecoderDriverLeft, drivers, DecoderLogicDriver, dataBuffer, DataBufferRight]]
};
MakeDataBuffer: PROC [design: Design, dataOcts: INT] RETURNS [top: ObPtr] = {
bitsPerDecoder: INT = 8;
listOb: PW.ListOb ← NIL;
BitDrive, arrayTop, block, BitSelNoPoly, BitSelContact, BitSelPoly, BitLineConnect, BitMux, BitMuxEnd, DecoderStitch:PW.ObPtr;
BitConnect: XYFunction ={
IF x>y THEN RETURN[BitSelNoPoly];
IF x=y THEN RETURN[BitSelContact];
IF x<y THEN RETURN[BitSelPoly];
};
BitDrive ← PW.Get[design, "BitDrive"];
BitSelNoPoly ← PW.Get[design, "BitSelNoPoly"];
BitSelContact ← PW.Get[design, "BitSelContact"];
BitSelPoly ← PW.Get[design, "BitSelPoly"];
BitLineConnect ← PW.Get[design, "BitLineConnect"];
BitMux ← PW.Get[design, "BitMux"];
BitMuxEnd ← PW.Get[design, "BitMuxEnd"];
DecoderStitch ← PW.Get[design, "DecoderStitch"];
block ← AbutX[design, AbutY[design,
ArrayX[design, BitLineConnect, bitsPerDecoder],
MapFunction[design, BitConnect, 0,bitsPerDecoder, 0,bitsPerDecoder],
AbutX[design, BitMuxEnd, ArrayX[design, BitMux    , bitsPerDecoder-1]],
BitDrive
], DecoderStitch];
FOR i: INT IN [0..dataOcts) DO
RenameData: PWPins.RenameProc =
{IF Rope.Equal[oldRope, "data"] THEN newRope ← PWPins.Index[oldRope, i];};
listOb ← CONS[PWPins.RenamePins[design, block, RenameData], listOb];
ENDLOOP;
arrayTop ← PW.AbutListX[design, listOb];
RETURN[arrayTop];
};
Register[MakeCrossRAM, "MakeCrossRAM"];
END.