<> <> <> <> <> <> <> <> <> <> DIRECTORY Cabbage, CD, CDBasics, CDProperties, CDSimpleRules, CMosBExtras, Connections, Core, CoreClasses, CoreCreate, CoreGeometry, CoreOps, CoreProperties, CoreRoute, IcPack, IO, PadFrame, PWCore, Rope, Route, RTBasic, Sinix, TerminalIO; PadFrameImpl: CEDAR PROGRAM IMPORTS Cabbage, CD, CDBasics, CDProperties, CDSimpleRules, CMosBExtras, Connections, CoreGeometry, CoreOps, CoreProperties, CoreRoute, IcPack, 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] ]; 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 OR ~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]]; IcPack.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. <<>>