DIRECTORY BondingPads, BrineIO, CD, CDBasics, CDRects, CMosB, Core, CoreGeometry, CoreGeometryBackdoor, CoreIO, CoreOps, CoreProperties, IO, PWCore, RefTab; BondingPadsImpl: CEDAR PROGRAM IMPORTS BrineIO, CD, CDBasics, CDRects, CMosB, CoreGeometry, CoreGeometryBackdoor, CoreIO, CoreOps, CoreProperties, PWCore, RefTab EXPORTS BondingPads ~ BEGIN PadArray: TYPE = BondingPads.PadArray; Side: TYPE = CoreGeometry.Side; SidePads: TYPE = BondingPads.SidePads; Pads: TYPE = BondingPads.Pads; Pad: TYPE = BondingPads.Pad; tech: CD.Technology _ CMosB.cmosB; MarkBondingPads: PUBLIC PROC[cell: Core.CellType] ~ { overGlass: CD.Layer _ CD.FetchLayer[tech, $ovg]; cut2: CD.Layer _ CD.FetchLayer[tech, $cut2]; layDeco: CoreGeometry.Decoration _ PWCore.extractMode.decoration; ect: Core.CellType; extractedToSource: RefTab.Ref; layout: CD.Object; bondingFrameSize: REF CD.Position; fourteen: INT _ tech.lambda*14; IsBig: PROC[ob: CD.Object] RETURNS[isBig: BOOL] = { size: CD.Position _ CD.InterestSize[ob]; RETURN[size.x > fourteen AND size.y > fourteen]}; EachAtomic: PROC[wire: Core.Wire] ~ { sourceWire: Core.Wire _ NARROW[RefTab.Fetch[extractedToSource, wire].val]; instances: LIST OF CoreGeometry.Instance; EachInst: CoreGeometry.EachInstanceProc ~ { -- instance RETURNS quit IF ~CDRects.IsBareRect[instance.obj] THEN [] _ CoreGeometry.FlattenInstance[instance, EachInst] ELSE { IF instance.obj.layer=overGlass OR (instance.obj.layer=cut2 AND IsBig[instance.obj]) THEN instances _ CONS[instance, instances]}}; name: IO.ROPE; IF sourceWire=NIL THEN RETURN; instances _ NARROW[CoreProperties.GetWireProp[sourceWire, $BondingPads]]; name _ CoreOps.GetFullWireName[cell.public, sourceWire]; [] _ CoreGeometry.EnumerateAllGeometry[layDeco, ect, wire, EachInst]; instances _ MergeSort[instances]; CoreProperties.PutWireProp[sourceWire, $BondingPads, instances]}; IF CoreProperties.GetCellTypeProp[cell, $BondingFrameSize]#NIL THEN RETURN; [] _ PWCore.Layout[cell]; IF CoreProperties.GetCellTypeProp[cell, $BondingFrameSize]#NIL THEN RETURN; [layout, ect, extractedToSource, ] _ PWCore.LayoutInfo[cell]; CoreOps.VisitRootAtomics[ect.public, EachAtomic]; bondingFrameSize _ NEW[CD.Position _ CD.InterestSize[layout]]; CoreProperties.PutCellTypeProp[cell, $BondingFrameSize, bondingFrameSize]}; EnsureBondingPads: PUBLIC PROC[cell: Core.CellType] = { IF CoreProperties.GetCellTypeProp[cell, $BondingFrameSize]=NIL THEN IF cell.class.recast=NIL THEN MarkBondingPads[cell] ELSE { recast: Core.CellType _ CoreOps.Recast[cell]; size: REF CD.Position; EachPair: PROC[actualWire, publicWire: Core.Wire] RETURNS [subWires: BOOL _ TRUE, quit: BOOL _ FALSE]= { origWire: Core.Wire _ actualWire; recastWire: Core.Wire _ publicWire; origInsts: LIST OF CoreGeometry.Instance _ NARROW[CoreProperties.GetWireProp[origWire, $BondingPads]]; recastInsts: LIST OF CoreGeometry.Instance _ NARROW[CoreProperties.GetWireProp[recastWire, $BondingPads]]; IF origInsts#NIL THEN RETURN -- recasted and original publics identical => this wire done ELSE FOR recastInsts _ recastInsts, recastInsts.rest WHILE recastInsts#NIL DO origInsts _ CONS[recastInsts.first, origInsts] ENDLOOP; CoreProperties.PutWireProp[origWire, $BondingPads, origInsts]}; EnsureBondingPads[recast]; []_CoreOps.VisitBindingSeq[cell.public, recast.public, EachPair]; size _ NARROW[CoreProperties.GetCellTypeProp[recast, $BondingFrameSize]]; CoreProperties.PutCellTypeProp[cell, $BondingFrameSize, NEW[CD.Position _ size^]] } }; GetSize: PUBLIC PROC[cell: Core.CellType] RETURNS[size: CD.Position] = { refSize: REF CD.Position _ NARROW[CoreProperties.GetCellTypeProp[cell, $BondingFrameSize]]; RETURN[refSize^]}; GetPads: PUBLIC PROC[cell: Core.CellType] RETURNS[padArray: PadArray] = { size: CD.Position _ GetSize[cell]; cRect: CD.Rect _ [0, 0, size.x, size.y]; eachPublic: PROC[wire: Core.Wire] = { instances: LIST OF CoreGeometry.Instance _ NARROW[CoreProperties.GetWireProp[wire, $BondingPads]]; FOR instances _ instances, instances.rest WHILE instances#NIL DO ir: CD.Rect _ CoreGeometry.BBox[instances.first]; side: Side _ NearestSide[ir, cRect]; offSet: CD.Position _ OffSet[ir, cRect, side]; pad: Pad _ [wire, offSet]; padArray[side].pads _ CONS[pad, padArray[side].pads] ENDLOOP }; []_CoreOps.VisitRootAtomics[cell.public, eachPublic]; FOR side: Side IN Side DO offSets: LIST OF INT _ NIL; FOR pads: Pads _ padArray[side].pads, pads.rest WHILE pads#NIL DO offSets _ CONS[pads.first.pos.x, offSets]; FOR oSets: LIST OF INT _ offSets, oSets.rest WHILE oSets#NIL AND oSets.rest#NIL DO TwoInts: TYPE = RECORD[i0, i1: INT]; IF oSets.first < oSets.rest.first THEN EXIT; IF oSets.first = oSets.rest.first THEN {oSets.rest _ oSets.rest.rest; EXIT}; [oSets.first, oSets.rest.first] _ TwoInts[oSets.rest.first, oSets.first] ENDLOOP; ENDLOOP; padArray[side].offSets _ offSets; IF offSets=NIL THEN LOOP; IF offSets.rest#NIL THEN{ IF offSets.rest.rest#NIL THEN ERROR; IF offSets.rest.first-offSets.first<100*tech.lambda THEN ERROR}; DO done: BOOL _ TRUE; FOR pads: Pads _ padArray[side].pads, pads.rest WHILE pads#NIL AND pads.rest#NIL DO TwoPads: TYPE = RECORD[p0, p1: Pad]; IF pads.first.pos.y < pads.rest.first.pos.y THEN { --IF (pads.rest.first.pos.y-pads.first.pos.y) < 100*tech.lambda THEN ERROR-- LOOP}; IF pads.first.pos.y > pads.rest.first.pos.y OR pads.first.pos.x > pads.rest.first.pos.x THEN {[pads.first, pads.rest.first] _ TwoPads[pads.rest.first, pads.first]; done _ FALSE} ENDLOOP; IF done THEN EXIT ENDLOOP; ENDLOOP}; CompareRectBottomLeft: PROC [rect1: CD.Rect, rect2: CD.Rect] RETURNS [BOOL] = { overlappingInY: BOOL _ rect1.y1= xr.x1) AND (xr.y2 >= xr.y1); IF touch THEN { union: CD.Rect _ CDBasics.Surround[ir1, ir2]; size: CD.Position _ CDBasics.SizeOfRect[union]; pos: CD.Position _ CDBasics.BaseOfRect[union]; newObj: CD.Object _ CDRects.CreateRect[size, list.first.obj.layer]; list.rest _ list.rest.rest; list.first _ [newObj, [pos]]; done _ FALSE} ELSE { IF ~CompareRectBottomLeft[ir1, ir2] THEN {[list.first, list.rest.first]_TwoInstances[list.rest.first, list.first]; done_FALSE}}; ENDLOOP; IF done THEN EXIT ENDLOOP; RETURN[instances]}; NearestSide: PROC[sml, lrg: CD.Rect] RETURNS[side: Side _ left] ~ { dist: INT _ ABS[lrg.x1 - sml.x1]; test: INT _ ABS[lrg.x2 - sml.x2]; IF test < dist THEN {dist _ test; side _ right}; test _ ABS[lrg.y1 - sml.y1]; IF test < dist THEN {dist _ test; side _ bottom}; test _ ABS[lrg.y2 - sml.y2]; IF test < dist THEN {dist _ test; side _ top}}; OffSet: PROC[sml, lrg: CD.Rect, side: Side] RETURNS[offSet: CD.Position] ~ { offSet _ SELECT side FROM left => [(sml.x1+sml.x2)/2 - lrg.x1, (sml.y1+sml.y2)/2], right => [lrg.x2 - (sml.x1+sml.x2)/2, (sml.y1+sml.y2)/2], bottom => [(sml.y1+sml.y2)/2 - lrg.y1, (sml.x1+sml.x2)/2], top => [lrg.y2 - (sml.y1+sml.y2)/2, (sml.x1+sml.x2)/2], ENDCASE => ERROR }; PropWriteInstances: CoreIO.PropWriteProc = {CoreGeometryBackdoor.WriteInstances[stream, NARROW[value]]}; PropReadInstances: CoreIO.PropReadProc = {value _ CoreGeometryBackdoor.ReadInstances[stream]}; PropWriteSize: CoreIO.PropWriteProc = { pos: REF CD.Position _ NARROW[value]; BrineIO.WriteInt[stream, pos.x]; BrineIO.WriteInt[stream, pos.y]}; PropReadSize: CoreIO.PropReadProc = { pos: REF CD.Position _ NEW[CD.Position _ [0,0]]; pos.x _ BrineIO.ReadInt[stream]; pos.y _ BrineIO.ReadInt[stream]; value _ pos}; []_CoreIO.RegisterProperty[$BondingPads, PropWriteInstances, PropReadInstances]; []_CoreIO.RegisterProperty[$BondingFrameSize, PropWriteSize, PropReadSize]; END. <BondingPadsImpl.mesa Copyright ำ 1988 by Xerox Corporation. All rights reserved. Don Curry June 7, 1988 9:46:55 am PDT Types Mark Bonding Pads Ref [Cherry]7.0>XrVTI4x>CDMEBESCMOSB16Nov87.load: oxidePad _ ((met2-10) AND (ovg OR cut2))-4 IF met2 always covers cut2 THEN (min dimension of cut2 > 14) => ovg IF instances=NIL THEN TerminalIO.PutF["No pad for: %g\n",IO.rope[name]]; Collect pads Find (and check) offsets Sort by y then x The offSet when building a left side normalized set of pads. X is the distance in and y is the distance up. Initialization ส ฎ˜šœ™Jšœ<™JšœK˜KJ˜—šžœœœ˜7šœ9œ˜Cšœœœœ˜:Jšœ/˜/Jšœœœ ˜šžœœ#˜1Jš œ œœœœ˜6Jšœ"˜"Jšœ#˜#šœ œœ˜,Jšœ5˜;—šœœœ˜-Jšœ7˜=—šœ ˜JšœœŸ<˜Hš œœ-œ œ˜MJšœ œœ˜7——Jšœ?˜?—Jšœ˜JšœA˜AJšœœ<˜IJšœ8œœ˜V——J˜—š žœœœœœ˜Hšœ œœ ˜Jšœœ:˜B—Jšœ ˜J˜—šžœœœœ˜IJšœœ˜"Jšœœ ˜)šœ œ˜%šœ œœ˜*Jšœ1˜7—šœ'œ œ˜@Jšœœ,˜3Jšœ&˜&Jšœœ$˜.Jšœ˜Jšœœœ˜?——Jšฯb ™ Jšœ5˜5šœ œ˜Jš œ œœœœ˜Jš ™šœ-œœ˜AJšœ œ˜*šœœœœœœœ œ˜RJšœ œœ œ˜$Jšœ œœ˜,Jšœ œ œ˜LJšœIœ˜Q—Jšœ˜—Jšœ!˜!Jšœ œœœ˜šœœœ˜Jšœœœœ˜$Jšœ2œœ˜@—Jš ™š˜Jšœœœ˜š œ-œœœ œ˜SJšœ œœ˜$šœ*œ˜2Jšœ<œœœ˜S—šœ*œ*˜\JšœNœ˜T—Jšœ˜—Jšœœœœ˜—Jšœ˜ —J˜—š žœœ œœœœ˜OJšœœœ˜?šœœ˜Jšœ˜Jšœ˜—J˜—šž œœ œœ˜9Jšœœœ˜*Jšœœœ ˜;š˜Jšœœœ˜Jšœœœ#˜0š œœœœ œ˜>Jšœœ&˜.Jšœœ+˜3Jšœœ(˜0Jšœœœ˜6šœ˜šœ˜Jšœœ%˜.Jšœœ'˜1Jšœœ'˜0Jšœ œ:˜EJšœ˜Jšœ˜Jšœœ˜—šœ˜šœ!˜#JšœPœ˜\———Jšœ˜—Jšœœœœ˜—Jšœ ˜J˜—šž œœ œœ˜CJšœœœ˜!Jš œœœœ œ˜RJšœœœ œ˜OJšœœœ œ˜MJ˜—š žœœ œœ œ˜LJšœl™lšœ œ˜Jšœ:˜:Jšœ;˜;Jšœ:˜:Jšœ8˜8Jšœœ˜———šœ™šžœ˜*Jšœ-œ ˜=—šžœ˜(Jšœ5˜5—šž œ˜'Jšœœœ œ˜%Jšœ ˜ Jšœ!˜!—šž œ˜%Jš œœœ œœ˜0Jšœ ˜ Jšœ ˜ Jšœ ˜ —JšœP˜PJšœK˜K—J˜Jšœ˜—…—ฐ+š