<> <> <> <> <> <> DIRECTORY CD, CDBasics, CStitching, CDCells, CDCommandOps, CDOps, CDRects, CDSequencer, CDInstances, CDProperties, CDDirectory, Recognizer, TerminalIO, CleanObjects; CleanObjectsImpl: CEDAR PROGRAM IMPORTS CD, CDBasics, CDCommandOps, CDOps, CStitching, CDCells, CDInstances, CDProperties, CDDirectory, CDRects, CDSequencer, Recognizer, TerminalIO EXPORTS CleanObjects= BEGIN RegList: TYPE=LIST OF REF CStitching.Region; Plane: TYPE=CStitching.Tesselation; Handle: TYPE=REF HandleRep; HandleRep: TYPE=RECORD [ design: CD.Design, cellOb: CD.Object, abstract: CD.Layer _ CD.undefLayer, actual: CD.Layer _ CD.undefLayer, surround: CD.Layer _ CD.undefLayer, surroundExt: CD.Number _ 0, actualPlane: Plane _ NIL, surroundPlane: Plane _ NIL, instance: CD.Instance _ NIL, pr: CD.DrawRef _ NIL --used to fill stuff into planes... ]; AbstractLayerRec: TYPE=RECORD [ technology: CD.Technology, abstract: CD.Layer, actual: CD.Layer, surround: CD.Layer, --The surrounding layer of an abstract layer surroundExt: CD.Number --The extension of the surrounding layer ]; CleanListRec: TYPE = RECORD [ technology: CD.Technology, clean: LIST OF CD.Layer ]; DevicePrivateRec: TYPE = RECORD [ handle: Handle, object: CD.Object ]; abstractLayerList: LIST OF REF AbstractLayerRec _ NIL; --contains registered abstract Layers cleanList: LIST OF REF CleanListRec _ NIL; DoCleanObjects: PUBLIC PROC [cellOb: CD.Object, design: CD.Design, recognizeObjects: BOOL _ TRUE] = BEGIN IF CDCells.IsCell[cellOb] THEN { IF recognizeObjects THEN Recognizer.RecognizeObjects[design, cellOb]; CleanCell[design, cellOb]; [] _ CDCells.ResizeCell[design, cellOb]; CDDirectory.PropagateChange[cellOb, design]; }; END; CleanObjectsAllLevels: PROC [design: CD.Design, recognizeObjects: BOOL] = BEGIN DoIt: CDDirectory.EachEntryAction={ DoCleanObjects[cellOb: ob, design: design, recognizeObjects: recognizeObjects] }; [] _ CDDirectory.Enumerate[design, DoIt]; DoCleanObjects[design.actual.first.dummyCell.ob, design, recognizeObjects]; END; RecognizeAllCommand: PROC [comm: CDSequencer.Command] = BEGIN TerminalIO.PutRope["recognize on all levels\n"]; CleanObjectsAllLevels[design: comm.design, recognizeObjects: TRUE]; TerminalIO.PutRope[" done\n"]; END; RecognizeTopCommand: PROC [comm: CDSequencer.Command] = BEGIN TerminalIO.PutRope["recognize on top level\n"]; DoCleanObjects[comm.design.actual.first.dummyCell.ob, comm.design, TRUE]; TerminalIO.PutRope[" done\n"]; END; CleanCell: PROC [design: CD.Design, cellOb: CD.Object] = BEGIN SetUpLayer: PROC [h: Handle, lay: CD.Layer] = BEGIN h.abstract _ lay; h.actual _ lay; h.surround _ CD.undefLayer; FOR abstractList: LIST OF REF AbstractLayerRec _ abstractLayerList, abstractList.rest WHILE abstractList#NIL DO IF abstractList.first.abstract=lay AND abstractList.first.technology=h.design.technology THEN { h.actual _ abstractList.first.actual; h.surround _ abstractList.first.surround; h.surroundExt _ abstractList.first.surroundExt; EXIT; } ENDLOOP; END; dummyInst: CD.Instance ~ NEW[CD.InstanceRep _ [ob: cellOb]]; h: Handle _ NEW[HandleRep _ [design, cellOb]]; actualCleanList: LIST OF CD.Layer _ NIL; FOR cl: LIST OF REF CleanListRec _ cleanList, cl.rest WHILE cl # NIL DO IF cl.first.technology = design.technology THEN {actualCleanList _ cl.first.clean; EXIT}; REPEAT FINISHED => actualCleanList _ design.technology.usedLayers; ENDLOOP; h.pr _ CD.CreateDrawRef[[ drawRect: DrawRectOfSimpleObject, drawChild: DrawChildOfSimpleObject, devicePrivate: NEW[DevicePrivateRec _ [h, NIL]], design: design ]]; FOR layerList: LIST OF CD.Layer _ actualCleanList, layerList.rest WHILE layerList#NIL DO SetUpLayer[h, layerList.first]; h.actualPlane _ CStitching.NewTesselation[]; h.surroundPlane _ CStitching.NewTesselation[]; <<--fill in the simple objects>> cellOb.class.drawMe[inst: dummyInst, trans: [], pr: h.pr]; CheckRectsAgainstPlane[h]; CStitching.ResetTesselation[h.actualPlane]; CStitching.ResetTesselation[h.surroundPlane]; ENDLOOP; <<--break circularity>> h.pr.devicePrivate _ NIL; h.pr _ NIL; END; DrawChildOfSimpleObject: CD.DrawProc = BEGIN IF ~inst.ob.class.wireTyped AND ~inst.ob.class.inDirectory THEN { private: REF DevicePrivateRec _ NARROW[pr.devicePrivate]; remember: CD.Object _ private.object; private.object _ inst.ob; inst.ob.class.drawMe[inst, trans, pr]; private.object _ remember; } END; DrawRectOfSimpleObject: PROC [r: CD.Rect, l: CD.Layer, pr: CD.DrawRef] = BEGIN IF CDBasics.NonEmpty[r] THEN { private: REF DevicePrivateRec _ NARROW[pr.devicePrivate]; handle: Handle _ private.handle; cont: CD.Object _ private.object; filter: REF CleanObjects.Filter _ IF cont # NIL THEN NARROW[CDProperties.GetProp[cont.class, $cleanSpecial]] ELSE NIL; IF filter#NIL AND filter[l] THEN RETURN; IF handle.actual = l THEN CStitching.ChangeRect[plane: handle.actualPlane, rect: r, new: $cover] ELSE IF handle.surround = l THEN CStitching.ChangeRect[plane: handle.surroundPlane, rect: r, new: $cover]; } END; CheckRectsAgainstPlane: PROC [h: Handle] = BEGIN mustRemove: CD.InstanceList _ NIL; EachInst: CDCells.InstEnumerator = { IF inst.ob.class.wireTyped AND inst.ob.layer=h.abstract THEN { IF WireNeededCleaning[inst, h] THEN mustRemove _ CONS[inst, mustRemove] ELSE inst.ob.class.drawMe[inst, inst.trans, h.pr] } }; [] _ CDCells.EnumerateInstances[h.cellOb, EachInst]; FOR il: CD.InstanceList _ mustRemove, il.rest WHILE il#NIL DO [] _ CDCells.RemoveInstance[design: h.design, cell: h.cellOb, inst: il.first, mode: dontResize] ENDLOOP; END; WireNeededCleaning: PROC [instance: CD.Instance, h: Handle] RETURNS [removeInst: BOOL _ FALSE] = BEGIN rect: CD.Rect _ CDInstances.InstRectI[instance]; keepList: RegList _ CStitching.ListArea[h.actualPlane, rect, $cover]; IF h.surround#CD.undefLayer THEN { --current Layer is an abstract Layer throwAwayList: RegList _ CStitching.ListArea[h.actualPlane, rect]; keepList _ AddUncoveredSurround[keepList, throwAwayList, h.surroundPlane, h.surroundExt]; }; <> IF keepList=NIL THEN RETURN[TRUE]; IF keepList.first.value=NIL AND keepList.first.rect=rect AND keepList.rest=NIL THEN RETURN; --keep whole wire WHILE keepList#NIL DO location: CD.Position _ CDBasics.BaseOfRect [keepList.first.rect]; object: CD.Object _ CDRects.CreateRect[CDBasics.OrientedSize[CDBasics.SizeOfRect[keepList.first.rect], instance.trans.orient], h.abstract]; newInst: CD.Instance _ CDInstances.NewInst[object, CDOps.FitObjectI[object, location, instance.trans.orient]]; [] _ CDCells.IncludeInstance[ design: h.design, cell: h.cellOb, inst: newInst, mode: dontResize ]; CDProperties.CopyProps[instance.properties, newInst]; removeInst _ TRUE; keepList _ keepList.rest; ENDLOOP; END; UpdateKeepList: PROC [keepList: RegList, instance: CD.Instance, rect: CD.Rect] RETURNS [newKeepList: RegList] = <<--If a piece on the keeplist is actually a cut along the width then the piece is grown to the full width of the original wire.>> BEGIN xWidth: BOOL; width: CD.Number; length: CD.Number; changed: BOOL _ TRUE; wirePlane: Plane _ CStitching.NewTesselation[]; WHILE keepList#NIL DO CStitching.ChangeRect[plane: wirePlane, rect: keepList.first.rect, new: $cover]; keepList _ keepList.rest; ENDLOOP; IF CDBasics.IncludesOddRot90[instance.trans.orient] THEN { xWidth _ FALSE; width _ rect.y2-rect.y1; length _ rect.x2-rect.x1; } ELSE { xWidth _ TRUE; width _ rect.x2-rect.x1; length _ rect.y2-rect.y1; }; IF length > width THEN -- normal shaped object WHILE changed DO changed _ FALSE; newKeepList _ CStitching.ListArea[plane: wirePlane, rect: rect]; WHILE newKeepList#NIL DO IF xWidth AND (newKeepList.first.rect.x2-newKeepList.first.rect.x1)#width THEN { changed _ TRUE; CStitching.ChangeRect[plane: wirePlane, rect: [rect.x1, newKeepList.first.rect.y1, rect.x2, newKeepList.first.rect.y2], new: $cover]; }; IF ~xWidth AND (newKeepList.first.rect.y2-newKeepList.first.rect.y1)#width THEN { changed _ TRUE; CStitching.ChangeRect[plane: wirePlane, rect: [newKeepList.first.rect.x1, rect.y1, newKeepList.first.rect.x2, rect.y2], new: $cover]; }; newKeepList _ newKeepList.rest; ENDLOOP; ENDLOOP; newKeepList _ CStitching.ListArea[plane: wirePlane, rect: rect]; CStitching.ResetTesselation[wirePlane]; END; AddUncoveredSurround: PROC [keepList, throwAwayList: RegList, surroundPlane: Plane, surroundExt: CD.Number] RETURNS [newKeepList: RegList] = <<--Used for verifying abstract layers. All pieces on throwAwayList must be surrounded, otherwise the piece is moved onto the keepList>> BEGIN newKeepList _ keepList; WHILE keepList#NIL DO CStitching.ChangeRect[plane: surroundPlane, rect: CDBasics.Extend[keepList.first.rect, surroundExt], new: $cover]; keepList _ keepList.rest; ENDLOOP; WHILE throwAwayList#NIL DO IF ~RectCoveredCompletely[throwAwayList.first.rect, surroundPlane, surroundExt] THEN newKeepList _ CONS[throwAwayList.first, newKeepList]; throwAwayList _ throwAwayList.rest; ENDLOOP; END; RectCoveredCompletely: PROC [rect: CD.Rect, plane: Plane, surroundExt: CD.Number] RETURNS [BOOL _ TRUE] = BEGIN FOR surList: RegList _ CStitching.ListArea[plane, CDBasics.Extend[rect, surroundExt], $none], surList.rest WHILE surList#NIL DO IF surList.first.value=NIL THEN RETURN[FALSE]; ENDLOOP; END; RegisterAbstractLayer: PUBLIC PROC [technology: CD.Technology, abstract, actual, surround: CD.Layer, surroundExt: CD.Number]= BEGIN abstractLayerList _ CONS[NEW[AbstractLayerRec _ [technology, abstract, actual, surround, surroundExt]], abstractLayerList]; END; RegisterCleanList: PUBLIC PROC [technology: CD.Technology, clean: LIST OF CD.Layer] = BEGIN cleanList _ CONS[NEW[CleanListRec _ [technology, clean]], cleanList]; END; RegisterClassLayerFilter: PUBLIC PROC [technology: CD.Technology, classKey: REF, filter: CleanObjects.Filter] = BEGIN objectClass: CD.ObjectClass _ CD.FetchObjectClass[classKey, technology]; CDProperties.PutProp[objectClass, $cleanSpecial, NEW[CleanObjects.Filter _ filter]]; END; CDCommandOps.RegisterWithMenu[menu: $ProgramMenu, entry: "Recognize All", key: $RecognizeAll, proc: RecognizeAllCommand]; CDCommandOps.RegisterWithMenu[menu: $ProgramMenu, entry: "Recognize Top", key: $RecognizeTop, proc: RecognizeTopCommand]; CDSequencer.ImplementCommand[key: $RecognizeAll, proc: RecognizeAllCommand]; CDSequencer.ImplementCommand[key: $RecognizeTop, proc: RecognizeTopCommand]; END.