<> <> <> <> <> DIRECTORY CD USING [Number], CDBasics USING [empty, NonEmpty], CDBasicsInline USING [MapRect], CMosB USING [lambda, ndif, nwellCont, pdif, pol, pwellCont], CoreGeometry USING [EachInstanceProc, EnumerateGeometry, FlattenInstance, InlineBBox], CStitching USING [all, ChangeEnumerateArea, ChangeRect, IsEmpty, ListArea, NewTesselation, Rect, RectProc, Region, Tesselation, TrustedDisposeTesselation], Drc USING [Rect, State, Transf, Wire, WireInstance, WireSet], DrcCmosbGapHack USING [notChannel], DrcUtilities USING [Bloat, Contains, Intersecting, Intersection, Layer, SameLayer], Saguaro USING [gate]; DrcCmosbGapHackImpl: CEDAR PROGRAM IMPORTS CDBasics, CDBasicsInline, CMosB, CoreGeometry, CStitching, DrcUtilities, Saguaro EXPORTS DrcCmosbGapHack SHARES Drc ~ BEGIN OPEN CMosB, Drc, DrcCmosbGapHack, DrcUtilities; Region: TYPE ~ LIST OF REF CStitching.Region; Tess: TYPE ~ CStitching.Tesselation; empty: REF ~ NIL; nothing: REF INT ~ NEW [INT]; universe: Rect ~ CStitching.all; gate: Layer ~ Saguaro.gate; lambda: CD.Number ~ CMosB.lambda; rectClass: ATOM ~ $Rect; wellRectClass: ATOM ~ $WellRect; pinClass: ATOM ~ $PinOb0; markClass: ATOM ~ $AlignmentMarkOb; segmentClass: ATOM ~ $SymbolicSegment; GapIsFilled: PUBLIC PROC [gap: Rect, l: Layer, w: WireInstance, state: State, additionalWire: WireInstance _ notChannel, additionalCells: LIST OF WireSet _ NIL] RETURNS [notch: LIST OF Rect] ~ BEGIN <> cracker: Tess _ CStitching.NewTesselation [stopFlag: state.abort]; nibbledCracker: Region; notchBB: Rect _ CDBasics.empty; transf: Transf _ w.transf; Nibble: CStitching.RectProc ~ BEGIN <<[plane: REF Tesselation, rect: Rect, oldValue: REF, data: REF]>> WITH oldValue SELECT FROM any: ATOM => cracker.ChangeRect [rect: rect, new: empty]; ENDCASE => NULL END; -- Nibble Bite: CStitching.RectProc ~ BEGIN <<[plane: REF Tesselation, rect: Rect, oldValue: REF, data: REF]>> WITH oldValue SELECT FROM any: ATOM => NULL; ENDCASE => cracker.ChangeRect [rect: rect, new: data] END; -- Bite FindPatch: CoreGeometry.EachInstanceProc ~ BEGIN <> <> SELECT instance.obj.class.objectType FROM rectClass, wellRectClass => IF (SameLayer [instance.obj.layer, l] OR (SameLayer [instance.obj.layer, gate] AND ((l = pdif) OR (l = ndif)))) THEN BEGIN r: Rect _ CDBasicsInline.MapRect [CoreGeometry.InlineBBox [instance], transf]; <> IF (instance.obj.layer = gate) THEN r _ Bloat [r, lambda]; IF Contains [r, gap] THEN {quit _ TRUE; notch _ NIL} END; markClass, segmentClass, pinClass => NULL; ENDCASE => quit _ CoreGeometry.FlattenInstance [instance, FindPatch] END; -- FindPatch FindFancyPatch: CoreGeometry.EachInstanceProc ~ BEGIN <> SELECT instance.obj.class.objectType FROM rectClass, wellRectClass => IF (SameLayer [instance.obj.layer, l] OR (SameLayer [instance.obj.layer, gate] AND ((l = pdif) OR (l = ndif)))) THEN BEGIN r: Rect _ CDBasicsInline.MapRect [CoreGeometry.InlineBBox [instance], transf]; <> IF (instance.obj.layer = gate) THEN r _ Bloat [r, lambda] ELSE r _ Bloat [r, 1]; IF Intersecting [r, gap] THEN cracker.ChangeEnumerateArea [Intersection [r, gap], Nibble, NIL, empty]; IF cracker.IsEmpty [] THEN quit _ TRUE END; markClass, segmentClass, pinClass => NULL; ENDCASE => quit _ CoreGeometry.FlattenInstance [instance, FindFancyPatch] END; -- FindFancyPatch IF (gap.x1 = gap.x2) OR (gap.y1 = gap.y2) THEN RETURN [NIL]; notch _ LIST [gap]; IF (w.local = NIL) THEN RETURN [notch]; IF state.attributes.EnumerateGeometry [w.local, FindPatch] THEN RETURN [NIL]; cracker _ CStitching.NewTesselation [stopFlag: state.abort]; cracker.ChangeEnumerateArea [gap, Bite, $gap, nothing]; IF state.attributes.EnumerateGeometry [w.local, FindFancyPatch] THEN RETURN [NIL]; IF (additionalWire.local # NIL) THEN BEGIN transf _ additionalWire.transf; IF state.attributes.EnumerateGeometry [additionalWire.local, FindPatch] THEN RETURN [NIL]; IF state.attributes.EnumerateGeometry [additionalWire.local, FindFancyPatch] THEN RETURN [NIL] END; <> FOR cl: LIST OF WireSet _ additionalCells, cl.rest WHILE cl # NIL DO FOR i: NAT IN [0 .. cl.first.size) DO transf _ cl.first[i].transf; IF state.attributes.EnumerateGeometry [cl.first[i].local, FindFancyPatch] THEN RETURN [NIL] ENDLOOP ENDLOOP; nibbledCracker _ cracker.ListArea [universe]; notch _ NIL; FOR n: Region _ nibbledCracker, n.rest WHILE n # NIL DO notchBB.x1 _ MIN [notchBB.x1, n.first.rect.x1]; notchBB.y1 _ MIN [notchBB.y1, n.first.rect.y1]; notchBB.x2 _ MAX [notchBB.x2, n.first.rect.x2]; notchBB.y2 _ MAX [notchBB.y2, n.first.rect.y2]; notch _ CONS [n.first.rect, notch] ENDLOOP; IF CDBasics.NonEmpty [notchBB] THEN BEGIN nibbledEdges: CARDINAL _ 0; s, w, n, e: BOOL _ FALSE; IF notchBB.x1 > gap.x1 THEN {w _ TRUE; nibbledEdges _ nibbledEdges.SUCC}; IF notchBB.y1 > gap.y1 THEN {s _ TRUE; nibbledEdges _ nibbledEdges.SUCC}; IF notchBB.x2 < gap.x2 THEN {e _ TRUE; nibbledEdges _ nibbledEdges.SUCC}; IF notchBB.y2 < gap.y2 THEN {n _ TRUE; nibbledEdges _ nibbledEdges.SUCC}; IF (nibbledEdges = 2) AND ((w AND s) OR (s AND e) OR (e AND n) OR (n AND w)) THEN notch _ NIL END; cracker.TrustedDisposeTesselation [] END; -- GapIsFilled END.