DIRECTORY BondingPads, CD, CDBasics, CDCells, CDInstances, CDProperties, CDRects, CMosB, Core, CoreClasses, CoreCreate, CoreGeometry, CoreOps, CoreProperties, IO, PW, PWCore, RefTab, Rope, Route, Sisyph, TerminalIO; HybridDiePad: CEDAR PROGRAM IMPORTS BondingPads, CD, CDBasics, CDCells, CDInstances, CDProperties, CDRects, CMosB, CoreGeometry, CoreOps, CoreProperties, IO, PW, PWCore, RefTab, Rope, Sisyph, TerminalIO = BEGIN Wires: TYPE = Core.Wires; Side: TYPE = CoreGeometry.Side; Trans: TYPE = CoreGeometry.Transformation; Instance: TYPE = CoreGeometry.Instance; Instances: TYPE = CoreGeometry.Instances; PadArray: TYPE = BondingPads.PadArray; SidePads: TYPE = BondingPads.SidePads; Pads: TYPE = BondingPads.Pads; Pad: TYPE = BondingPads.Pad; tech: CD.Technology _ CMosB.cmosB; grid: INT _ tech.lambda*2; layDeco: CoreGeometry.Decoration _ PWCore.extractMode.decoration; schDeco: CoreGeometry.Decoration _ Sisyph.mode.decoration; Layout: PWCore.LayoutProc = { name: IO.ROPE _ CoreOps.GetCellTypeName[cellType]; instances: CD.InstanceList _ NIL; padArray: PadArray; gndPlane: Instance; recordCellType: CoreClasses.RecordCellType _ NARROW[cellType.data]; subInst: CoreClasses.CellInstance _ recordCellType.instances[0]; size: CD.Position; ir: CD.Rect; used: RefTab.Ref _ RefTab.Create[]; widths: ARRAY Side OF INT; bindPads: CoreOps.EachWirePairProc = { pubInsts: Instances _ NARROW[CoreProperties.GetWireProp[actualWire, $BondingPads]]; actInsts: Instances _ NARROW[CoreProperties.GetWireProp[publicWire, $BondingPads]]; IF RefTab.Store[used, publicWire, publicWire] -- Store is TRUE if new THEN FOR actInsts _ actInsts, actInsts.rest WHILE actInsts#NIL DO pubInsts _ CONS[actInsts.first, pubInsts] ENDLOOP; CoreProperties.PutWireProp[actualWire, $BondingPads, pubInsts]}; BuildCDInstanceList: PROC[w: Core.Wire] = { geo: Instances _ NARROW[CoreProperties.GetWireProp[w, $PadGeometry]]; CoreProperties.PutWireProp[w, $PadGeometry, NIL]; FOR geo _ geo, geo.rest WHILE geo#NIL DO inst: CD.Instance _ CDInstances.NewInst[geo.first.obj, geo.first.trans]; CDProperties.PutProp[inst, $SignalName, CoreOps.GetFullWireName[cellType.public, w]]; instances _ CONS[inst, instances] ENDLOOP}; []_PWCore.Layout[subInst.type]; BondingPads.EnsureBondingPads[subInst.type]; size _ BondingPads.GetSize[subInst.type]; CoreProperties.PutCellTypeProp[cellType, $BondingFrameSize, NEW[CD.Position _ size]]; []_CoreOps.VisitBindingSeq[subInst.actual, subInst.type.public, bindPads]; padArray _ BondingPads.GetPads[cellType]; TerminalIO.PutF["HybridDiePad for: %g.\n", IO.rope[name]]; FOR side: Side IN Side DO twoTier: BOOL _ padArray[side].offSets.rest#NIL; pads: Pads _ padArray[side].pads; length: INT _ IF side=top OR side=bottom THEN size.x ELSE size.y; width: INT _ IF twoTier THEN loc6 ELSE loc3; trans: Trans; vddPlane: CD.Object _ CDRects.CreateRect[[loc1, length], layer1]; trans.off _ SELECT side FROM left => [-width, 0 ], right => [size.x+width, 0 ], top => [0, size.y+width ], ENDCASE => [0, -width ]; trans.orient _ SELECT side FROM left => original, right => mirrorX, top => rotate270, ENDCASE => rotate90X; widths[side] _ width; WHILE pads#NIL DO wire1: Core.Wire _ pads.first.wire; pwr: BOOL _ IsVdd[wire1] OR IsGnd[wire1]; centerY: INT _ pads.first.pos.y; IF twoTier THEN { fstOuter: BOOL _ padArray[side].offSets.first=pads.first.pos.x; scdInner: BOOL _ pads.rest#NIL AND (pads.first.pos.y = pads.rest.first.pos.y); wire2: Core.Wire _ IF scdInner THEN pads.rest.first.wire ELSE NIL; signal: IO.ROPE _ NIL; SELECT TRUE FROM scdInner AND ~pwr => ERROR; scdInner AND IsVdd[wire2] => ERROR; scdInner AND IsGnd[wire2] => ERROR; scdInner => {AddPads[2, centerY, wire1, wire2, trans]; pads_pads.rest}; ~pwr => {AddPads[2, centerY, NIL, wire1, trans]}; ENDCASE => {AddPads[2, centerY, wire1, NIL, trans]} } ELSE AddPads[1, centerY, wire1, NIL, trans]; pads _ pads.rest ENDLOOP; AddPositionedObject [CoreOps.FindWire[cellType.public, "Vdd"], vddPlane, 0, length/2, trans, TRUE]; ENDLOOP; ir _ [-widths[left], -widths[right], size.x + widths[right], size.y + widths[top]]; gndPlane _ [CDRects.CreateRect[CDBasics.SizeOfRect[ir], layer0], [CDBasics.BaseOfRect[ir]] ]; AddInstance[CoreOps.FindWire[cellType.public, "Gnd"], gndPlane, TRUE]; []_CoreOps.VisitRootAtomics[cellType.public, BuildCDInstanceList]; obj _ CDCells.CreateCell[il: instances, ir: ir]; CDCells.ToSequenceMode[obj]}; AddPositionedObject: PROC [wire: Core.Wire, obj: CD.Object, posX, centerY: INT, trans: Trans, isPin: BOOL _ FALSE] = { szY: INT _ CD.InterestSize[obj].y; trans _ CDBasics.ComposeTransform[ [[posX, centerY-szY/2 ]], trans]; AddInstance[wire, [obj, trans], isPin]}; AddInstance: PROC [wire: Core.Wire, inst: Instance, isPin: BOOL _ FALSE] = { geo: Instances _ NARROW[CoreProperties.GetWireProp[wire, $PadGeometry]]; IF isPin THEN CoreGeometry.AddPins[layDeco, wire, LIST[inst]]; geo _ CONS[inst, geo]; CoreProperties.PutWireProp[wire, $PadGeometry, geo]}; AddPads: PROC[tiers, centerY: INT, sig0, sig1: Core.Wire, trans: Trans] = { SELECT tiers FROM 1 => { SELECT TRUE FROM IsVdd[sig0] => { AddPositionedObject[sig0, cntc23, loc0, centerY, trans, TRUE]; AddPositionedObject[sig0, long1, loc0, centerY, trans, TRUE]; AddPositionedObject[sig0, cntc12, loc1, centerY, trans]}; IsGnd[sig0] => { AddPositionedObject[sig0, cntc23, loc0, centerY, trans, TRUE]; AddPositionedObject[sig0, cntc12, loc1, centerY, trans]; AddPositionedObject[sig0, cntc01, loc2, centerY, trans]}; ENDCASE => AddPositionedObject[sig0, cntc23, loc0, centerY, trans, TRUE]}; 2 => { IF sig1#NIL THEN AddPositionedObject[sig1, cntc23, loc0, centerY, trans, TRUE]; SELECT TRUE FROM IsVdd[sig0] => { AddPositionedObject[sig0, short1, loc1, centerY, trans]; AddPositionedObject[sig0, long1, loc2, centerY, trans]; AddPositionedObject[sig0, cntc23, loc2, centerY, trans]; AddPositionedObject[sig0, cntc12, loc3, centerY, trans]}; IsGnd[sig0] => { AddPositionedObject[sig0, cntc23, loc2, centerY, trans]; AddPositionedObject[sig0, cntc12, loc3, centerY, trans]; AddPositionedObject[sig0, cntc01, loc4, centerY, trans]}; ENDCASE}; ENDCASE => ERROR}; sml: INT _ 100 * tech.lambda; lrg: INT _ 250 * tech.lambda; loc0: INT _ 0; loc1: INT _ loc0 + lrg; loc2: INT _ loc1 + sml; loc3: INT _ loc2 + lrg; loc4: INT _ loc3 + sml; loc5: INT _ loc4 + sml; loc6: INT _ loc5 + sml; layer0: CD.Layer _ CMosB.ndif; layer1: CD.Layer _ CMosB.pol; short1: CD.Object _ CDRects.CreateRect[[sml, sml], CMosB.pol]; -- for gaps long1: CD.Object _ CDRects.CreateRect[[lrg, sml], CMosB.pol]; -- for beneath cntc23 cntc01: CD.Object _ MakeContact[CMosB.ndif, CMosB.bur, CMosB.pol, sml, sml, sml/4]; cntc12: CD.Object _ MakeContact[CMosB.pol, CMosB.cut, CMosB.met, sml, sml, sml/4]; cntc23: CD.Object _ MakeContact[CMosB.met, CMosB.cut2, CMosB.met2, lrg, sml, sml/20]; IsVdd: PROC[wire: Core.Wire] RETURNS[BOOL] = {RETURN[wire#NIL AND CoreOps.GetShortWireName[wire].Equal["Vdd"]]}; IsGnd: PROC[wire: Core.Wire] RETURNS[BOOL] = {RETURN[wire#NIL AND CoreOps.GetShortWireName[wire].Equal["Gnd"]]}; MakeContact: PROC[l0, l1, l2: CD.Layer, sizex, sizey, border: INT] RETURNS[obj: CD.Object] = { node: IO.ROPE _ "node"; insts: CD.InstanceList _ NIL; middle: CD.Object _ CDRects.CreateRect[[sizex-2*border, sizey-2*border], l1]; insts _ CONS[NEW[CD.InstanceRep _ [middle, [[border, border]]]], insts]; CDProperties.PutProp[insts.first, $SignalName, node]; insts _ CONS[NEW[CD.InstanceRep _ [CDRects.CreateRect[[sizex, sizey], l0]]], insts]; CDProperties.PutProp[insts.first, $SignalName, node]; insts _ CONS[NEW[CD.InstanceRep _ [CDRects.CreateRect[[sizex, sizey], l2]]], insts]; CDProperties.PutProp[insts.first, $SignalName, node]; obj _ PW.CreateCell[instances: insts, ir: [0, 0, sizex, sizey]]; CDProperties.PutProp[obj, PWCore.extractMode.extractProcProp, $ExtractAtomic]}; [] _ PWCore.RegisterLayoutAtom[$HybridDiePad, Layout]; END. ΒHybridDiePad.mesa Copyright Σ 1987 by Xerox Corporation. All rights reserved. Don Curry May 12, 1988 8:30:02 pm PDT Types and constants Layout and Decorate AddPositionedObject[sig0, long1, loc0, centerY, trans, TRUE]; The only direct references to CMosB layers See HybridDiePadRef.dale {RETURN[CoreOps.GetShortWireName[wire].Find["Vdd", 0, FALSE]#-1]}; {RETURN[CoreOps.GetShortWireName[wire].Find["Gnd", 0, FALSE]#-1]}; Register layout atoms ΚM˜šœ™Icode™Jšœœ ˜Jšœ5˜5J˜—šžœœœ*˜Kšœ˜˜šœœ˜šœ˜Jšœ8œ˜>Jšœ7œ˜=Jšœ9˜9—šœ˜Jšœ8œ˜>Jšœ8˜8Jšœ9˜9—šœ˜ Jšœ8œ˜?———˜Jšœœœ9œ˜Ošœœ˜šœ˜Jšœ8œ™>Jšœ9˜9Jšœ8˜8Jšœ9˜9Jšœ:˜:—šœ˜Jšœ9˜9Jšœ9˜9Jšœ:˜:—Jšœ˜ ——Jšœœ˜——J˜šΟb*™*Jš ™Jšœœ˜Jšœœ˜Jšœœ˜Jšœœ˜Jšœœ˜Jšœœ˜Jšœœ˜Jšœœ˜Jšœœ˜Jšœœ˜Jšœœ˜Jšœœ5Ÿ ˜JJšœœ5Ÿ˜TJšœœI˜SJšœœI˜SJšœœL˜VJ˜—šžœœœœ˜,Jšœœœœ/˜CJšœœ/œ™B—šžœœœœ˜,Jšœœœœ/˜CJšœœ/œ™BJ˜—šž œœ œœ˜BJšœœ ˜Jšœœœ ˜Jšœœœ˜JšœœE˜OJšœœœœ5˜HJšœ5˜5JšœœœœA˜TJšœ5˜5JšœœœœA˜TJšœ5˜5Jšœœ8˜@JšœO˜O——™Jšœ6˜6J˜Jšœ˜—J˜J˜Jšœ˜—…—Z)i