DIRECTORY Cabbage, CD, CDOrient, CDProperties, CDSymbolicObjects, CMos, Connections, Core, CoreClasses, CoreOps, CoreProperties, PadFrameMaker, PW, PWPins, Rope, RTBasic, SCCoreUtil, CDCells; PadFrameMakerImpl: CEDAR PROGRAM IMPORTS Cabbage, CD, CDCells, CMos, CoreOps, CDProperties, Connections, CoreProperties, CDSymbolicObjects, PW, PWPins, Rope, SCCoreUtil EXPORTS PadFrameMaker ~ BEGIN ListPadData: TYPE = LIST OF PadData; PadData: TYPE = REF PadDataRec; PadDataRec: TYPE = RECORD [ type: Rope.ROPE _ NIL, cdOb: CD.Object _ NIL, bindings: LIST OF WirePair]; WirePair: TYPE = RECORD [ formal, actual: Rope.ROPE _ NIL]; CollectBindings: PROC [cellInstance: CoreClasses.CellInstance] RETURNS[bindings: LIST OF WirePair _ NIL] = { DoWire: CoreOps.EachWirePairProc = { wirePair: WirePair _ []; IF actualWire # NIL AND actualWire.size = 0 AND publicWire # NIL AND publicWire.size = 0 THEN { wirePair.formal _ NARROW[CoreProperties.GetWireProp[publicWire, CoreOps.nameProp]]; wirePair.actual _ NARROW[CoreProperties.GetWireProp[actualWire, CoreOps.nameProp]]; bindings _ CONS[wirePair, bindings]; }; }; [] _ CoreOps.VisitBinding[cellInstance.actual, cellInstance.type.public, DoWire]; }; MakePadRows: PUBLIC PROC [ libDesign, resultDesign: CD.Design, padFrameCell: Core.CellType, inner: CD.Object] RETURNS [chip: CD.Object] = { pads: ARRAY RTBasic.Side OF PW.ListOb _ ALL[NIL]; padData: ARRAY RTBasic.Side OF ListPadData _ ALL[NIL]; padCells: ARRAY RTBasic.Side OF CD.Object _ ALL[NIL]; side: RTBasic.Side _ RTBasic.Side.FIRST; sideName: ARRAY RTBasic.Side OF Rope.ROPE _ ["bottom", "top", "left", "right"]; orientation: ARRAY RTBasic.Side OF CD.Orientation _ [CDOrient.rotate180, CDOrient.original, CDOrient.rotate90, CDOrient.rotate270]; connections: Connections.Table; routerParams: Cabbage.PadRingParams _ NEW[Cabbage.PadRingParamsRec _ ["metal", "metal2", resultDesign.technology.key]]; innerPos: CD.Position _ [0,0]; layers: ARRAY RTBasic.Side OF CD.Layer _ [CMos.met2, CMos.met2, CMos.met, CMos.met]; bottomLeft: CD.Object _ PW.Get[libDesign, "C2LB37V"]; topLeft: CD.Object _ PW.Get[libDesign, "C2LT37G"]; topRight: CD.Object _ PW.Get[libDesign, "C2RT37V"]; bottomRight: CD.Object _ PW.Get[libDesign, "C2RB37G"]; ProcessInstance: SCCoreUtil.EachInstanceProc = { name: Rope.ROPE _ NARROW[CoreProperties.GetCellTypeProp[cellInstance.type, CoreOps.nameProp]]; IF Rope.Match["C2*", name, FALSE] THEN { ob: CD.Object _ PW.Get[libDesign, name]; bindings: LIST OF WirePair _ NIL; pads[side] _ CONS[ob, pads[side]]; bindings _ CollectBindings[cellInstance]; padData[side] _ CONS[NEW[PadDataRec _ [name, ob, bindings]], padData[side]]; } ELSE { ChangeToSignalPin: PWPins.RenameProc = { RETURN[GetSignal[bindings, oldRope]]; }; bindings: LIST OF WirePair _ CollectBindings[cellInstance]; inner _ PWPins.RenamePins[ob: inner, renameProc: ChangeToSignalPin]; }; IF side = RTBasic.Side.LAST THEN side _ RTBasic.Side.FIRST ELSE side _ SUCC[side]; }; [] _ SCCoreUtil.EnumerateInstances[padFrameCell, ProcessInstance]; FOR side IN RTBasic.Side DO abutOb: CD.Object _ PW.AbutListX[pads[side]]; padCells[side] _ IncludeCell[abutOb, sideName[side]]; AddSignalPins[padCells[side], padData[side], layers[side]]; padCells[side] _ PW.ChangeOrientation[padCells[side], orientation[side]]; ENDLOOP; innerPos _ Cabbage.Center[inner, bottomLeft, padCells[bottom], bottomRight, padCells[right], topRight, padCells[top], topLeft, padCells[left], routerParams]; connections _ GetConnections[inner, padCells[bottom], padCells[right], padCells[top], padCells[left]]; chip _ Cabbage.PadRoute[inner, bottomLeft, padCells[bottom], bottomRight, padCells[right], topRight, padCells[top], topLeft, padCells[left], [innerPos.x-30, innerPos.y], connections, routerParams]; [] _ CDCells.IncludeOb[design: resultDesign, cell: NIL, ob: chip, position: [0, 0], orientation: CDOrient.original, cellCSystem: interrestCoords, obCSystem: interrestCoords, mode: dontPropagate]; PW.CleanUp[resultDesign]; }; GetConnections: PROC [inner, bottom, right, top, left: Cabbage.Object] RETURNS [connections: Connections.Table] ~ { UseAll: Connections.PinFilterProc ~ {keepIt _ TRUE}; UseTop: Connections.PinFilterProc ~ {keepIt _ PWPins.GetSide[obj, inst].side=top}; UseLeft: Connections.PinFilterProc ~ {keepIt _ PWPins.GetSide[obj, inst].side=left}; UseBottom: Connections.PinFilterProc ~ {keepIt _ PWPins.GetSide[obj, inst].side=bottom}; UseRight: Connections.PinFilterProc ~ {keepIt _ PWPins.GetSide[obj, inst].side=right}; connections _ Connections.CreateForRopes[]; Connections.InsertPins[connections, inner, UseAll]; Connections.InsertPins[connections, bottom, UseTop]; Connections.InsertPins[connections, right, UseLeft]; Connections.InsertPins[connections, top, UseBottom]; Connections.InsertPins[connections, left, UseRight]; }; GetSignal: PROC [bindings: LIST OF WirePair, formal: Rope.ROPE] RETURNS [actual: Rope.ROPE _ NIL] = { FOR bl: LIST OF WirePair _ bindings, bl.rest UNTIL bl = NIL DO IF Rope.Equal[bl.first.formal, formal] THEN RETURN [bl.first.actual]; ENDLOOP; }; AddSignalPins: PROC [padCell: CD.Object, padData: LIST OF PadData, layer: CD.Layer] = { xPos: CD.Number _ 0; list: LIST OF PadData _ NIL; MakeSignalPin: PWPins.InstanceEnumerator = { pinOb: CD.Object _ CDSymbolicObjects.CreatePin[inst.ob.size]; pinInst: CD.Instance _ NIL; signal: Rope.ROPE _ GetSignal[list.first.bindings, CDSymbolicObjects.GetName[inst]]; IF Rope.Equal[signal, "unconnected"] THEN RETURN; pinInst _ PW.IncludeInCell[ padCell, pinOb, [xPos+inst.location.x, inst.location.y]]; CDSymbolicObjects.SetName[pinInst, signal]; CDSymbolicObjects.SetLayer[pinInst, layer]; }; FOR list _ padData, list.rest UNTIL list = NIL DO [] _ PWPins.EnumerateEdgePins[ob: list.first.cdOb, eachPin: MakeSignalPin]; xPos _ xPos + list.first.cdOb.size.x; ENDLOOP; }; IncludeCell: PROC [rowOb: PW.Object, name: Rope.ROPE _ NIL, stopEnumerateDeepPins: BOOLEAN _ TRUE] RETURNS [rCell: CD.Object] = { rCellPtr: CD.CellPtr; inst: CD.Instance; rCell _ PW.CreateEmptyCell[]; rCellPtr _ NARROW [rCell.specificRef]; inst _ NEW [CD.InstanceRep _ [ob: rowOb]]; IF stopEnumerateDeepPins THEN CDProperties.PutProp[inst, $StopEnumerateDeepPins, $StopEnumerateDeepPins]; rCellPtr.contents _ CONS [inst, rCellPtr.contents]; rCellPtr.name _ name; CDCells.SetInterestRect[rCell, CD.InterestRect[rowOb]]; [] _ PW.RepositionCell[rCell]}; END. DPadFrameMakerImpl.mesa Frank Bowers June 19, 1986 11:24:23 am PDT Get layout for standard cell pads from padFrameCell ob _ PW.Get[libDesign, objectName]; divide pads into 4 groups: top left bottom and right PW.ListOb for each group create cells from each group by abutting PW.AbutListX create signal pins on top level cell for each group must keep Core celltype and CellInstance for actual-formal signal mapping perhaps attach core to CD cellinstance [cellInstance: CoreClasses.CellInstance] [] _ CDCells.IncludeOb[design: resultDesign, cell: NIL, ob: padCell, position: [0, 0], orientation: orientation[side], cellCSystem: interrestCoords, obCSystem: interrestCoords, mode: dontPropagate]; InstEnumerator: TYPE = PROC [inst: CD.Instance] RETURNS [quit: BOOL_FALSE]; CDProperties.PutInstanceProp[inst, $InstanceName, name]; Κ˜šœ™Icode™*—J˜J˜šΟk ˜ K˜Kšœ˜K˜ K˜ K˜K˜K˜ K˜K˜ K˜K˜Kšœ˜Kšœ˜K˜K˜K˜K˜ Kšœ˜K˜—K˜KšΠlnœœ˜ Kšœ œXœ˜‡Kšœ˜Kšœ˜K˜K˜Kšœ œœœ ˜$K˜Kšœ œœ ˜K˜šœ œœ˜Kšœ œœ˜Kšœœ œ˜Kšœ œœ ˜K˜—šœ œœ˜Kšœœœ˜!K˜K˜K˜šΟnœœ*˜?Kšœ œœ œ˜-˜šŸœ˜$K˜šœœœœœœœ˜_Kšœœ;˜SKšœœ;˜SKšœ œ˜$K˜—˜K˜———KšœQ˜QK˜——˜K˜K˜K˜šŸ œœœ˜Kšœœ-œ˜RKšœœ ˜K˜Kš œœœœ œœ˜1Kš œ œœœœ˜6Kš œ œœœ œœ˜5Kšœ"œ˜(Kšœ œœœ&˜OKšœ œœœ^˜ƒKšœ˜Kšœ&œN˜wKšœ œ˜Kšœœœœ4˜TK˜5K˜2K˜3K˜6K˜K˜K˜K˜K™YK™NK™5™3K™IK™&K™—šŸœ!˜0Kšœ(™(Kšœ œœF˜^šœœœ˜)Kšœœ œ˜(Kšœ œœ œ˜!Kšœ œ˜"K˜)Kšœœœ4˜LK˜—Kšœ˜˜šŸœ˜(Kšœ˜%J˜K˜—Kšœ œœ*˜;KšœD˜DK˜—Kš œœœœœœ˜RK˜K˜—K˜Bšœœ˜Kšœœ œ˜-Kšœ5˜5K˜;Kšœœ6˜Išœ-™-JšœœA™JJšœO™O—Kšœ˜—Kšœ˜Jšœf˜fJšœΕ˜Εšœ-˜-Jšœœ>˜GJšœO˜O—Kšœ˜K˜K˜K˜—šŸœœ3œ%˜sKšŸœ(œ˜4KšŸœL˜RKšŸœM˜TKšŸ œO˜XKšŸœN˜VK˜Kšœ+˜+Kšœ3˜3Kšœ4˜4Kšœ4˜4Kšœ4˜4Kšœ4˜4K˜—K˜š Ÿ œœ œœœ˜?Kšœœœ˜%š œœœœœ˜>Kšœ%œœ˜EKšœ˜—K˜—˜K˜—š Ÿ œœ œœœœ ˜WKšœœ ˜Kšœœœ œ˜K˜šŸ œ˜,Kš œœœœ œœœ™KKšœœ4˜=Kšœ œ ˜Kšœ œC˜TKšœ#œœ˜1šœ œ˜Kšœ9˜9—Jšœ+˜+Jšœ+˜+K˜——˜šœœœ˜1K˜KK˜%Kšœ˜—K˜K˜—šŸ œœ œœœœœœ œ ˜Jšœ œ ˜Jšœœ ˜J˜Jšœœ˜Jšœ œ˜&Jšœœœ˜*Jšœ8™8šœ˜JšœK˜K—Jšœœ˜3J˜Jšœœ˜7Jšœœ˜J˜—K˜K˜K˜—K˜šœ˜K˜—K˜—…—#G