IFUAdderRow:
PUBLIC
PROC[
design: CD.Design,
name: Rope.ROPE,
ctl: LIST OF REF ← NIL,
top: LIST OF REF ← NIL,
in: LIST OF REF ← NIL,
out: LIST OF REF ← NIL,
bot: LIST OF REF ← NIL,
sums: INT ← 1,
seq:
BOOL ←
FALSE ]
RETURNS[cellName: IFUPW.ObjName]= { -- positive bus on top
controlOnTop: BOOL ← PW.ODD[PW.Log2[IFUPW.rngByte*IFUPW.rngBit/sums]];
wdA: InterfaceWdLIST;
wdIn: LIST OF List;
list1, list2: LIST OF REF ← NIL;
cellList, mainList, ctls: IFUPW.List ← NIL;
size: IFUPW.Size;
in1Y, in2Y, outY: INT;
refCell, obj: CD.ObPtr;
met2Box, polyBox, switchbox: IFUPW.ObjName;
gpcRow, sumRow: IFUPW.ObjName;
[wdA, wdIn] ← GenInterleavedSplitTreeNames[sums, (IF seq THEN 4 ELSE 1)];
FOR ii:
INT
DECREASING
IN [0..sums)
DO
ctls ← CONS[Rope.Cat["C", Convert.RopeFromInt[ii]], ctls] ENDLOOP;
list1 ← list2 ← NIL;
list2 ← ConsGPCCopyOnLIST [list2, wdA[top][lng][rt], FALSE, TRUE, FALSE];
list2 ← ConsGPCCopyOnLIST [list2, wdA[top][lng][lt], FALSE, TRUE, FALSE];
list2 ← ConsNILsOnLIST [list2, 8];
met2Box ←
IFUPW.SwitchBoxRow[
design: design,
name: name.Cat["TopMet2"],
rowType: IFUPW.cmosMet2,
topSeq: seq,
top: list1,
left: NIL,
right: IF controlOnTop THEN ctls ELSE NIL,
bot: list2,
botSeq: seq,
fixGV: TRUE ];
list1 ← list2 ← NIL;
list2 ← ConsGPCCopyOnLIST [list2, wdA[top][srt][rt], FALSE, TRUE, FALSE];
list2 ← ConsGPCCopyOnLIST [list2, wdA[top][srt][lt], FALSE, TRUE, FALSE];
list2 ← ConsNILsOnLIST [list2, 8];
polyBox ←
IFUPW.SwitchBoxRow[
design: design,
name: name.Cat["TopPoly"],
rowType: IFUPW.cmosPoly,
topSeq: seq,
top: list1,
left: NIL,
right: NIL,
bot: list2,
botSeq: seq,
fixGV: TRUE,
m2Pitch: TRUE ];
switchbox ← ShiftMergeFill[design, polyBox, met2Box, name.Cat["SwitchTop"]];
mainList ← CONS[switchbox, mainList];
cellList ← NIL;
FOR index:
INT
DECREASING
IN [0..
IFUPW.rngByte*
IFUPW.rngBit)
DO
byte, bit, numIndex, level: INT ← 0;
[byte, bit] ← IFUPW.ByteBitFromIndex[index, seq];
numIndex ← (byte*8+bit) MOD (IFUPW.rngByte*IFUPW.rngBit/sums);
FOR val: INT ← numIndex, val/2 WHILE (val MOD 2) = 1 DO level ← level+1 ENDLOOP;
cellList ←
CONS[
(
IF numIndex+1 = (
IFUPW.rngByte*
IFUPW.rngBit/sums)
THEN "GPAdderGPCBlank"
ELSE
IF (level
MOD 2)=0
THEN "GPAdderGPC0"
ELSE "GPAdderGPC1"),
cellList];
ENDLOOP;
gpcRow ← IFUPW.AbutListX[design, cellList];
obj ← CDDirectory.Fetch[design, gpcRow].object;
[ ] ← CDDirectory.Rename[design, obj, name.Cat["GPC"]];
mainList ← CONS[CDDirectory.Name[obj], mainList];
list1 ← list2 ← NIL;
list1 ← ConsGPCCopyOnLIST [list1, wdA[bot][lng][rt]];
list1 ← ConsGPCCopyOnLIST [list1, wdA[bot][lng][lt]];
list1 ← ConsNILsOnLIST [list1, 8];
met2Box ←
IFUPW.SwitchBoxRow[
design: design,
name: name.Cat["BotMet2"],
rowType: IFUPW.cmosMet2,
topSeq: seq,
top: list1,
left: NIL,
right: IF ~controlOnTop THEN ctls ELSE NIL,
bot: list2,
botSeq: seq,
fixGV: TRUE ];
list1 ← list2 ← NIL;
list1 ← ConsGPCCopyOnLIST [list1, wdA[bot][srt][rt]];
list1 ← ConsGPCCopyOnLIST [list1, wdA[bot][srt][lt]];
list1 ← ConsNILsOnLIST [list1, 8];
list2 ← ConsGPCCopyOnLIST [list2, wdIn];
list2 ← ConsNILsOnLIST [list2, 8];
polyBox ←
IFUPW.SwitchBoxRow[
design: design,
name: name.Cat["BotPoly"],
rowType: IFUPW.cmosPoly,
topSeq: seq,
top: list1,
left: NIL,
right: NIL,
bot: list2,
botSeq: seq,
fixGV: TRUE,
m2Pitch: TRUE ];
switchbox ← ShiftMergeFill[design, polyBox, met2Box, name.Cat["SwitchBot"]];
mainList ← CONS[switchbox, mainList];
cellList ← NIL;
FOR index:
INT
DECREASING
IN [0..
IFUPW.rngByte*
IFUPW.rngBit)
DO
cellList ← CONS["GPAdderSum", cellList] ENDLOOP;
sumRow ← IFUPW.AbutListX[design, cellList];
obj ← CDDirectory.Fetch[design, sumRow].object;
[ ] ← CDDirectory.Rename[design, obj, name.Cat["XOR"]];
mainList ← CONS[CDDirectory.Name[obj], mainList];
cellName ← IFUPW.AbutListY[design, mainList];
size ← PWBasics.GetISize[CDDirectory.Fetch[design, cellName].object];
obj ← CDCells.CreateEmptyCell[];
[]←PWBasics.IncludeApplication[obj, CDDirectory.Fetch[design, cellName].object];
refCell ← CDDirectory.Fetch[design, "GPAdderSum"].object;
in1Y ← CDPinObjects.FindPins[refCell, "In1"].first.location.y;
in2Y ← CDPinObjects.FindPins[refCell, "In2"].first.location.y;
outY ← CDPinObjects.FindPins[refCell, "Out"].first.location.y;
FOR index:
INT
IN [0..
IFUPW.rngBit)
DO
FOR byte:
INT
IN [0..
IFUPW.rngByte)
DO
refX: INT ← IFUPW.cellWidth*IFUPW.ByteBitToIndex[byte, index, seq];
topl: IFUPW.List ← IFUPW.FixGVInList[IFUPW.ExpandList[byte, index, top]];
botl: IFUPW.List ← IFUPW.FixGVInList[IFUPW.ExpandList[byte, index, bot]];
inl: IFUPW.List ← IFUPW.ExpandList[byte, index, in];
outl: IFUPW.List ← IFUPW.ExpandList[byte, index, out];
IFUPW.IOConnect[
design: design,
cell: obj,
refX: refX,
top: topl,
topY: size.y,
in1: IF inl=NIL THEN NIL ELSE inl.first,
in2: IF inl=NIL THEN NIL ELSE IF inl.rest=NIL THEN NIL ELSE inl.rest.first,
out: IF outl=NIL THEN NIL ELSE outl.first,
in1Y: in1Y,
in2Y: in2Y,
outY: outY,
botY: 0,
bot: botl ];
IFUPW.AddMetalPins[obj, topl, botl, refX, size.y, 0, TRUE];
ENDLOOP;
ENDLOOP;
PWBasics.RepositionCell[design, obj];
[ ] ← CDDirectory.Rename[design, obj, name];
cellName ← CDDirectory.Name[obj]};
ShiftMergeFill:
PROC
[design: CD.Design, lrgBox, smlBox: IFUPW.ObjName, name: ROPE]
RETURNS[cellName: IFUPW.ObjName] = {
lrgObj: CD.ObPtr ← CDDirectory.Fetch[design, lrgBox].object;
smlObj: CD.ObPtr ← CDDirectory.Fetch[design, smlBox].object;
lrgRect: CD.DesignRect ← CD.InterestRect[lrgObj];
smlRect: CD.DesignRect ← CD.InterestRect[smlObj];
diff: INT ← (lrgRect.y2 - lrgRect.y1) - (smlRect.y2 - smlRect.y1);
fillerTop: CD.ObPtr ← NIL;
fillerBot: CD.ObPtr ← NIL;
cell: CD.ObPtr ← CDCells.CreateEmptyCell[];
fTopName: IFUPW.ObjName ← NIL;
fBotName: IFUPW.ObjName ← NIL;
IF diff<9
THEN {
IF diff#0 THEN ERROR;
fillerTop ← IFUPW.FillerCell[design, lrgObj, IFUPW.TopSide, 3*9, FALSE];
fillerBot ← IFUPW.FillerCell[design, smlObj, IFUPW.BotSide, 3*9, FALSE];
fTopName ← CDDirectory.Name[fillerTop];
fBotName ← CDDirectory.Name[fillerBot];
smlBox ← IFUPW.AbutListY[design, LIST [fBotName, smlBox]];
lrgBox ← IFUPW.AbutListY[design, LIST [lrgBox, fTopName]];
smlObj ← CDDirectory.Fetch[design, smlBox].object;
lrgObj ← CDDirectory.Fetch[design, lrgBox].object}
ELSE {
fillerTop ← IFUPW.FillerCell[design, smlObj, IFUPW.TopSide, 9, FALSE];
fillerBot ← IFUPW.FillerCell[design, smlObj, IFUPW.BotSide, diff - 9, FALSE];
fTopName ← CDDirectory.Name[fillerTop];
fBotName ← CDDirectory.Name[fillerBot];
smlBox ← IFUPW.AbutListY[design, LIST [fBotName, smlBox, fTopName]];
smlObj ← CDDirectory.Fetch[design, smlBox].object};
[]←PWBasics.IncludeApplication[cell, smlObj];
[]←PWBasics.IncludeApplication[cell, lrgObj];
PWBasics.RepositionCell[design, cell, name];
RETURN[CDDirectory.Name[cell]] };