DIRECTORY CD, CDBasics, CDCommandOps, CDErrors, CDMenus, CDOrient, CDProperties, CDSequencer, CDSimpleRules, CStitching, Imager, IO, Rope, TerminalIO; CDWellTestCommand: CEDAR PROGRAM IMPORTS CD, CDBasics, CDCommandOps, CDErrors, CDMenus, CDOrient, CDProperties, CDSequencer, CDSimpleRules, CStitching, IO, TerminalIO = BEGIN wellContMaxDistInLambda: INT _ 75; --in lambda (assume 75 mu, 1 lambda = 1 mu) nothing: REF INT = NEW [INT]; StateRec: TYPE = RECORD [ nwell: CD.Layer, wellTess: CStitching.Tesselation _ NIL, nodeFound: REF NodeRec _ NIL, wellTess2: CStitching.Tesselation _ NIL, nwellcont: CD.Layer, growDist: CD.Number, diff: CD.Layer, diffTess: CStitching.Tesselation _ NIL, design: CD.Design, inst: CD.Instance, errorCount: INT _ 0 ]; NodeRec: TYPE = RECORD [ refer: REF NodeRec _ NIL ]; WellCheckCommand: PROC [comm: CDSequencer.Command] = BEGIN inst: CD.Instance; inst _ CDCommandOps.TheInstance[comm: comm, text: "check well contacts"]; IF inst#NIL THEN { no: INT; no _ CheckAGlobalInstance[comm.design, inst].errNo; TerminalIO.WriteF[" well contact check found %g problems\n", IO.int[no]]; }; END; DrawInstance: PROC [pr: CD.DrawRef, inst: CD.Instance] = BEGIN pr.drawChild[inst, inst.location, inst.orientation, pr]; END; CheckAGlobalInstance: PROC [design: CD.Design, inst: CD.Instance] RETURNS [errNo: INT] = BEGIN cf: REF CD.ContextFilter = NEW [CD.ContextFilter _ ALL[FALSE]]; dist: CD.Number _ wellContMaxDistInLambda*design.technology.lambda; pr: CD.DrawRef _ CD.CreateDrawRef[[design: design]]; state: REF StateRec _ NEW[StateRec_[ nwell: CDSimpleRules.GetLayer[design.technology, $nwell], nwellcont: CDSimpleRules.GetLayer[design.technology, $nwelCont], growDist: dist, wellTess: CStitching.NewTesselation[], diff: CDSimpleRules.GetLayer[design.technology, $pdif], diffTess: CStitching.NewTesselation[], design: design, inst: inst, errorCount: 0 ]]; cf[state.nwell] _ cf[state.nwellcont] _ cf[state.diff] _ TRUE; CDErrors.RemoveMessages[design: state.design, ob: state.inst.ob, owner: errorOwner]; pr.contextFilter _ cf; pr.devicePrivate _ state; pr.drawRect _ DrawNWellTess; -- and p-diffusion DrawInstance[pr, inst]; TerminalIO.WriteChar['.]; state.wellTess2 _ MakeCopy[state.wellTess]; pr.drawRect _ SubtractBlownContact; DrawInstance[pr, inst]; TerminalIO.WriteChar['.]; RestrictToDiff[tess: state.wellTess, restrict: state.diffTess]; TerminalIO.WriteChar['.]; CStitching.EnumerateArea[plane: state.wellTess, rect: CDBasics.universe, eachTile: ReportError, data: state]; errNo _ state.errorCount; END; GetRealNode: PROC [n: REF NodeRec] RETURNS [rn: REF NodeRec_NIL] = BEGIN IF n#NIL THEN { IF n.refer=NIL THEN rn _ n ELSE { rn _ GetRealNode[n.refer]; n.refer _ rn } }; END; Unify: PROC [a, b: REF NodeRec] RETURNS [REF NodeRec] = BEGIN ra: REF NodeRec _ GetRealNode[a]; rb: REF NodeRec _ GetRealNode[b]; IF ra#rb THEN ra.refer _ rb; RETURN [rb]; END; UnifyNodes: CStitching.TileProc = BEGIN state: REF StateRec _ NARROW[data]; WITH tile.value SELECT FROM nd: REF NodeRec => { IF state.nodeFound=NIL THEN state.nodeFound _ nd ELSE IF state.nodeFound#nd THEN state.nodeFound _ Unify[state.nodeFound, nd] }; ENDCASE => NULL END; DrawNWellTess: PROC [r: CD.Rect, l: CD.Layer, pr: CD.DrawRef] = BEGIN state: REF StateRec _ NARROW[pr.devicePrivate]; IF state.nwell=l THEN { state.nodeFound _ NIL; CStitching.EnumerateArea[plane: state.wellTess, rect: CDBasics.Extend[r, 1], eachTile: UnifyNodes, data: state]; IF state.nodeFound=NIL THEN state.nodeFound _ NEW[NodeRec]; CStitching.ChangeRect[plane: state.wellTess, rect: r, new: GetRealNode[state.nodeFound]]; } ELSE IF state.diff=l THEN { CStitching.ChangeRect[plane: state.diffTess, rect: CDBasics.Extend[r, state.growDist], new: $pdiff] }; END; SubtractBlownContact: PROC [r: CD.Rect, l: CD.Layer, pr: CD.DrawRef] = BEGIN state: REF StateRec _ NARROW[pr.devicePrivate]; IF l=state.nwellcont THEN { t: CStitching.Tile _ CStitching.FindTile[state.wellTess2, CDBasics.Center[r]]; WITH t.value SELECT FROM rn: REF NodeRec => { state.nodeFound _ rn; CStitching.ChangeEnumerateArea[plane: state.wellTess, rect: CDBasics.Extend[r, state.growDist], eachRect: SubtractConnection, data: state, skip: nothing]; }; ENDCASE => IncludeErrorMessage[state, r, "well missing"] }; END; SubtractConnection: CStitching.RectProc = BEGIN state: REF StateRec _ NARROW[data]; WITH oldValue SELECT FROM rn: REF NodeRec => { IF GetRealNode[rn]=GetRealNode[state.nodeFound] THEN { CStitching.ChangeRect[plane: state.wellTess, rect: rect, new: NIL]; } }; ENDCASE => NULL; END; RestrictToDiff: PROC [tess, restrict: CStitching.Tesselation] ~ BEGIN CStitching.EnumerateArea[plane: restrict, rect: CDBasics.universe, eachTile: RestictPerTile, data: tess, skip: NEW[INT]] END; -- RestrictToDiff RestictPerTile: CStitching.TileProc ~ BEGIN IF tile.value=NIL THEN BEGIN r: CD.Rect _ CDBasics.Intersection [CStitching.Area[tile], CDBasics.universe]; CStitching.ChangeRect[plane: NARROW[data], rect: r, new: NIL] END END; -- RestictPerTile ReportError: CStitching.TileProc = BEGIN state: REF StateRec _ NARROW[data]; IncludeErrorMessage[state, CStitching.Area[tile], "N-Well contact missing"]; END; MakeCopy: PROC [t: CStitching.Tesselation] RETURNS [new: CStitching.Tesselation] = BEGIN new _ CStitching.NewTesselation[]; CStitching.EnumerateArea[plane: t, rect: CDBasics.universe, eachTile: CopyTile, data: new] END; CopyTile: CStitching.TileProc = BEGIN into: CStitching.Tesselation _ NARROW[data]; nr: REF NodeRec _ NARROW[tile.value]; CStitching.ChangeRect[plane: into, rect: CStitching.Area[tile], new: GetRealNode[nr]] END; IncludeErrorMessage: PROC [state: REF StateRec, rect: CD.Rect, msg: Rope.ROPE] = BEGIN r: CD.Rect _ CDOrient.DeMapRect[itemInWorld: rect, cellSize: state.inst.ob.size, cellInstOrient: state.inst.orientation, cellInstPos: state.inst.location ]; state.errorCount _ state.errorCount+1; [] _ CDErrors.IncludeMessage[design: state.design, ob: state.inst.ob, rect: r, message: msg, owner: errorOwner]; END; errorOwner: ATOM _ $WellProblem; [] _ CDProperties.RegisterProperty[errorOwner, $chj]; CDMenus.CreateEntry[menu: $ProgramMenu, entry: "Check Well Contacts (Gismo)", key: $WellContactsCheck]; CDSequencer.ImplementCommand[key: $WellContactsCheck, proc: WellCheckCommand, queue: doQueue]; END. CDWellTestCommand.mesa Jacobi, November 16, 1985 4:02:43 pm PST Jacobi, January 15, 1986 6:52:06 pm PST gbb March 25, 1986 10:41:19 am PST --the original nwell tesselation --for unify Node --the copied nwell tesselation --the wellcontact -- Diffusion --reporting errors The tessellation for p-diff is created at the same time as the one of the wells. If there should be memory problems, do the following. Dispose wellTess2 after the blown contacts have been subtracted and construct the tesselation for the p-diff. --and simplify refer path --both#NIL, a#b tess is the modified tesselation. PROC [tile: REF Tile, data: REF]; --rect in world coordinates gbb March 20, 1986 3:46:40 pm PST Converted to CStitching2 changes to: DIRECTORY, CDWellTestCommand, wellContMaxDistInLambda, nothing, StateRec, CheckAGlobalInstance, UnifyNodes, DrawNWellTess, SubtractBlownContact, rn, rn, RestrictToDiff, RestictPerTile (local of RestrictToDiff), ReportError, MakeCopy, CDSequencer gbb March 25, 1986 10:41:09 am PST Changed labels of menu entries. Κ˜codešœ™K™(K™'K™"K˜—šΟk ˜ Kšœ˜Kšœ ˜ K˜ K˜ K˜K˜ K˜ K˜ K˜Kšœ ˜ Kšœ˜Kšœ˜Kšœ˜Kšœ ˜ —K˜šΠblœœ˜ Kšœœnœ˜ˆ—Kšœ˜K˜KšœœΟc+˜NKš œ œœœœ˜K˜šœ œœ˜šœ ™ Kšœœ˜Kšœ#œ˜'šœ™Kšœ œ œ˜——šœ™Kšœ$œ˜(—šœ™Kšœ œ˜Kšœ˜—šœ ™ Kšœœ˜Kšœ#œ˜'—šœ™Kšœœ˜Kšœœ ˜Kšœ œ˜—Kšœ˜—K˜šœ œœ˜Kšœœ ˜Kšœ˜K˜—šΟnœœ˜4Kš˜Kšœœ ˜KšœI˜Išœœœ˜Kšœœ˜Kšœ3˜3Kšœ=œ ˜IKšœ˜—Kšœ˜—K˜š  œœœœ ˜8Kš˜Kšœ8˜8Kšœ˜—K˜š  œœ œœ œ œ˜XKš˜KšœΟe œ[™τKš œœœœœœœ˜?Kšœœ;˜CKšœœ œ!˜4šœœ œ ˜$Kšœ9˜9Kšœ@˜@Kšœ˜Kšœ&˜&Kšœ7˜7Kšœ&˜&Kšœ˜Kšœ ˜ Kšœ ˜ Kšœ˜—Kšœ9œ˜>KšœT˜TKšœ˜Kšœ˜KšœŸ˜/Kšœ˜K˜Kšœ+˜+Kšœ#˜#Kšœ˜K˜Kšœ?˜?K˜Kšœm˜mKšœ˜Kšœ˜—K˜š   œœœ œœ œ˜BKšœ™Kš˜šœœœ˜Kšœ œœ˜šœ˜Kšœ˜Kšœ ˜ K˜—Kšœ˜—Kšœ˜K˜—š  œœœ œœ ˜7Kšœ™Kš˜Kšœœ˜!Kšœœ˜!Kšœœ˜Kšœ˜ Kšœ˜—K˜šΟb œ˜!Kš˜Kšœœ œ˜#šœ œ˜šœœ ˜Kšœœœ˜0Kšœœœ-˜LK˜—Kšœ˜—Kšœ˜—K˜š Πbn œœœ œ œ ˜?Kš˜Kšœœ œ˜/šœœ˜Kšœœ˜Kšœp˜pKšœœœœ ˜;KšœY˜YKšœ˜—šœœœ˜Kšœc˜cKšœ˜—Kšœ˜K˜—š £œœœ œ œ ˜FKš˜Kšœœ œ˜/šœœ˜Kšœœ<˜Nšœ œ˜šœœ ˜Kšœ˜Kšœš˜šK˜—Kšœ1˜8—Kšœ˜—Kšœ˜K˜š’œ˜)Kš˜Kšœœ œ˜#šœ  ˜šœœ ˜šœ.œ˜6Kšœ>œ˜CK˜—K˜—Kšœœ˜—Kšœ˜——K˜š œœœ˜EKš‘œ™!Kšœoœœ˜xKšœŸ˜š’œ˜+Kšœœ œ™!šœ œ ˜KšœœI˜NKšœœœ˜=Kš˜—KšœŸ˜——K˜š’ œ˜"Kš˜Kšœœ œ˜#KšœL˜LKšœ˜K˜—š£œœœœ˜RKš˜Kšœ"˜"KšœZ˜Zšœ˜K˜š’œ˜Kš˜Kšœœœ˜,Kšœœ œ ˜%KšœU˜UKšœ˜—K˜——K˜š  œœ œœœ˜PKšœ™Kš˜šœœ-˜2Kšœ˜Kšœ'˜'Kšœ ˜ Kšœ˜—K˜&Kšœp˜pKšœ˜—K˜Kšœ œ˜!Kšœ5˜5Kšœg˜gKšœ^˜^Kšœ˜™!K™Kšœ Οr·œ€$™—™"K™—K™—…—”%)