DIRECTORY CD, CDBasics, CDCommandOps, CDErrors, CDMenus, CDOrient, CDProperties, CDSequencer, CDSimpleRules, CornerStitching, IO, Rope, TerminalIO; CDWellTestCommand: CEDAR PROGRAM IMPORTS CD, CDBasics, CDCommandOps, CDErrors, CDMenus, CDOrient, CDProperties, CDSequencer, CDSimpleRules, CornerStitching, IO, TerminalIO = BEGIN wellContMaxDistInLambda: INT _ 75; --in lambda (assume 75 mu, 1 lambda = 1 mu) StateRec: TYPE = RECORD [ nwell: CD.Layer, wellTess: REF CornerStitching.Tesselation _ NIL, nodeFound: REF NodeRec _ NIL, wellTess2: REF CornerStitching.Tesselation _ NIL, nwellcont: CD.Layer, growDist: CD.Number, 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 dist: CD.Number _ wellContMaxDistInLambda*design.technology.lambda; pr: CD.DrawRef _ CD.CreateDrawRef[design]; state: REF StateRec _ NEW[StateRec_[ nwell: CDSimpleRules.GetLayer[design.technology, $nwell], nwellcont: CDSimpleRules.GetLayer[design.technology, $nwelCont], growDist: dist, wellTess: CornerStitching.NewTesselation[], design: design, inst: inst, errorCount: 0 ]]; CDErrors.RemoveMessages[design: state.design, ob: state.inst.ob, owner: errorOwner]; pr.devicePrivate _ state; pr.drawRect _ DrawNWellTess; DrawInstance[pr, inst]; state.wellTess2 _ MakeCopy[state.wellTess]; pr.drawRect _ SubtractBlownContact; DrawInstance[pr, inst]; CornerStitching.EnumerateArea[plane: state.wellTess, rect: CDBasics.universe, perTile: 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: CornerStitching.PerTileProc = 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; CornerStitching.EnumerateArea[plane: state.wellTess, rect: CDBasics.Extend[r, 1], perTile: UnifyNodes, data: state]; IF state.nodeFound=NIL THEN state.nodeFound _ NEW[NodeRec]; CornerStitching.ChangeRect[plane: state.wellTess, rect: r, newValue: GetRealNode[state.nodeFound]]; }; 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: REF CornerStitching.Tile _ CornerStitching.TileAt[state.wellTess2, CDBasics.Center[r]]; WITH t.value SELECT FROM rn: REF NodeRec => { state.nodeFound _ rn; CornerStitching.FuncChangeRect[plane: state.wellTess, rect: CDBasics.Extend[r, state.growDist], perTile: SubtractConnection, data: state]; }; ENDCASE => IncludeErrorMessage[state, r, "well missing"] }; END; SubtractConnection: CornerStitching.PerTileChangeProc = BEGIN state: REF StateRec _ NARROW[data]; WITH oldValue SELECT FROM rn: REF NodeRec => { IF GetRealNode[rn]=GetRealNode[state.nodeFound] THEN { CornerStitching.ChangeRect[plane: state.wellTess, rect: rect, newValue: NIL]; } }; ENDCASE => NULL; END; ReportError: CornerStitching.PerTileProc = BEGIN state: REF StateRec _ NARROW[data]; IncludeErrorMessage[state, CornerStitching.Area[tile], "N-Well contact missing"]; END; MakeCopy: PROC [t: REF CornerStitching.Tesselation] RETURNS [new: REF CornerStitching.Tesselation] = BEGIN new _ CornerStitching.NewTesselation[]; CornerStitching.EnumerateArea[plane: t, rect: CDBasics.universe, perTile: CopyTile, data: new] END; CopyTile: CornerStitching.PerTileProc = BEGIN into: REF CornerStitching.Tesselation _ NARROW[data]; nr: REF NodeRec _ NARROW[tile.value]; CornerStitching.ChangeRect[plane: into, rect: CornerStitching.Area[tile], newValue: 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", key: $WellContactsCheck]; CDSequencer.ImplementCommand[a: $WellContactsCheck, p: WellCheckCommand, queue: doQueue]; END. xCDWellTestCommand.mesa Jacobi, November 16, 1985 4:02:43 pm PST Jacobi, November 18, 1985 12:15:14 pm PST copy /indigo/chipndale/temp/CDWellTestCommand.mesa _ CDWellTestCommand.mesa --the original nwell tesselation --for unify Node --the copied nwell tesselation --the wellcontact --reporting errors --and simplify refer path --both#NIL, a#b --rect in world coordinates Κ˜codešœ™K™(K™)KšœK™KK˜—šΟk ˜ Kšœ˜Kšœ ˜ K˜ K˜ K˜K˜ K˜ K˜ K˜Kšœ˜Kšœ˜Kšœ˜Kšœ ˜ —K˜šΠblœœ˜ Kšœœƒ˜—Kšœ˜K˜KšœœΟc+˜NK˜šœ œœ˜šœ ™ Kšœœ˜Kšœ œœ˜0šœ™Kšœ œ œ˜——šœ™Kšœ œœ˜1—šœ™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šœœ;˜CKšœœ œ˜*šœœ œ ˜$Kšœ9˜9Kšœ@˜@Kšœ˜Kšœ+˜+Kšœ˜Kšœ ˜ Kšœ ˜ Kšœ˜—KšœT˜TKšœ˜Kšœ˜Kšœ˜Kšœ+˜+Kšœ#˜#Kšœ˜Kšœq˜qKšœ˜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šœt˜tKšœœœœ ˜;Kšœc˜cKšœ˜—Kšœ˜K˜—š ’œœœ œ œ ˜FKš˜Kšœœ œ˜/šœœ˜KšœœT˜Zšœ œ˜šœœ ˜Kšœ˜KšœŠ˜ŠK˜—Kšœ1˜8—Kšœ˜—Kšœ˜K˜š‘œ%˜7Kš˜Kšœœ œ˜#šœ  ˜šœœ ˜šœ.œ˜6KšœHœ˜MK˜—K˜—Kšœœ˜—Kšœ˜——K˜K˜š‘ œ˜*Kš˜Kšœœ œ˜#KšœQ˜QKšœ˜K˜—š’œœœ,œ˜dKš˜Kšœ'˜'Kšœ^˜^šœ˜K˜š‘œ˜'Kš˜Kšœœœ˜5Kšœœ œ ˜%Kšœd˜dKšœ˜—K˜——K˜š  œœ œœœ˜PKšœ™Kš˜šœœ-˜2Kšœ˜Kšœ'˜'Kšœ ˜ Kšœ˜—K˜&Kšœp˜pKšœ˜—K˜Kšœ œ˜!Kšœ5˜5Kšœ_˜_KšœY˜YKšœ˜—…—Ψn