DIRECTORY Cabbage, CD, CDBasics, CDSimpleRules, Connections, Core, CoreClasses, CoreCreate, CoreOps, CoreProperties, CoreGeometry, PWCore, PWRoute, Rope, Route, RTBasic, Sisyph, SymTab, TerminalIO; NewPadFrameImpl: CEDAR PROGRAM IMPORTS Cabbage, CD, CDBasics, CDSimpleRules, Connections, CoreClasses, CoreOps, CoreProperties, CoreGeometry, PWCore, Route, Sisyph, SymTab, TerminalIO = BEGIN ROPE: TYPE = Core.ROPE; Wire: TYPE = Core.Wire; WireSeq: TYPE = Core.WireSeq; CellType: TYPE = Core.CellType; CellInstance: TYPE = CoreCreate.CellInstance; 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]; }; SideToSide: PROC [side: CoreGeometry.Side] RETURNS [RTBasic.Side] = { RETURN [SELECT side FROM top => top, bottom => bottom, left => left, right => right, ENDCASE => ERROR ]; }; AddConnection: PROC [nets: Connections.Table, internal: WireSeq, actual: Wire, object: CD.Object, min, max: INT, side: CoreGeometry.Side, layer: CD.Layer] = { name: ROPE _ CoreOps.GetFullWireNames[internal, actual].first; net: Connections.Net _ Connections.Fetch[nets, actual].net; IF net=NIL THEN { net _ NEW [Connections.NetRec _ [name: name]]; [] _ Connections.Store[nets, actual, net]; }; net.segments _ CONS [ NEW [Connections.SegmentRec _ [object: object, range: [min, max], side: SideToSide[side], layer: layer]], net.segments]; }; BBox: PROC [inst: CellInstance] RETURNS [CD.Rect] ~ { RETURN[CDBasics.MapRect[CD.InterestRect[CoreGeometry.GetObject[Sisyph.mode.decoration, inst.type]], CoreGeometry.GetTrans[Sisyph.mode.decoration, inst]]] }; AttributePadFrame: PWCore.AttributesProc = { data: CoreClasses.RecordCellType _ NARROW [cellType.data]; minX, minY: INT _ LAST[INT]; maxX, maxY: INT _ FIRST[INT]; left, right, top, bottom: CellInstance _ NIL; IF data.size#5 THEN ERROR; -- 4 sides and inner FOR i: NAT IN [0..data.size) DO IF BBox[data[i]].x1maxX THEN {right _ data[i]; maxX _ BBox[data[i]].x2}; IF BBox[data[i]].y1maxY THEN {top _ data[i]; maxY _ BBox[data[i]].y2}; ENDLOOP; CoreProperties.PutCellInstanceProp[left, $PadFrameSide, $Left]; CoreProperties.PutCellInstanceProp[bottom, $PadFrameSide, $Bottom]; CoreProperties.PutCellInstanceProp[right, $PadFrameSide, $Right]; CoreProperties.PutCellInstanceProp[top, $PadFrameSide, $Top]; }; technologyKey: ATOM = $cmosB; wireWidthProp: ATOM = $w; lambda: INT _ CDSimpleRules.GetTechnology[technologyKey].lambda; SpecifiedWidthProc: PWRoute.WireWidthProc = { widthTab: SymTab.Ref _ NARROW[context]; ref: REF _ SymTab.Fetch[widthTab, netName].val; wireWidth _ IF ref=NIL THEN CDSimpleRules.MinWidth[CDSimpleRules.GetLayer[technologyKey, "metal2"]] ELSE lambda*NARROW[ref, REF INT]^; }; LayoutPadFrame: PWCore.LayoutProc = { data: CoreClasses.RecordCellType _ NARROW [cellType.data]; left, right, top, bottom, inner: CellInstance _ NIL; prop: REF _ CoreProperties.GetCellTypeProp[cellType, $VerticalMetal]; vertLayer: ROPE _ IF prop=NIL OR prop=$Metal2 THEN "metal2" ELSE "metal"; -- default: metal2 horizLayer: ROPE _ IF prop=NIL OR prop=$Metal2 THEN "metal" ELSE "metal2"; outerChanWidth: INT _ GetCTPropInt[cellType, $outerWidth, 40]*lambda; --45 powerCellWidth: INT _ GetCTPropInt[cellType, $powerWidth, 270]*lambda; --220 hLayer: CD.Layer _ CDSimpleRules.GetLayer[technologyKey, horizLayer]; vLayer: CD.Layer _ CDSimpleRules.GetLayer[technologyKey, vertLayer]; params: Cabbage.PadRingParams _ NEW [Cabbage.PadRingParamsRec _ [ horizLayer: horizLayer, vertLayer: vertLayer, technologyKey: technologyKey, -- $cmosB wireWidthProc: SpecifiedWidthProc, outerChanWidth: outerChanWidth, -- enough for xxx tracks powerCellWidth : powerCellWidth, -- xxx lambda power busses opt: noIncompletes, signalIncomplete: TRUE, signalSinglePinNets: TRUE]]; nets: Connections.Table _ Connections.CreateForRefs[]; innerPos: CD.Position; leftSize, rightSize, topSize, bottomSize: CD.Position; IF data.size#5 THEN ERROR; -- 4 sides and inner FOR i: NAT IN [0..data.size) DO SELECT CoreProperties.GetCellInstanceProp[data[i], $PadFrameSide] FROM $Left => left _ data[i]; $Right => right _ data[i]; $Top => top _ data[i]; $Bottom => bottom _ data[i]; NIL => inner _ data[i]; ENDCASE => ERROR; ENDLOOP; IF left=NIL OR right=NIL OR top=NIL OR bottom=NIL OR inner=NIL THEN ERROR; leftSize _ CD.InterestSize[PWCore.Layout[left.type]]; rightSize _ CD.InterestSize[PWCore.Layout[right.type]]; topSize _ CD.InterestSize[PWCore.Layout[top.type]]; bottomSize _ CD.InterestSize[PWCore.Layout[bottom.type]]; IF NOT(bottomSize.x=topSize.x AND leftSize.y=rightSize.y) THEN ERROR; FOR i: NAT IN [0..data.size) DO EachWirePin: CoreGeometry.EachWirePinProc ~ { actual: Wire _ CoreClasses.CorrespondingActual[data[i], wire]; name: ROPE _ CoreOps.GetFullWireName[data.internal, actual]; SELECT data[i] FROM left => IF side#right OR layer#vLayer THEN RETURN; right => IF side#left OR layer#vLayer THEN RETURN; top => IF side#bottom OR layer#hLayer THEN RETURN; bottom => IF side#top OR layer#hLayer THEN RETURN; inner => IF NOT (layer=(IF side=top OR side=bottom THEN vLayer ELSE hLayer)) THEN RETURN; ENDCASE => ERROR; IF min>max THEN ERROR; AddConnection[nets, data.internal, actual, PWCore.Layout[data[i].type], min, max, side, layer]; }; [] _ PWCore.Layout[data[i].type]; [] _ CoreGeometry.EnumerateNonOverlappingSides[PWCore.extractMode.decoration, data[i].type, EachWirePin]; ENDLOOP; innerPos _ CDBasics.AddPoints[[0, 70*lambda], Cabbage.Center[ PWCore.Layout[inner.type], NIL, PWCore.Layout[bottom.type], NIL, PWCore.Layout[right.type], NIL, PWCore.Layout[top.type], NIL, PWCore.Layout[left.type], params]]; CoreGeometry.PutTrans[PWCore.extractMode.decoration, inner, [innerPos]]; CoreGeometry.PutTrans[PWCore.extractMode.decoration, bottom, [[leftSize.x, 0]]]; CoreGeometry.PutTrans[PWCore.extractMode.decoration, right, [[leftSize.x+bottomSize.x, bottomSize.y]]]; CoreGeometry.PutTrans[PWCore.extractMode.decoration, top, [[leftSize.x, bottomSize.y+leftSize.y]]]; CoreGeometry.PutTrans[PWCore.extractMode.decoration, left, [[0, bottomSize.y]]]; obj _ Cabbage.PadLimitedRoute[ inner: PWCore.Layout[inner.type], bottom: PWCore.Layout[bottom.type], right: PWCore.Layout[right.type], top: PWCore.Layout[top.type], left: PWCore.Layout[left.type], bottomLeft: NIL, bottomRight: NIL, topRight: NIL, topLeft: NIL, innerPos: innerPos, connections: nets, parms: params, name: CoreOps.GetCellTypeName[cellType] ! Cabbage.Signal => {TerminalIO.PutRopes["Cabbage message: ", explanation, "\n"]; RESUME}; Route.Signal => {TerminalIO.PutRopes["Route message: ", explanation, "\n"]; RESUME} ]; }; DecoratePadframe: PWCore.DecorateProc = { CoreGeometry.PutRecordLazyPins[PWCore.extractMode.decoration, cellType, CD.InterestRect[obj]]; }; [] _ PWCore.RegisterLayoutAtom[$NewPadFrame, LayoutPadFrame, DecoratePadframe, AttributePadFrame]; END. ΘNewPadFrameImpl.mesa Copyright Σ 1987 by Xerox Corporation. All rights reserved. Louis Monier June 14, 1986 6:32:41 pm PDT Bertrand Serlet March 14, 1987 1:50:05 am PST Last Edited by: Louis Monier April 28, 1987 1:38:11 pm PDT Common types Utilities Layout Proc -- default: metal1 -- warning: the new Cabbage changes layer from inner to pads, so pads on the left will use their pins in vertLayer!!! -- Call Cabbage Decorate Proc Initialization Κ|˜– "Cedar" stylešœ™Jšœ<™Kšœ;˜;šœœœ˜KšœœP˜YKšœ˜—šœœ˜Kšœg˜jKšœ˜—K˜——™ •StartOfExpansion6 -- [cellType: Core.CellType] RETURNS [obj: CD.Object]šŸœœœœ ˜5Kšœ“˜™K˜—šžœ˜,Jšœ#œ˜:Jšœ  œœ˜Jšœ  œœ˜Jšœ)œ˜-Jšœ œœΟc˜0šœœœ˜Kšœœ+˜HKšœœ,˜IKšœœ-˜JKšœœ*˜GKšœ˜—Kšœ?˜?KšœC˜CKšœA˜AKšœ=˜=Kšœ˜—Jšœœ ˜Jšœœ˜Jšœœ5˜@J˜šŸœ˜-Kšœœ ˜'Kšœœ'˜/Kšœ œœœIœœœœ˜†Kšœ˜—šžœ˜%Jšœ#œ˜:Jšœ0œ˜4Kšœœ<˜Eš œ œœœœœ œ ˜IKš ˜—š œ œœœœœ œ ˜JKšœ™—Kšœœ7˜JKšœœ9˜LKšœœ;˜EKšœœ:˜Dšœ œ˜AKšœ˜Kšœ˜Kšœ  ˜'Jšœ"˜"Kšœ  ˜8Kšœ! ˜;Kšœ˜Kšœœ˜Kšœœ˜—Jšœ6˜6Jšœ œ ˜Jšœ*œ ˜6J˜Jšœ œœ ˜0šœœœ˜šœ<˜FKšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœœ˜—Kšœ˜—Kšœœœœœœœœœœœœ˜JK˜Kšœ5˜5Kšœ7˜7Kšœ3˜3Kšœ9˜9Kš œœœœœ˜EK˜šœœœ˜šŸ œ"˜-Kšœ>˜>Kšœœ2˜