DIRECTORY CD, CDBasics, CDCells, CDDirectory, CDInstances, CDLayers, CDProperties, CDRects, CDSymbolicObjects, CDTexts, CMosB, CStitching, GList, HashTable, IO, PW, PWObjects, Rope, TerminalIO; PWSqueezeImpl: CEDAR PROGRAM IMPORTS CD, CDBasics, CDCells, CDDirectory, CDInstances, CDLayers, CDProperties, CDRects, CDSymbolicObjects, CDTexts, CMosB, CStitching, GList, HashTable, IO, PW, PWObjects, TerminalIO SHARES CDCells, CDRects = BEGIN ROPE: TYPE = Rope.ROPE; CountTransistors: PROC [obj: CD.Object] RETURNS [count: INT _ 0] = { value: REF INT _ NARROW [CDProperties.GetObjectProp[obj, $TransistorCount]]; IF value#NIL THEN RETURN [value^]; SELECT obj.class FROM CDCells.pCellClass => { EachSub: CDCells.InstEnumerator = {count _ count + CountTransistors[inst.ob]}; [] _ CDCells.EnumerateInstances[obj, EachSub]; }; CD.FetchObjectClass[$C2Trans, CMosB.cmosB], CD.FetchObjectClass[$C2WellTrans, CMosB.cmosB], CD.FetchObjectClass[$C2LTrans, CMosB.cmosB], CD.FetchObjectClass[$C2LWellTrans, CMosB.cmosB] => RETURN [1]; ENDCASE => RETURN [0]; }; FlattenInstance: PUBLIC PROC [instance: CD.Instance, eachInstance: CDCells.InstEnumerator] RETURNS [quit: BOOL _ FALSE] = { EachSubInstance: CDCells.InstEnumerator = { quit _ eachInstance[CDInstances.NewInst[inst.ob, CDBasics.ComposeTransform[itemInCell: inst.trans, cellInWorld: instance.trans]]]; }; SELECT TRUE FROM instance.ob.class=CDRects.bareRectClass => ERROR; instance.ob.class=CDCells.pCellClass => quit _ CDCells.EnumerateInstances[instance.ob, EachSubInstance]; ENDCASE => { flat: CD.Object _ CDDirectory.ExpandByDraw[instance.ob, TRUE, TRUE]; quit _ FlattenInstance[CDInstances.NewInst[CDDirectory.ExpandByDraw[instance.ob, TRUE, TRUE], instance.trans], eachInstance]; }; }; Touch: PROC [instance1, instance2: CD.Instance] RETURNS [BOOL _ FALSE] = { IF NOT CDBasics.Intersect[CDInstances.InstRectO[instance1], CDInstances.InstRectO[instance2]] THEN RETURN; SELECT TRUE FROM instance1.ob.class=CDRects.bareRectClass => RETURN [TouchRect[instance2, CDInstances.InstRectO[instance1], instance1.ob.layer]]; CDSymbolicObjects.IsSymbolicOb[instance1.ob] => RETURN [TouchRect[instance2, CDInstances.InstRectO[instance1], CDSymbolicObjects.GetLayer[instance1]]]; ENDCASE => { TouchInstance2: CDCells.InstEnumerator = {quit _ Touch[inst, instance2]}; RETURN [FlattenInstance[instance1, TouchInstance2]]; }; }; TouchRect: PUBLIC PROC [instance: CD.Instance, rect: CD.Rect, layer: CD.Layer] RETURNS [BOOL _ FALSE] = { IF ~CDBasics.Intersect[rect, CDInstances.InstRectO[instance]] THEN RETURN; IF instance.ob.class=CDRects.bareRectClass THEN RETURN [CDLayers.AbstractToPaint[instance.ob.layer]=CDLayers.AbstractToPaint[layer]]; RETURN [Touch[ instance, CDInstances.NewInst[ob: CDRects.CreateRect[CDBasics.SizeOfRect[rect], layer], trans: [CDBasics.BaseOfRect[rect]]] ]]; }; cacheRotate: ARRAY CD.Orientation OF HashTable.Table _ ALL[NIL]; CachedRotate: PROC [obj: CD.Object, orient: CD.Orientation] RETURNS [new: CD.Object] = { table: HashTable.Table; IF orient=original THEN RETURN [obj]; table _ cacheRotate[orient]; IF table=NIL THEN {table _ HashTable.Create[]; cacheRotate[orient] _ table}; new _ NARROW [HashTable.Fetch[table, obj].value]; IF new#NIL THEN RETURN; new _ PW.ChangeOrientation[obj, orient]; [] _ HashTable.Store[table, obj, new]; }; RootInst: PROC [fused: HashTable.Table, inst: CD.Instance] RETURNS [root: CD.Instance] = { IF inst=NIL THEN ERROR; root _ NARROW [HashTable.Fetch[fused, inst].value]; IF root=NIL THEN RETURN [inst]; IF root=inst THEN ERROR; root _ RootInst[fused, root]; [] _ HashTable.Replace[fused, inst, root]; }; ToRoutingCell: PROC [old: CD.Object] RETURNS [new: CD.Object] = { plane: CStitching.Tesselation _ CStitching.NewTesselation[]; fused: HashTable.Table _ HashTable.Create[]; -- Fisher Galler table pointing instances to their father rootInsts: HashTable.Table _ HashTable.Create[]; -- Table root instance -> other instances fused to it nodes: LIST OF PWObjects.Node _ NIL; nodesNb: INT _ 0; name: ROPE = CDDirectory.Name[old]; AddInst: CDCells.InstEnumerator = { Fuse: CStitching.TileProc = { oldInst: CD.Instance _ NARROW [tile.value]; oldInst _ RootInst[fused, oldInst]; IF oldInst=inst THEN RETURN; IF NOT Touch[oldInst, inst] THEN RETURN; [] _ HashTable.Store[fused, oldInst, inst]; tile.value _ inst; }; IF CDTexts.IsText[inst.ob] THEN {TerminalIO.PutF["Discarded text %g.\n", IO.rope[NARROW [inst.ob.specific, CDTexts.TextSpecific].text]]; RETURN}; CStitching.EnumerateArea[plane, CDInstances.InstRectO[inst], Fuse]; }; AddRootInst: CDCells.InstEnumerator = { IF CDTexts.IsText[inst.ob] THEN RETURN; IF RootInst[fused, inst]=inst THEN [] _ HashTable.Store[rootInsts, inst, NIL]; }; AddFusedInst: HashTable.EachPairAction = { fusedInst: CD.Instance _ NARROW [key]; root: CD.Instance _ RootInst[fused, NARROW [value]]; insts: LIST OF CD.Instance; IF fusedInst=root THEN ERROR; insts _ NARROW [HashTable.Fetch[rootInsts, root].value]; IF NOT GList.Member[fusedInst, insts] THEN insts _ CONS [fusedInst, insts]; [] _ HashTable.Store[rootInsts, root, insts]; }; MakeNode: HashTable.EachPairAction = { root: CD.Instance _ NARROW [key]; insts: LIST OF CD.Instance _ NARROW [value]; geometry: LIST OF PWObjects.PlacedObject _ NIL; FOR list: LIST OF CD.Instance _ CONS [root, insts], list.rest WHILE list#NIL DO instance: CD.Instance _ list.first; object: CD.Object = CachedRotate[instance.ob, instance.trans.orient]; geometry _ CONS [ [object: object, position: CDBasics.BaseOfRect[CDInstances.InstRectO[instance]]], geometry ]; ENDLOOP; nodes _ CONS [PWObjects.CreateNode[geometry], nodes]; nodesNb _ nodesNb + 1; }; old _ PW.Flatten[old]; [] _ CDCells.EnumerateInstances[old, AddInst]; CStitching.ResetTesselation[plane]; [] _ CDCells.EnumerateInstances[old, AddRootInst]; [] _ HashTable.Pairs[fused, AddFusedInst]; [] _ HashTable.Pairs[rootInsts, MakeNode]; new _ PWObjects.CreateRouting[CD.InterestRect[old], nodes]; TerminalIO.PutF["Object %g translated to routing: %g nodes.\n", IO.rope[name], IO.int[nodesNb]]; }; END. όPWSqueezeImpl.mesa Copyright Σ 1987 by Xerox Corporation. All rights reversed. Created by Bertrand Serlet, February 3, 1985 12:49:51 pm PST Last edited by Bertrand Serlet, March 15, 1987 6:30:27 pm PST Count Transistors Touching (a la CoreGeometry) and various utilities Transform into a RoutingCell We flatten! We create the corner stitch Let's release some space! We compute rootInsts by first putting all roots in the table We add in rootInsts all the fused ones We make node, now The final cell Κ¬˜šœ™Jšœ<™™>—J˜š ˜ Jšœl˜nJ˜Jšœ ˜ Jšœœ˜6J˜—šΟn œœœ˜Jšœœ‘œ˜ΈJšœ˜Jšœ˜Jšœœœ˜—head™codeš žœœœ œ œ ˜DLšœœœœ5˜LLšœœœœ ˜"šœ ˜šœ˜LšžœG˜NLšœ.˜.L˜—Lš œ*œ.œ+œ1œ˜ΗLšœœ˜—L˜——™2šžœœœ œ1œœœ˜{šžœ˜+Jšœ‚˜‚J˜—šœœ˜Jšœ-œ˜3Jšœk˜kšœ ˜Jšœœ0œœ˜DJšœQœœ"˜}J˜——L˜L˜—š žœœœ œœœ˜JJšœœXœœ˜jšœœ˜Jšœ/œN˜ƒJšœ5œa˜œšœ˜Jšžœ;˜IJšœ.˜4Jšœ˜——J˜J˜—šž œœœ œœœœœœ˜iJšœ<œœ˜Jšœ)œ˜0JšœO˜U—šœ˜Jšœ ˜ Jšœq˜qJšœ˜—J˜J˜—Jš œ œœ œœœ˜@š ž œœœœœœ ˜XJ˜Jšœœœœ˜%J˜Jšœœœ;˜LJšœœ%˜1Jšœœœœ˜Jšœœ ˜(J˜&J˜——™š žœœ œ œœ˜ZJšœœœœ˜Jšœœ&˜3Jšœœœœ˜Jšœ œœ˜Jšœ˜Jšœ*˜*J˜J˜—š ž œœœ œœ ˜ALšœ<˜