<> <> <> <> <> <> <<>> DIRECTORY CD, CDBasics, CDCommandOps, CDErrors, CDMenus, CDOrient, CDProperties, CDSequencer, CDSimpleRules, CornerStitching, IO, 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) TessData: TYPE = RECORD [ toDo: ARRAY CD.Layer OF REF TessDefine _ ALL[NIL] ]; TessDefine: TYPE = RECORD[ tess: REF CornerStitching.Tesselation _ NIL, surround: CD.Number _ 0, value: REF _ $covered ]; ReportRec: TYPE = RECORD [ design: CD.Design, inst: CD.Instance, count: INT _ 0 ]; 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]; report: REF ReportRec _ NEW[ReportRec_[design: design, inst: inst]]; passTessInfo: REF TessData _ NEW[TessData]; nwell: CD.Layer _ CDSimpleRules.GetLayer[design.technology, $nwell]; nwellcontact: CD.Layer _ CDSimpleRules.GetLayer[design.technology, $nwelCont]; passTessInfo.toDo[nwell] _ NEW[TessDefine]; passTessInfo.toDo[nwell].tess _ CornerStitching.NewTesselation[]; passTessInfo.toDo[nwellcontact] _ NEW[TessDefine]; passTessInfo.toDo[nwellcontact].tess _ CornerStitching.NewTesselation[]; passTessInfo.toDo[nwellcontact].surround _ dist; pr.devicePrivate _ passTessInfo; pr.drawRect _ DrawInTess; DrawInstance[pr, inst]; SubTess[passTessInfo.toDo[nwell].tess, passTessInfo.toDo[nwellcontact].tess]; CDErrors.RemoveMessages[design: report.design, ob: report.inst.ob, owner: errorOwner]; CornerStitching.EnumerateArea[plane: passTessInfo.toDo[nwell].tess, rect: CDBasics.universe, perTile: ReportError, data: report]; errNo _ report.count; END; DrawInTess: PROC [r: CD.Rect, l: CD.Layer, pr: CD.DrawRef] = BEGIN tessData: REF TessData _ NARROW[pr.devicePrivate]; tessDefine: REF TessDefine; IF (tessDefine_tessData.toDo[l])#NIL THEN CornerStitching.ChangeRect[plane: tessDefine.tess, rect: CDBasics.Extend[r, tessDefine.surround], newValue: tessDefine.value] END; Remove: CornerStitching.PerTileProc = BEGIN from: REF CornerStitching.Tesselation _ NARROW[data]; CornerStitching.ChangeRect[from, CornerStitching.Area[tile], NIL] END; ReportError: CornerStitching.PerTileProc = BEGIN rect: CD.Rect; report: REF ReportRec _ NARROW[data]; report.count _ report.count+1; rect _ CDOrient.DeMapRect[itemInWorld: CornerStitching.Area[tile], cellSize: report.inst.ob.size, cellInstOrient: report.inst.orientation, cellInstPos: report.inst.location ]; [] _ CDErrors.IncludeMessage[design: report.design, ob: report.inst.ob, rect: rect, message: "N-Well contact missing", owner: errorOwner]; END; SubTess: PROC [x, minus: REF CornerStitching.Tesselation] = BEGIN CornerStitching.EnumerateArea[plane: minus, rect: CDBasics.universe, perTile: Remove, data: x] 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.