<> <> <> <> DIRECTORY CD, CornerStitching, CDCells, CDMenus, CDSequencer, CDInstances, CDDirectory, TerminalIO, OverlapRemover; OverlapRemoverImpl: CEDAR PROGRAM IMPORTS CornerStitching, CDCells, CDInstances, CDDirectory, CDMenus, 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 CornerStitching.Region; OverlapRemover: PUBLIC PROC [cellOb: CD.Object, design: CD.Design] = BEGIN WITH cellOb.specificRef SELECT FROM cp: CD.CellPtr => { OverlapRemoverCell[design, cellOb]; [] _ CDCells.RepositionCell[cellOb, design]; 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.WriteRope["Overlap removal on all levels\n"]; OverlapAllLevels[design: comm.design]; TerminalIO.WriteRope["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 { cellPtr: CD.CellPtr _ NARROW[cellOb.specificRef]; keepPlane: REF CornerStitching.Tesselation _ CornerStitching.NewTesselation[]; FillPlaneFromWires[cellPtr, layerList.first.keepLayer, keepPlane]; CompareWiresAgainstPlane[design, cellOb, cellPtr, layerList.first.throwAwayLayer, keepPlane]; }; ENDLOOP; END; FillPlaneFromWires: PROC [cellPtr: CD.CellPtr, layer: CD.Layer, plane: REF CornerStitching.Tesselation] = BEGIN FOR instanceList: CD.InstanceList _ cellPtr.contents, instanceList.rest WHILE instanceList #NIL DO IF instanceList.first.ob.class.wireTyped AND instanceList.first.ob.layer = layer THEN CornerStitching.ChangeRect[plane: plane, rect: CDInstances.InstRectI[instanceList.first], newValue: $cover]; ENDLOOP; END; CompareWiresAgainstPlane: PROC [design: CD.Design, cellOb: CD.Object, cellPtr: CD.CellPtr, layer: CD.Layer, plane: REF CornerStitching.Tesselation] = BEGIN FOR instanceList: CD.InstanceList _ cellPtr.contents, instanceList.rest WHILE instanceList #NIL DO IF instanceList.first.ob.class.wireTyped AND instanceList.first.ob.layer = layer AND RectCoveredCompletely[CDInstances.InstRectI[instanceList.first], plane] THEN [] _ CDCells.RemoveInstance[design: design, cell: cellOb, inst: instanceList.first]; ENDLOOP; END; RectCoveredCompletely: PROC [rect: CD.Rect, plane: REF CornerStitching.Tesselation] RETURNS [BOOL _ TRUE] = BEGIN FOR rectList: RegionList _ CornerStitching.ListArea[plane: plane, rect: rect, skipValue: $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>> <> <> <> <> <> <> <> <> <<>> CDMenus.CreateEntry[menu: $ProgramMenu, entry: "Overlap Remover All", key: $OverlapAll]; CDSequencer.ImplementCommand[a: $OverlapAll, p: OverlapAllCommand, queue: doQueue]; END.