IFUAdderRow:
PUBLIC
PROC[
design: CD.Design,
name: Rope.ROPE,
leftCtl: List ← NIL,
rightCtl: List ← NIL,
top: LIST OF REF ← NIL,
in: LIST OF REF ← NIL,
out: LIST OF REF ← NIL,
bot: LIST OF REF ← NIL,
sums: INT ← 1,
rp:
IFUPW.RowParams ←
IFUPW.IFUDataColNSeq ]
RETURNS[cell: CD.Object]= { -- positive bus on top
controlOnRt: BOOL ← leftCtl=NIL;
controlOnTop: BOOL ← PW.ODD[PW.Log2[rp.rngByte*rp.rngBit/sums]];
wdA: InterfaceWdLIST;
wdIn: LIST OF List;
list1, list2: LIST OF REF ← NIL;
ctls: IFUPW.List ← NIL;
cellList, mainList: PW.ListOb ← NIL;
size: IFUPW.Size;
gpcRow, sumRow, refCell, met2Box, polyBox, switchbox: CD.Object;
[wdA, wdIn] ← GenInterleavedSplitTreeNames
[sums, (IF rp.seq THEN rp.rngByte ELSE 1), rp];
FOR ii:
INT
DECREASING
IN [0..sums)
DO
ctls ← CONS[Rope.Cat["C", Convert.RopeFromInt[ii]], ctls] ENDLOOP;
list1 ← list2 ← NIL;
list2 ← ConsGPCCopyOnLIST [rp, list2, wdA[top][lng][rt], FALSE, TRUE, FALSE];
list2 ← ConsGPCCopyOnLIST [rp, list2, wdA[top][lng][lt], FALSE, TRUE, FALSE];
list2 ← ConsNILsOnLIST [8, list2];
met2Box ←
IFUPW.SwitchBoxRow[
design: design,
name: name.Cat["TopMet2"],
rowType: IFUPW.cmosMet2,
topRP: rp,
top: list1,
left: IF controlOnTop AND ~controlOnRt THEN ctls ELSE NIL,
right: IF controlOnTop AND controlOnRt THEN ctls ELSE NIL,
bot: list2,
botRP: rp ];
list1 ← list2 ← NIL;
list2 ← ConsGPCCopyOnLIST [rp, list2, wdA[top][srt][rt], FALSE, TRUE, FALSE];
list2 ← ConsGPCCopyOnLIST [rp, list2, wdA[top][srt][lt], FALSE, TRUE, FALSE];
list2 ← ConsNILsOnLIST [8, list2];
polyBox ←
IFUPW.SwitchBoxRow[
design: design,
name: name.Cat["TopPoly"],
rowType: IFUPW.cmosPoly,
topRP: rp,
top: list1,
left: NIL,
right: NIL,
bot: list2,
botRP: rp,
m2Pitch: TRUE ];
switchbox ← ShiftMergeFill[design, polyBox, met2Box, name.Cat["SwitchTop"]];
mainList ← CONS[switchbox, mainList];
cellList ← NIL;
FOR index:
INT
DECREASING
IN [0..rp.rngByte*rp.rngBit)
DO
byte, bit, numIndex, level: INT ← 0;
[byte, bit] ← IFUPW.ByteBitFromIndex[index, rp];
numIndex ← (byte*8+bit) MOD (rp.rngByte*rp.rngBit/sums);
FOR val: INT ← numIndex, val/2 WHILE (val MOD 2) = 1 DO level ← level+1 ENDLOOP;
cellList ←
CONS[
(
IF numIndex+1 = (rp.rngByte*rp.rngBit/sums)
THEN CDDirectory.Fetch[design, "GPAdderGPCBlank"].object
ELSE
IF (level
MOD 2)=0
THEN CDDirectory.Fetch[design, "GPAdderGPC0"].object
ELSE CDDirectory.Fetch[design, "GPAdderGPC1"].object),
cellList];
ENDLOOP;
gpcRow ← PW.AbutListX[design, cellList];
PW.RenameObject[design, gpcRow, name.Cat["GPC"]];
mainList ← CONS[gpcRow, mainList];
list1 ← list2 ← NIL;
list1 ← ConsGPCCopyOnLIST [rp, list1, wdA[bot][lng][rt]];
list1 ← ConsGPCCopyOnLIST [rp, list1, wdA[bot][lng][lt]];
list1 ← ConsNILsOnLIST [8, list1];
met2Box ←
IFUPW.SwitchBoxRow[
design: design,
name: name.Cat["BotMet2"],
rowType: IFUPW.cmosMet2,
topRP: rp,
top: list1,
left: IF ~controlOnTop AND ~controlOnRt THEN ctls ELSE NIL,
right: IF ~controlOnTop AND controlOnRt THEN ctls ELSE NIL,
bot: list2,
botRP: rp ];
list1 ← list2 ← NIL;
list1 ← ConsGPCCopyOnLIST [rp, list1, wdA[bot][srt][rt]];
list1 ← ConsGPCCopyOnLIST [rp, list1, wdA[bot][srt][lt]];
list1 ← ConsNILsOnLIST [8, list1];
list2 ← ConsGPCCopyOnLIST [rp, list2, wdIn];
list2 ← ConsNILsOnLIST [8, list2];
polyBox ←
IFUPW.SwitchBoxRow[
design: design,
name: name.Cat["BotPoly"],
rowType: IFUPW.cmosPoly,
topRP: rp,
top: list1,
left: NIL,
right: NIL,
bot: list2,
botRP: rp,
m2Pitch: TRUE ];
switchbox ← ShiftMergeFill[design, polyBox, met2Box, name.Cat["SwitchBot"]];
mainList ← CONS[switchbox, mainList];
cellList ← NIL;
FOR index:
INT
DECREASING
IN [0..rp.rngByte*rp.rngBit)
DO
cellList ← CONS[CDDirectory.Fetch[design, "GPAdderSum"].object, cellList] ENDLOOP;
sumRow ← PW.AbutListX[design, cellList];
PW.RenameObject[design, sumRow, name.Cat["XOR"]];
mainList ← CONS[sumRow, mainList];
sumRow ← PW.AbutListY[design, mainList];
size ← CD.InterestSize[sumRow];
cell ← CDCells.CreateEmptyCell[];
[]←PW.IncludeInCell[cell, sumRow];
refCell ← CDDirectory.Fetch[design, "GPAdderSum"].object;
FOR index:
INT
IN [0..rp.rngBit)
DO
FOR byte:
INT
IN [0..rp.rngByte)
DO
refX: INT ← IFUPW.cellWidth*IFUPW.ByteBitToIndex[byte, index, rp];
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];
IF outl = NIL OR outl.first = NIL THEN inl ← outl ← NIL;
IFUPW.IOConnect[
design: design,
cell: cell,
top: topl,
in: inl,
out: outl,
bot: botl,
refcell: refCell,
refX: refX,
refY: 0,
topY: size.y,
botY: 0 ];
IFUPW.AddMetalPins[cell, topl, botl, refX, size.y, 0, TRUE];
ENDLOOP;
ENDLOOP;
PW.IncludeInDirectory[design, cell];
cell ←
IFUPW.RenameObjAndAssignRowPins
[design, cell, name, FALSE, top, bot, leftCtl, rightCtl, rp]};
PW.RenameObject[design, cell, name]};