-- ChipWireImpl.mesa -- Subroutines to maintain and use of a slice of features -- with constant x. -- last modified by E. McCreight, August 31, 1983 9:50 AM -- written by E. McCreight, March 5, 1982 10:12 AM DIRECTORY ChipNetDefs, ChipDRC, ChipExpand, ChipWire, FeaturePST, ppdefs; ChipWireImpl: PROGRAM IMPORTS ChipDRC, ChipExpand, ChipNetDefs, FeaturePST EXPORTS ChipWire = BEGIN OPEN ppdefs, ChipNetDefs, FeaturePST, ChipExpand, ChipDRC, ChipWire; NewSlice: PUBLIC PROCEDURE RETURNS[SlicePtr] = BEGIN slice: SlicePtr _ uz.NEW[Slice]; FOR lev: ExtractLevel IN ExtractLevel DO slice[lev] _ NewFeaturePST[uz]; ENDLOOP; RETURN[slice]; END; DestroySlice: PUBLIC PROCEDURE[slice: SlicePtr] RETURNS[SlicePtr] = BEGIN FOR lev: ExtractLevel IN ExtractLevel DO slice[lev] _ DestroyFeaturePST[slice[lev]]; ENDLOOP; uz.FREE[@slice]; RETURN[NIL]; END; WireEntered: PUBLIC PROCEDURE[f: FeaturePtr, slice: SlicePtr] = BEGIN ContactToWell: PROC [item: FeaturePtr] = {MergeFeatureNets[f, item]}; CheckBuriedContact: PROCEDURE[item: FeaturePtr] = BEGIN BogusTransistor1: PROCEDURE[int: Interval] = BEGIN IF int.min BEGIN SearchFeaturePST[p: slice[nPlus], int: [min: f.cover.y1, max: f.cover.y2], touch: CheckBuriedContact]; OverlapIsViolation[p: slice[pPlus], f: f, problem: BogusPTransistor]; END; pPlus => BEGIN OverlapIsViolation[p: slice[poly], f: f, problem: BogusPTransistor]; END; nPlus => BEGIN SearchFeaturePST[p: slice[poly], int: [min: f.cover.y1, max: f.cover.y2], touch: CheckBuriedContact]; END; nwel => BEGIN SearchFeaturePST[p: slice[nwelCont], int: [min: f.cover.y1, max: f.cover.y2], touch: ContactToWell]; END; nwelCont => BEGIN SearchFeaturePST[p: slice[nwel], int: [min: f.cover.y1, max: f.cover.y2], touch: ContactToWell]; END; pwel => BEGIN SearchFeaturePST[p: slice[pwelCont], int: [min: f.cover.y1, max: f.cover.y2], touch: ContactToWell]; END; pwelCont => BEGIN SearchFeaturePST[p: slice[pwel], int: [min: f.cover.y1, max: f.cover.y2], touch: ContactToWell]; END; ENDCASE => NULL; END; -- of WireEntered WireLeft: PUBLIC PROCEDURE[f: FeaturePtr, slice: SlicePtr] = BEGIN deltaSides: INTEGER _ 2; deltaWidth: Coord _ f.cover.y2-f.cover.y1; dw: locNum; -- deltaWidth in locNum's LeaveTouch: PROCEDURE[int: Interval, repItem: FeaturePtr] = BEGIN deltaWidth _ deltaWidth- (MIN[int.max, yMax]-MAX[int.min, yMin]); deltaSides _ deltaSides-2; END; PolyIsBogusTransistor: PROCEDURE[item: FeaturePtr] = BEGIN difFeature _ item; SearchFeaturePST[p: slice[poly], int: SharedYInterval[difFeature, f], touch: BogusTransistor2]; END; BogusTransistor2: PROCEDURE[item: FeaturePtr] = {NoteViolation[[ place: RefCoordPt[ SharedArea[difFeature.cover, item.cover]], info: bogusTransistor[lev: nPlus]]]}; cond: Conductors; caps: LayerCapPtr; id: NormalNetIdPtr; difFeature: FeaturePtr; yMin: Coord _ f.cover.y1; yMax: Coord _ f.cover.y2; SELECT f.lev FROM nPlus, nwelCont => cond _ ndif; pPlus, pwelCont => cond _ pdif; poly => cond _ poly; metal => cond _ metal; metal2 => cond _ metal2; nBuriedContact => BEGIN SearchFeaturePST[p: slice[nPlus], int: [min: f.cover.y1, max: f.cover.y2], touch: PolyIsBogusTransistor]; RETURN; END; ENDCASE => RETURN; UpdateAreas[GetNormalNetId[@f.net]]; ClassifyFeaturePSTInterval[p: slice[f.lev], int: [min: yMin-1, max: yMax+1], covered: LeaveTouch, gap: NullFeatureGap]; dw _ ScaleToChipmonk[deltaWidth]; id _ GetNormalNetId[@f.net]; caps _ @id.caps[cond]; caps.cutSides _ caps.cutSides-deltaSides; caps.cutWidth _ caps.cutWidth-dw; caps.perimeter _ caps.perimeter+dw; WITH dc: f.caller.head SELECT FROM cell => BEGIN sn: Atom = FindPropValue[ItemRefToLp[f.caller], signalName]; IF sn#NIL THEN SetupCluster[(f.net _ CanonNet[f.net]), f.caller, @dc, sn]; END; ENDCASE => NULL; END; -- of WireLeft JoinConductors: PROCEDURE[f: FeaturePtr, slice: SlicePtr] = BEGIN deltaSides: INTEGER _ 2; deltaWidth: Coord _ f.cover.y2-f.cover.y1; dw: locNum; -- deltaWidth in locNum's yMin: Coord _ f.cover.y1; yMax: Coord _ f.cover.y2; Strength: TYPE = {wire, well, none}; StrengthCond: TYPE = RECORD[ strength: Strength, cond: Conductors ]; EnterTouch: PROCEDURE[int: Interval, repItem: FeaturePtr] = BEGIN deltaWidth _ deltaWidth- (MIN[int.max, yMax]-MAX[int.min, yMin]); deltaSides _ deltaSides-2; MergeFeatureNets[f, repItem]; END; strength: Strength; cond: Conductors; [strength: strength, cond: cond] _ SELECT f.lev FROM nPlus, nwelCont => StrengthCond[wire, ndif], pPlus, pwelCont => StrengthCond[wire, pdif], poly => StrengthCond[wire, poly], metal => StrengthCond[wire, metal], metal2 => StrengthCond[wire, metal2], pWell => StrengthCond[well, pdif], nWell => StrengthCond[well, ndif], ENDCASE => StrengthCond[none, ndif]; SELECT strength FROM wire => BEGIN caps: LayerCapPtr; IF f.net=NIL THEN BEGIN nid: NormalNetIdPtr; f.net _ NewNet[]; nid _ GetNormalNetId[@f.net]; nid.source _ NearestCellInstance[f.caller.head]; nid.final _ [lev: f.lev, r: f.cover]; END; UpdateAreas[GetNormalNetId[@f.net]]; ClassifyFeaturePSTInterval[p: slice[f.lev], int: [min: yMin-1, max: yMax+1], covered: EnterTouch, gap: NullFeatureGap]; dw _ ScaleToChipmonk[deltaWidth]; caps _ @GetNormalNetId[@f.net].caps[cond]; caps.cutSides _ caps.cutSides+deltaSides; caps.cutWidth _ caps.cutWidth+dw; caps.perimeter _ caps.perimeter+dw; END; well => BEGIN IF f.net=NIL THEN BEGIN cn: CanonNetPtr _ f.net _ NewNet[]; cn.id.details _ well[attachedTo: NIL]; cn.id.final _ [lev: f.lev, r: f.cover]; END; ClassifyFeaturePSTInterval[p: slice[f.lev], int: [min: yMin-1, max: yMax+1], covered: EnterTouch, gap: NullFeatureGap]; END; ENDCASE => NULL; END; -- of JoinConductors HaveSharedArea: PUBLIC PROCEDURE[r1, r2: CoordRect] RETURNS[BOOLEAN] = {RETURN[MAX[r1.x1, r2.x1] NULL END; END. -- of ChipWireImpl