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. ‚IFUPWAdder.mesa Copyright c 1985 by Xerox Corporation. All rights reserved. Last Edited by Curry, November 20, 1985 3:42:02 pm PST PW.RenameObject[design, cell, name]}; Adder32x1x1: IFUPW.UserProc = {RETURN[ IFUAdderRow[ design: design, name: "AdderTest", ctl: NIL, top: LIST["XBus.", "SumLt.", "SumRt."], in: LIST["SumLt.", "SumRt."], out: LIST["Sum."], bot: LIST["XBus.", "Sum."], sums: 1, rp: IFUDataColNSeq ]]}; Adder32x1x1Seq: IFUPW.UserProc = {RETURN[ IFUAdderRow[ design: design, name: "AdderTest", ctl: NIL, top: LIST["XBus.", "SumLt.", "SumRt."], in: LIST["SumLt.", "SumRt."], out: LIST["Sum."], bot: LIST["XBus.", "Sum."], sums: 1, rp: IFUDataColSeq ]]}; Adder32x4x4: IFUPW.UserProc = {RETURN[ IFUAdderRow[ design: design, name: "AdderTest", ctl: NIL, top: LIST["XBus.", "SumLt.", "SumRt."], in: LIST["SumLt.", "SumRt."], out: LIST["Sum."], bot: LIST["XBus.", "Sum."], sums: 4, rp: IFUDataColNSeq ]]}; IFUPW.Register[Adder32x1x1, "Adder32x1x1"]; IFUPW.Register[Adder32x1x1Seq, "Adder32x1x1Seq"]; IFUPW.Register[Adder32x4x4, "Adder32x4x4"]; �ÊÛ˜šœ™Jšœ<™Jšœ ˜ Jšœ ˜ —J˜Jšœ�œ˜Jšœ9˜9Jšœ9˜9Jšœ$˜$Jšœ,˜,Jšœ$˜$šœ �œ˜Jšœ˜Jšœ˜Jšœ �œ ˜Jšœ ˜ Jšœ ˜ Jšœ�œ˜ Jšœ�œ˜ Jšœ ˜ Jšœ ˜ Jšœ �œ˜—J˜JšœL˜LJšœ �œ˜%J˜Jšœ �œ˜š �œ�œ� œ�œ�˜9Jšœ �œ;�œ˜R—Jšœ �œ˜(Jš�œ/˜1Jšœ �œ˜"Jšœ �œ˜(J˜Jšœ�œ˜Jšœ!˜!Jšœ�œ˜"Jšœ9˜9š�œ�œ�œ�˜#š�œ�œ�œ�˜#Jšœ�œ�œ �œ!˜BJšœ�œ�œ �œ˜IJšœ�œ�œ �œ˜IJšœ�œ�œ˜4Jšœ�œ�œ˜6Jš �œ�œ�œ�œ�œ�œ˜8š�œ ˜Jšœ˜Jšœ ˜ Jšœ ˜ Jšœ ˜ Jšœ ˜ Jšœ ˜ Jšœ˜Jšœ ˜ Jšœ ˜ Jšœ˜Jšœ ˜ —Jš�œ1�œ˜—Jšœ%™%J˜—Jšœ�œ˜Jšœ�œ˜Jšœ�œ ˜J˜šœ�œ˜š�œ�˜š�œ�˜Jš�œ�œ�œ�œ�œ�œ�œ�œ˜0———šœ�œ˜š�œ�˜š�œ�˜Jš �œ�œ�œ�œ�œ�œ˜(———šœ�œ˜š�œ�˜š�œ�˜Jš�œ�œ�œ�œ�œ�œ�œ˜(———J˜šžœ�œ˜#Jšœ �œŸ ˜Jšœ �œŸ5˜Gšœ�œ Ÿ7˜OJš�œ�œ�œ ˜5—š ž œ�œ�œ�œ�œ�œ˜?Jšœ�œ˜+Jšœ�œ˜+Jš�œ˜—Jšœ �œ�œ˜Jšœ �œ)˜7š �œ�œ� œ�œ�˜.Jšœ)�œ˜-š �œ�œ� œ�œ�˜,Jšœ �œ�œ˜Jšœ"�œ�œ˜-Jšœ�œŸ˜*Jšœ�œ˜Jšœ �œ*˜6Jšœ�œ�œ ˜7Jšœ˜š�œ�œ�œ�œ˜1Jš�œ �œ˜*—Jšœ�œ�œ�œ˜0Jšœ�œ�œ�œ˜/Jšœ1˜1š�œ�˜šœ ˜ Jšœ:˜:Jšœ<˜