DIRECTORY CD, CDBasics, CDCommandOps, CDErrors, CDOps, CDProperties, CDSequencer, CDSimpleRules, CStitching, Imager, IO, Rope, TerminalIO; CDWellTestCommand: CEDAR PROGRAM IMPORTS CD, CDBasics, CDErrors, CDOps, 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 FOR all: CD.InstanceList _ CDOps.InstList [comm.design], all.rest WHILE all # NIL DO IF all.first.selected THEN BEGIN no: INT; no _ CheckAGlobalInstance[comm.design, all.first].errNo; IF no > 0 THEN BEGIN TerminalIO.PutF["\n%g: ", IO.rope[CDOps.ObjectRope[all.first.ob]]]; TerminalIO.PutF["Well contact check found %g problems.\n", IO.int[no]] END END ENDLOOP; TerminalIO.PutRope ["\nWellCheckCommand done.\n"] END; DrawInstance: PROC [pr: CD.DrawRef, inst: CD.Instance] = BEGIN pr.drawChild[inst, inst.trans, 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, $nwel], 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.PutRope["."]; state.wellTess2 _ MakeCopy[state.wellTess]; pr.drawRect _ SubtractBlownContact; DrawInstance[pr, inst]; TerminalIO.PutRope["."]; RestrictToDiff[tess: state.wellTess, restrict: state.diffTess]; TerminalIO.PutRope["."]; 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 _ CDBasics.DeMapRect [itemInWorld: rect, cellInWorld: state.inst.trans]; 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]; CDSequencer.ImplementCommand[key: $WellContactsCheck, proc: WellCheckCommand, queue: doQueue]; END. 8CDWellTestCommand.mesa Copyright c 1986 by Xerox Corporation. All rights reserved. Jacobi, November 16, 1985 4:02:43 pm PST Jacobi, January 15, 1986 6:52:06 pm PST gbb December 8, 1986 5:05:12 pm PST --the original nwell tesselation --for unify Node --the copied nwell tesselation --the wellcontact -- Diffusion --reporting errors inst: CD.Instance; inst _ CDCommandOps.TheInstance[comm: comm, text: "check well contacts"]; IF inst#NIL THEN { }; 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 CDMenus.CreateEntry[menu: $ProgramMenu, entry: "Check Well Contacts (Gismo)", key: $WellContactsCheck]; 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. gbb May 20, 1986 5:34:04 pm PDT Tracked change from $nwell to $nwel in ChipNDale changes to: CheckAGlobalInstance. gbb June 12, 1986 3:07:15 pm PDT Changed command to loop over all selected cells. changes to: WellCheckCommand: traded TheInstance for a for list loop Κι˜codešœ™Kšœ Οmœ1™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˜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šž˜KšœžœN˜SK˜&Kšœp˜pKšžœ˜—K˜Kšœ žœ˜!Kšœ5˜5Kšœg™gKšœ^˜^Kšžœ˜™!K™Kšœ Οr·œ₯$™—™"K™—™Kšœ0™0Kšœ ₯œ™!—™ K™0Kšœ ₯œ(™D—K™—…—F'g