-- ChipWireImpl.mesa -- Subroutines to maintain and use of a slice of features -- with constant x. -- last modified by E. McCreight, November 5, 1982 11:28 AM -- written by E. McCreight, March 5, 1982 10:12 AM DIRECTORY ChipNetDefs, ChipDRC, ChipExpand, ChipWire, FeaturePST, ppdddefs, ppdefs, StringDefs; ChipWireImpl: PROGRAM IMPORTS ChipDRC, ChipExpand, ChipNetDefs, FeaturePST, ppdddefs, StringDefs 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 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; 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]], type: bogusTransistor, lev1: nPlus]]}; cond: Conductors; caps: LayerCapPtr; id: NormalNetIdPtr; difFeature: FeaturePtr; yMin: Coord _ f.cover.y1; yMax: Coord _ f.cover.y2; SELECT f.lev FROM nPlus, pPlus => cond _ diffusion; 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 lp: listPtr _ ItemRefToLp[f.caller]; IF ppdddefs.getTextProp[lp]#NIL THEN SetupCluster[(f.net _ CanonNet[f.net]), f.caller, @dc, ppdddefs.getTextProp[lp].s]; 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, pPlus => StrengthCond[wire, diffusion], poly => StrengthCond[wire, poly], metal => StrengthCond[wire, metal], metal2 => StrengthCond[wire, metal2], pWell, nWell => StrengthCond[well, diffusion], ENDCASE => StrengthCond[none, diffusion]; 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 MergeFeatureNets: PROCEDURE[f1, f2: FeaturePtr] = BEGIN id: NetIdPtr; net: netPtr; SELECT f1.net FROM #NIL => SELECT f2.net FROM #NIL => net _ MergeNets[f1.net, f2.net]; ENDCASE => net _ RefCanonNet[f1.net]; ENDCASE => SELECT f2.net FROM #NIL => net _ RefCanonNet[f2.net]; ENDCASE => BEGIN net _ NewNet[2]; SELECT f1.lev FROM nWell, pWell => CanonNet[net].id.details _ well[attachedTo: NIL]; ENDCASE => GetNormalNetId[@net].source _ NearestCellInstance[f1.caller.head]; END; id _ (f1.net _ f2.net _ CanonNet[net]).id; IF id.final.r.x2 NULL END; END. -- of ChipWireImpl