<> <> <> <<>> DIRECTORY Basics, CD, CDCells, CDDirectory, Convert, IFUPW, PW, Rope; IFUPWAdder: CEDAR PROGRAM IMPORTS CD, CDCells, CDDirectory, Convert, IFUPW, PW, Rope EXPORTS IFUPW = BEGIN List: TYPE = IFUPW.List; ROPE: TYPE = Rope.ROPE; 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]}; <> TopBot: TYPE = {top, bot}; LngSrt: TYPE = {lng, srt}; LtRt: TYPE = {lt, rt}; InterfaceWdLIST: TYPE = ARRAY TopBot OF ARRAY LngSrt OF ARRAY LtRt OF LIST OF List _ ALL[ALL[ALL[NIL]]]; InterfaceByteLIST: TYPE = ARRAY TopBot OF ARRAY LngSrt OF ARRAY LtRt OF List _ ALL[ALL[ALL[NIL]]]; InterfaceNameLIST: TYPE = ARRAY TopBot OF ARRAY LngSrt OF ARRAY LtRt OF ROPE _ ALL[ALL[ALL[NIL]]]; GenInterleavedSplitTreeNames: PROC[ nofResults: INT, -- rngByte, longThres: INT, -- rngByte, differences <= to this are short wires rp: IFUPW.RowParams] -- IFUDataColNSeq implies partitioning of result lists RETURNS[wdA: InterfaceWdLIST, wdIn: LIST OF List] = { AddIndices: PROC[rope: ROPE, int1, int2: INT] RETURNS[ROPE] = { rope _ IFUPW.AppendIndexToRope[int1, rope]; rope _ IFUPW.AppendIndexToRope[int2, rope]; RETURN[rope]}; insOnTop: BOOL _ FALSE; secLength: INT _ (rp.rngByte * rp.rngBit) / nofResults; FOR byte: INT DECREASING IN [0..rp.rngByte) DO byteA: InterfaceByteLIST; byteIn: List _ NIL; FOR bit: INT DECREASING IN [0..rp.rngBit) DO longWire: BOOL _ TRUE; nameA: InterfaceNameLIST; nameIn: ROPE _ NIL; size: INT _ 1; -- will be length of output level: INT _ 0; section: INT _ ((byte * rp.rngBit) + bit) / secLength; index: INT _ ((byte * rp.rngBit) + bit) MOD secLength; topln, botln: LngSrt; FOR val: INT _ index, val/2 WHILE (val MOD 2) = 1 DO level _ level+1; size _ size*2 ENDLOOP; topln _ IF size/2 > longThres THEN lng ELSE srt; botln _ IF size > longThres THEN lng ELSE srt; nameIn _ AddIndices["In.", section, index]; SELECT size FROM 1 => { nameA[top][topln][lt] _ AddIndices["In.", section, index]; nameA[top][topln][rt] _ AddIndices["In.", section, index+1]; nameA[bot][botln][rt] _ AddIndices["Xx.", section, index]}; secLength/2 =>{ nameA[top][topln][lt] _ AddIndices["Xx.", section, index - size/2]; nameA[top][topln][rt] _ AddIndices["Xx.", section, index + size/2]; nameA[bot][botln][rt] _ Convert.RopeFromInt[section,36,FALSE]}; secLength => NULL; ENDCASE => { nameA[top][topln][lt] _ AddIndices["Xx.", section, index - size/2]; nameA[top][topln][rt] _ AddIndices["Xx.", section, index + size/2]; nameA[bot][botln][rt] _ AddIndices["Xx.", section, index]}; IF (level MOD 2 =1) = insOnTop THEN FOR ls: LngSrt IN LngSrt DO FOR lr: LtRt IN LtRt DO temp: ROPE _ nameA[bot][ls][lr]; nameA[bot][ls][lr] _ nameA[top][ls][lr]; nameA[top][ls][lr] _ temp; ENDLOOP ENDLOOP; byteIn _ CONS[nameIn, byteIn]; FOR tb: TopBot IN TopBot DO FOR ls: LngSrt IN LngSrt DO FOR lr: LtRt IN LtRt DO byteA[tb][ls][lr] _ CONS[nameA[tb][ls][lr], byteA[tb][ls][lr]]; ENDLOOP ENDLOOP ENDLOOP; ENDLOOP; wdIn _ CONS[byteIn, wdIn]; FOR tb: TopBot IN TopBot DO FOR ls: LngSrt IN LngSrt DO FOR lr: LtRt IN LtRt DO wdA[tb][ls][lr] _ CONS[byteA[tb][ls][lr], wdA[tb][ls][lr]] ENDLOOP ENDLOOP ENDLOOP; ENDLOOP }; ConsGPCCopyOnLIST: PROC [rp: IFUPW.RowParams, list: LIST OF REF, ref: LIST OF List, gout, cout, pout: BOOL _ FALSE] RETURNS[new: LIST OF REF] = { new _ CONS[CopyModifiedLIST[ref: ref, rope: "C", shortRopes: cout, rp: rp], list]; new _ CONS[CopyModifiedLIST[ref: ref, rope: "P", shortRopes: pout, rp: rp], new]; new _ CONS[CopyModifiedLIST[ref: ref, rope: "G", shortRopes: gout, rp: rp], new]}; CopyModifiedLIST: PROC [ref: LIST OF List, rope: Rope.ROPE, shortRopes: BOOL, rp: IFUPW.RowParams] RETURNS[new: LIST OF List] = { LISTIndexItem: PROC [list: LIST OF List, index: INT] RETURNS[item: List] = { FOR index _ index, index-1 WHILE index#0 AND list#NIL DO list_list.rest ENDLOOP; RETURN[IF list=NIL THEN NIL ELSE list.first]}; new _ NIL; FOR i1: INT DECREASING IN [0..rp.rngByte) DO rlist: List _ LISTIndexItem[ref, i1]; nlist: List _ NIL; FOR i2: INT DECREASING IN [0..8) DO rrope: Rope.ROPE _ IFUPW.ListIndexItem[rlist, i2]; rrope _ IF rrope = NIL OR rrope.Length[]=0 OR (rrope.Length[]<3 AND ~shortRopes) THEN NIL ELSE rope.Cat[rrope]; nlist _ CONS[rrope, nlist]; ENDLOOP; new _ CONS[nlist, new]; ENDLOOP}; ConsNILsOnLIST: PROC[count: INT, list: LIST OF REF] RETURNS[new: LIST OF REF] = { new _ list; FOR count _ count, count-1 WHILE count#0 DO new _ CONS[NIL, new] ENDLOOP}; ShiftMergeFill: PROC [design: CD.Design, lrgObj, smlObj: CD.Object, name: ROPE] RETURNS[cell: CD.Object] = { lrgRect: IFUPW.Size _ CD.InterestSize[lrgObj]; smlRect: IFUPW.Size _ CD.InterestSize[smlObj]; diff: INT _ lrgRect.y - smlRect.y; fillerTop: CD.Object _ NIL; fillerBot: CD.Object _ NIL; cell _ CDCells.CreateEmptyCell[]; IF diff<9 THEN { IF diff#0 THEN ERROR; fillerTop _ IFUPW.FillerCell[design, lrgObj, top, 3*9, FALSE]; fillerBot _ IFUPW.FillerCell[design, smlObj, bottom, 3*9, FALSE]; smlObj _ PW.AbutListY[design, LIST [fillerBot, smlObj]]; lrgObj _ PW.AbutListY[design, LIST [lrgObj, fillerTop]]} ELSE { fillerTop _ IFUPW.FillerCell[design, smlObj, top, 9, FALSE]; fillerBot _ IFUPW.FillerCell[design, smlObj, bottom, diff - 9, FALSE]; smlObj _ PW.AbutListY[design, LIST [fillerBot, smlObj, fillerTop]]}; []_PW.IncludeInCell[cell, smlObj]; []_PW.IncludeInCell[cell, lrgObj]; PW.IncludeInDirectory[design, cell, name]; RETURN[cell] }; <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <<>> <> <> <> <<>> END.