<> <> <> <> <> DIRECTORY CD, CStitching, CDCells, CDCommandOps, CDSequencer, CDInstances, CDDirectory, TerminalIO, OverlapRemover; OverlapRemoverImpl: CEDAR PROGRAM IMPORTS CStitching, CDCells, CDCommandOps, CDInstances, CDDirectory, CDSequencer, TerminalIO EXPORTS OverlapRemover = BEGIN OverlapLayerRec: TYPE = RECORD [ technology: CD.Technology, keepLayer: CD.Layer, throwAwayLayer: CD.Layer ]; overlapLayerList: LIST OF REF OverlapLayerRec _ NIL; --contains registered abstract Layers RegionList: TYPE = LIST OF REF CStitching.Region; OverlapRemover: PUBLIC PROC [cellOb: CD.Object, design: CD.Design] = BEGIN WITH cellOb.specific SELECT FROM cp: CD.CellSpecific => { OverlapRemoverCell[design, cellOb]; [] _ CDCells.ResizeCell[design, cellOb]; CDDirectory.PropagateChange[cellOb, design]; }; ENDCASE => NULL; END; OverlapAllLevels: PROC [design: CD.Design] = BEGIN DoIt: CDDirectory.EachEntryAction = { OverlapRemover[cellOb: ob, design: design] }; [] _ CDDirectory.Enumerate[design, DoIt]; OverlapRemover[design.actual.first.dummyCell.ob, design]; END; OverlapAllCommand: PROC [comm: CDSequencer.Command] = BEGIN TerminalIO.PutRope["Overlap removal on all levels\n"]; OverlapAllLevels[design: comm.design]; TerminalIO.PutRope["Removal Finished\n"]; END; OverlapRemoverCell: PROC [design: CD.Design, cellOb: CD.Object] = BEGIN FOR layerList: LIST OF REF OverlapLayerRec _ overlapLayerList, layerList.rest WHILE layerList #NIL DO IF layerList.first.technology = design.technology THEN { keepPlane: CStitching.Tesselation _ CStitching.NewTesselation[]; FillPlaneFromWires[cellOb, layerList.first.keepLayer, keepPlane]; CompareWiresAgainstPlane[design, cellOb, layerList.first.throwAwayLayer, keepPlane]; }; ENDLOOP; END; FillPlaneFromWires: PROC [cellOb: CD.Object, layer: CD.Layer, plane: CStitching.Tesselation] = BEGIN EachInstance: CDCells.InstEnumerator = { IF inst.ob.class.wireTyped AND inst.ob.layer = layer THEN CStitching.ChangeRect[plane: plane, rect: CDInstances.InstRectI[inst], new: $cover]; }; [] _ CDCells.EnumerateInstances[cellOb, EachInstance]; END; CompareWiresAgainstPlane: PROC [design: CD.Design, cellOb: CD.Object, layer: CD.Layer, plane: CStitching.Tesselation] = BEGIN removeList: CD.InstanceList _ NIL; EachInstance: CDCells.InstEnumerator = { IF inst.ob.class.wireTyped AND inst.ob.layer = layer AND RectCoveredCompletely[CDInstances.InstRectI[inst], plane] THEN removeList _ CONS[inst, removeList]; }; [] _ CDCells.EnumerateInstances[cellOb, EachInstance]; FOR il: CD.InstanceList _ removeList, il.rest WHILE il #NIL DO [] _ CDCells.RemoveInstance[design: design, cell: cellOb, inst: il.first]; ENDLOOP; END; RectCoveredCompletely: PROC [rect: CD.Rect, plane: CStitching.Tesselation] RETURNS [BOOL _ TRUE] = BEGIN FOR rectList: RegionList _ CStitching.ListArea[plane: plane, rect: rect, skip: $none], rectList.rest WHILE rectList #NIL DO IF rectList.first.value = NIL THEN RETURN[FALSE]; ENDLOOP; END; RegisterOverlapLayers: PUBLIC PROC [technology: CD.Technology, keepLayer: CD.Layer, throwAwayLayer: CD.Layer] = BEGIN overlapLayerList _ CONS[NEW[OverlapLayerRec _ [technology, keepLayer, throwAwayLayer]], overlapLayerList]; END; <<--Its not clear that an Overlap Remover on the Top level is a useful command, but if someone wants it just uncomment the below>> <> <> <> <> <> <> <> <> <<>> CDCommandOps.RegisterWithMenu[menu: $ProgramMenu, entry: "Overlap Remover All", key: $OverlapAll]; CDSequencer.ImplementCommand[key: $OverlapAll, proc: OverlapAllCommand, queue: doQueue]; END.