DIRECTORY BondingPads, Cabbage, CD, CDBasics, CDProperties, CDSimpleRules, CMosBExtras, Connections, Core, CoreClasses, CoreCreate, CoreGeometry, CoreOps, CoreProperties, CoreRoute, IO, PadFrame, PWCore, Rope, Route, RTBasic, Sinix, TerminalIO; PadFrameImpl: CEDAR PROGRAM IMPORTS BondingPads, Cabbage, CD, CDBasics, CDProperties, CDSimpleRules, CMosBExtras, Connections, CoreGeometry, CoreOps, CoreProperties, CoreRoute, IO, PWCore, Rope, Route, TerminalIO EXPORTS PadFrame = BEGIN ROPE: TYPE = Core.ROPE; Wire: TYPE = Core.Wire; WireSeq: TYPE = Core.WireSeq; CellType: TYPE = Core.CellType; CellInstance: TYPE = CoreCreate.CellInstance; technologyKey: ATOM = $cmosB; wireWidthProp: ATOM = $w; lambda: INT _ CDSimpleRules.GetTechnology[technologyKey].lambda; AttributePadFrame: PWCore.AttributesProc = { ia: CoreRoute.InstanceArray _ CoreRoute.SortedInstanceArray[cellType]; -- reorders instances name: IO.ROPE _ CoreOps.GetCellTypeName[cellType]; TerminalIO.PutF["PadFrame Layout: %g.\n", IO.rope[name]]; CoreRoute.ShowInstanceArray[ia]; IF ia.size#3 OR ia[0].size#3 THEN ERROR; CoreProperties.PutCellTypeProp[cellType, $PadFrameInstanceArray, ia]}; LayoutPadFrame: PWCore.LayoutProc = { data: CoreClasses.RecordCellType _ NARROW [cellType.data]; ia: CoreRoute.InstanceArray _ NARROW[CoreProperties.GetCellTypeProp [cellType, $PadFrameInstanceArray]]; innerDX: INT _ GetCTPropInt[cellType, $innerDX, 0]; innerDY: INT _ GetCTPropInt[cellType, $innerDY, 0]; outerChanWidth: INT _ GetCTPropInt[cellType, $outerWidth, 90]; powerCellWidth: INT _ GetCTPropInt[cellType, $powerWidth, 200]; leftSize: CD.Position _ CD.InterestSize[PWCore.Layout[ia[1][0].type]]; rightSize: CD.Position _ CD.InterestSize[PWCore.Layout[ia[1][2].type]]; topSize: CD.Position _ CD.InterestSize[PWCore.Layout[ia[2][1].type]]; bottomSize: CD.Position _ CD.InterestSize[PWCore.Layout[ia[0][1].type]]; innerPos: CD.Position; bottomLeftInst: CellInstance _ ia[0][0]; bottomInst: CellInstance _ ia[0][1]; bottomRightInst: CellInstance _ ia[0][2]; leftInst: CellInstance _ ia[1][0]; innerInst: CellInstance _ ia[1][1]; rightInst: CellInstance _ ia[1][2]; topLeftInst: CellInstance _ ia[2][0]; topInst: CellInstance _ ia[2][1]; topRightInst: CellInstance _ ia[2][2]; params: Cabbage.PadRingParams; metalLayer: CD.Layer _ CDSimpleRules.GetLayer[technologyKey, "Metal"]; vLayer: CD.Layer; hLayer: CD.Layer; nets: Connections.Table _ Connections.CreateForRopes[]; [vLayer, hLayer] _ CoreRoute.GetCellTypePropLayer[cellType, $VerticalMetal, $met2]; params _ NEW [Cabbage.PadRingParamsRec _ [ horizLayer: IF hLayer=metalLayer THEN "Metal" ELSE "Metal2", vertLayer: IF vLayer=metalLayer THEN "Metal" ELSE "Metal2", technologyKey: technologyKey, -- $cmosB outerBTChanWidth: outerChanWidth, -- enough for xxx tracks outerLRChanWidth: outerChanWidth, -- enough for xxx tracks powerBTCellWidth: powerCellWidth, -- xxx lambda power busses powerLRCellWidth: powerCellWidth, -- xxx lambda power busses opt: noIncompletes, signalSinglePinNets: TRUE ]]; IF NOT(bottomSize.x=topSize.x AND leftSize.y=rightSize.y) THEN ERROR; ConnectionsFromList[data, nets, leftInst, right, vLayer]; ConnectionsFromList[data, nets, rightInst, left, vLayer]; ConnectionsFromList[data, nets, topInst, bottom, hLayer]; ConnectionsFromList[data, nets, bottomInst, top, hLayer]; ConnectionsFromList[data, nets, innerInst, right, hLayer]; ConnectionsFromList[data, nets, innerInst, left, hLayer]; ConnectionsFromList[data, nets, innerInst, bottom, vLayer]; ConnectionsFromList[data, nets, innerInst, top, vLayer]; innerPos _ CDBasics.AddPoints[ [innerDX*lambda, innerDY*lambda], Cabbage.Center[ inner: InstLayout[innerInst], bottomLeft: InstLayout[bottomLeftInst], bottom: InstLayout[bottomInst], bottomRight: InstLayout[bottomRightInst], right: InstLayout[rightInst], topRight: InstLayout[topRightInst], top: InstLayout[topInst], topLeft: InstLayout[topLeftInst], left: InstLayout[leftInst], parms: params] ]; innerPos.x _ (innerPos.x/lambda)*lambda; innerPos.y _ (innerPos.y/lambda)*lambda; PutInstTrans[innerInst, innerPos]; PutInstTrans[bottomLeftInst, [0, 0]]; PutInstTrans[bottomInst, [leftSize.x, 0]]; PutInstTrans[bottomRightInst, [leftSize.x+bottomSize.x, 0]]; PutInstTrans[rightInst, [leftSize.x+bottomSize.x, bottomSize.y]]; PutInstTrans[topLeftInst, [0, bottomSize.y+leftSize.y]]; PutInstTrans[topInst, [leftSize.x, bottomSize.y+leftSize.y]]; PutInstTrans[topRightInst, [leftSize.x+bottomSize.x, bottomSize.y+leftSize.y]]; PutInstTrans[leftInst, [0, bottomSize.y]]; obj _ Cabbage.PadLimitedRoute[ inner: InstLayout[innerInst], bottomLeft: InstLayout[bottomLeftInst], bottom: InstLayout[bottomInst], bottomRight: InstLayout[bottomRightInst], right: InstLayout[rightInst], topRight: InstLayout[topRightInst], top: InstLayout[topInst], topLeft: InstLayout[topLeftInst], left: InstLayout[leftInst], innerPos: innerPos, connections: nets, parms: params, name: CoreOps.GetCellTypeName[cellType] ] }; DecoratePadFrame: PWCore.DecorateProc = { WireToLabels: PROC [wire: Core.Wire] RETURNS [labels: LIST OF IO.ROPE _ NIL] = {RETURN[LIST[CoreRoute.LabelInternal[data.internal, wire]]]}; name: IO.ROPE _ CoreOps.GetCellTypeName[cellType]; data: CoreClasses.RecordCellType _ NARROW [cellType.data]; size: REF CD.Position _ NEW[CD.Position _ CD.InterestSize[obj]]; ia: CoreRoute.InstanceArray _ NARROW[CoreProperties.GetCellTypeProp [cellType, $PadFrameInstanceArray]]; markBondingPads: REF BOOL _ NARROW[CoreProperties.GetCellTypeProp [cellType, $MarkBondingPads]]; CoreRoute.DecorateRoutedArea[cellType, obj, WireToLabels, CoreRoute.CompareXorYStack]; IF markBondingPads#NIL AND ~markBondingPads^ THEN RETURN; TerminalIO.PutF["Marking Bonding Pads: %g.\n", IO.rope[name]]; CoreProperties.PutCellTypeProp[cellType, $BondingFrameSize, size]; FOR row: INT IN [0..3) DO FOR col: INT IN [0..3) DO eachPair: CoreOps.EachWirePairProc = { aList: LIST OF CoreGeometry.Instance _ NARROW[CoreProperties.GetWireProp[actualWire, $BondingPads]]; pList: LIST OF CoreGeometry.Instance _ NARROW[CoreProperties.GetWireProp[publicWire, $BondingPads]]; trans: CoreGeometry.Transformation _ CoreGeometry.GetTrans[PWCore.extractMode.decoration, ia[row][col]]; FOR pList _ pList, pList.rest WHILE pList#NIL DO inst: CoreGeometry.Instance _ pList.first; inst.trans _ CDBasics.ComposeTransform[pList.first.trans, trans]; aList _ CONS[inst, aList] ENDLOOP; CoreProperties.PutWireProp[actualWire, $BondingPads, aList]}; IF row=1 AND col=1 THEN LOOP; IF ia[row][col]=NIL THEN LOOP; name _ CoreOps.GetCellTypeName[ia[row][col].type]; TerminalIO.PutF[" Mark Pads: [%g, %g] %g.\n", IO.int[row], IO.int[col], IO.rope[name]]; BondingPads.MarkBondingPads[ia[row][col].type]; []_CoreOps.VisitBinding[ia[row][col].actual, ia[row][col].type.public, eachPair]; ENDLOOP; ENDLOOP}; ShowInstances: PROC[list: LIST OF CoreGeometry.Instance] = {FOR list _ list, list.rest WHILE list#NIL DO ShowInstance[list.first] ENDLOOP}; ShowInstance: PROC[inst: CoreGeometry.Instance] = { TerminalIO.PutRope["Layer: "]; ShowLayer[inst.obj.layer]; TerminalIO.PutRope[" IR: "]; ShowIR[CD.InterestRect[inst.obj]]; TerminalIO.PutRope[" Trans: "]; ShowTrans[inst.trans]; TerminalIO.PutRope["\n"]}; ShowLayer: PROC[layer: CD.Layer] = {TerminalIO.PutF["%g", IO.atom[CD.LayerKey[layer]]]}; ShowIR: PROC[ir: CD.Rect] = {TerminalIO.PutF["[%g, %g, %g, %g]", IO.int[ir.x1], IO.int[ir.y1], IO.int[ir.x2], IO.int[ir.y2]]}; ShowTrans: PROC[trans: CD.Transformation] = { TerminalIO.PutF["[[%g, %g] %g]", IO.int[trans.off.x], IO.int[trans.off.y], IO.rope[orientRope[trans.orient]]]}; orientRope: ARRAY CD.Orientation OF IO.ROPE _ [ original: "original", mirrorX: "mirrorX", rotate90: "rotate90", rotate90X: "rotate90X", rotate180: "rotate180", rotate180X: "rotate180X", rotate270: "rotate270", rotate270X: "rotate270X"]; InstLayout: PROC[inst: CellInstance] RETURNS[obj: CD.Object] = {RETURN[IF inst=NIL THEN NIL ELSE PWCore.Layout[inst.type]]}; PutInstTrans: PROC[inst: CellInstance, off: CD.Position] = { IF inst#NIL THEN { irBase: CD.Position _ CDBasics.BaseOfRect[CD.InterestRect[PWCore.Layout[inst.type]]]; tranOff: CD.Position _ CDBasics.SubPoints[off, irBase]; CoreGeometry.PutTrans[PWCore.extractMode.decoration, inst, [tranOff]]}}; ConnectionsFromList: PROC [data: CoreClasses.RecordCellType, nets: Connections.Table, inst: CellInstance, side: CoreGeometry.Side, layer: CD.Layer] ~ { FOR l: CoreRoute.WirePins _ CoreRoute.FilteredInstanceLayoutPins[inst, side], l.rest WHILE l#NIL DO actual: Wire _ l.first.wire; name: ROPE _ CoreRoute.LabelInternal[data.internal, actual]; widthVal: REF _ CoreProperties.GetWireProp[actual, wireWidthProp]; width: INT _ IF widthVal = NIL THEN 0 ELSE NARROW[widthVal, REF INT]^; net: Connections.Net _ Connections.Fetch[nets, name].net; IF layer#l.first.layer THEN LOOP; IF l.first.min > l.first.max THEN ERROR; IF net=NIL THEN net _ NEW [Connections.NetRec _ [name: name, width: width]]; [] _ Connections.Store[nets, name, net]; net.segments _ CONS [ NEW [ Connections.SegmentRec _ [ object: PWCore.Layout[inst.type], range: [l.first.min, l.first.max], side: side, layer: l.first.layer]], net.segments ]; ENDLOOP}; GetCTPropBool: PROC [ct: CellType, prop: ATOM, default: BOOL] RETURNS [val: BOOL] ~ { ref: REF _ CoreProperties.GetCellTypeProp[ct, prop]; val _ IF ref=NIL THEN default ELSE NARROW[ref, REF BOOL]^}; GetCTPropInt: PROC [ct: CellType, prop: ATOM, default: INT] RETURNS [val: INT] ~ { ref: REF _ CoreProperties.GetCellTypeProp[ct, prop]; val _ IF ref=NIL THEN default ELSE NARROW[ref, REF INT]^}; GetCTPropRope: PROC [ct: CellType, prop: ATOM, default: ROPE] RETURNS [val: ROPE] ~ { ref: REF _ CoreProperties.GetCellTypeProp[ct, prop]; val _ IF ref=NIL THEN default ELSE NARROW[ref, ROPE]}; AddConnection: PROC [nets: Connections.Table, internal: WireSeq, actual: Wire, object: CD.Object, min, max: INT, side: CoreGeometry.Side, layer: CD.Layer] = { name: ROPE _ CoreRoute.LabelInternal[internal, actual]; net: Connections.Net _ Connections.Fetch[nets, name].net; widthVal: REF ANY _ CoreProperties.GetWireProp[actual, wireWidthProp]; width: INT _ IF widthVal = NIL THEN 0 ELSE NARROW[widthVal, REF INT]^; IF net=NIL THEN { net _ NEW [Connections.NetRec _ [name: name, width: width]]; [] _ Connections.Store[nets, name, net]}; net.segments _ CONS [ NEW [Connections.SegmentRec _ [object: object, range: [min, max], side: side, layer: layer]], net.segments]}; NameExtractedPads: PUBLIC PROC[source, extracted: Core.CellType] = { CDProperties.PutLayerProp[CMosBExtras.bond, $RoutingLayer, $RoutingLayer]; [] _ PWCore.Layout[source]; -- make sure it's decorated FOR side: CoreGeometry.Side IN CoreGeometry.Side DO srcPins: CoreRoute.WirePins _ CoreRoute.LayPins[source, side]; extPins: CoreRoute.WirePins _ CoreRoute.LayPins[extracted, side]; DO FOR srcPins _ srcPins, srcPins.rest WHILE srcPins#NIL DO IF srcPins.first.layer=CMosBExtras.bond THEN EXIT ENDLOOP; FOR extPins _ extPins, extPins.rest WHILE extPins#NIL DO IF extPins.first.layer=CMosBExtras.bond THEN EXIT ENDLOOP; IF (srcPins=NIL)#(extPins=NIL) THEN ERROR; IF srcPins=NIL THEN EXIT ELSE { eNm: IO.ROPE _ CoreOps.GetShortWireName[extPins.first.wire]; sNm: IO.ROPE _ CoreRoute.LabelInternal[source.public, srcPins.first.wire]; IF eNm.Length[]=0 THEN eNm _ "-"; TerminalIO.PutF["Naming public: %20g _ %20g\n", IO.rope[sNm], IO.rope[eNm]]; []_CoreOps.SetShortWireName[extPins.first.wire, sNm]; extPins _ extPins.rest; srcPins _ srcPins.rest}; ENDLOOP; ENDLOOP; CoreOps.FlushNameCaches[extracted.public]; CoreRoute.FlushLayPinCache[source]; CoreRoute.FlushLayPinCache[extracted]; CDProperties.PutLayerProp[CMosBExtras.bond, $RoutingLayer, $RoutingLayer]}; LayoutWithOutRouteSignals: PUBLIC PWCore.LayoutProc = { TerminalIO.PutF["\nBEGIN: LayoutWithOutCabbageSignals: %g\n", IO.time[]]; obj _ PWCore.Layout[cellType ! Cabbage.Signal => {TerminalIO.PutF["*** Cabbage Signal: %g\n", IO.rope[explanation]]; RESUME}; Route.Signal => {TerminalIO.PutF["*** Route Signal: %g\n", IO.rope[explanation]]; RESUME} ]; TerminalIO.PutF["\nEND: LayoutWithOutCabbageSignals: %g\n", IO.time[]]}; [] _ PWCore.RegisterLayoutAtom [$PadFrame, LayoutPadFrame, DecoratePadFrame, AttributePadFrame]; END. τPadFrameImpl.mesa Copyright Σ 1987 by Xerox Corporation. All rights reserved. Bertrand Serlet September 10, 1987 11:17:02 pm PDT Louis Monier October 7, 1987 12:52:31 pm PDT Don Curry June 15, 1988 8:29:36 pm PDT Implements the Layout atom $PadFrame Corners may be used. Correctly deals with the case of multiple possible routing layers on the inner. Decorates using CoreRoute.DecorateRoutedArea. Derived from BicPadFrame Common types Attribute, Layout and Decorate Procs cornersOK: BOOL _ ConstructCorners[ia]; Layer changes from inner to pads; vLayer is vertical for inner and horizontal for pads. MarkBondingPads IF markBondingPads=NIL OR ~markBondingPads^ THEN RETURN; Utilities Name Extracted Pads LayoutWithOutRouteSignals Initialization Κ u˜– "Cedar" stylešœ™Jšœ<™Jšœ$ ˜>Jšœ˜Jšœœ˜—J˜Jš œœœœœ˜EJš "œ /™WJšœ;˜;Jšœ:˜:Jšœ:˜:Jšœ:˜:Jšœ;˜;Jšœ:˜:Jšœ<˜JšœB˜Bšœœœ˜šœœœ˜šœ&˜&šœœœ˜&Jšœ7˜=—šœœœ˜&Jšœ7˜=—šœ"˜"JšœE˜E—šœœœ˜0Jšœ*˜*Jšœžœ˜AJšœœ œ˜"—Jšœ=˜=—Jšœœœœ˜Jšœœœœ˜Jšœ2˜2šœ.˜.Jšœ œ œ ˜*—Jšœ/˜/JšœQ˜QJšœ˜—Jšœ˜ ———™ šž œœœœ˜:Jš œœœœœž œ œ˜P—šž œœ!˜3Jšœ9˜9Jšœ&œ˜AJšœ7˜7Jšœ˜—Jš ž œœœ!œœ˜Xšžœœœ-˜AJšœ œ œ œ˜=—šž œœœ˜/šœ ˜ Jšœœœ"˜N——š œ œœ œœœ˜/Jšœ˜Jšœ˜Jšœ˜Jšœ˜Jšœ˜Jšœ˜Jšœ˜Jšœ˜—šž œœœœ ˜>Jš œœœœœœœ˜=—šž œœœ˜<šœœœ˜Jšœœ œ)˜UJšœ œ,˜7JšœI˜I—J˜—šžœ˜Jšœpœ ˜}šœRœœ˜cJšœ˜Jšœœ2˜>Jšœ œ5˜BJšœœœ œœœœ œœ˜GJšœ9˜9Jšœœœ˜!Jšœœœ˜(Jšœœœœ3˜LJšœ(˜(šœœ˜šœ˜ Jšœ!˜!Jšœ#˜#Jšœ ˜ Jšœ˜—Jšœ˜—Jšœ˜ J˜——š ž œœœ œœœ˜UJšœœ,˜4Jšœœœœ œœœœ˜;J˜—š ž œœœ œœœ˜RJšœœ,˜4Jšœœœœ œœœœ˜:J˜—š ž œœœ œœœ˜UJšœœ,˜4Jš œœœœ œœœ˜6J˜—š ž œœDœœ"œ ˜žJšœœ-˜7Jšœ9˜9Jšœ œœ5˜FJšœœœ œœœœ œœ˜Fšœœœ˜Jšœœ3˜˜JJšœœ ˜!Jšœ0œ œ ˜LJšœ5˜5Jšœ˜Jšœ˜—Jšœ˜—Jšœ˜—Jšœ*˜*Jšœ#˜#Jšœ&˜&JšœK˜K——šž™šžœœ˜7Jšœ>œ ˜Išœ˜šœ˜Jšœ-œœ˜L—šœ˜Jšœ+œœ˜L——Jšœ<œ ˜H——™šœ˜JšœA˜AJ™——Jšœ˜J˜J™—…—0D?­