CDWellTestCommand.mesa
Copyright Ó 1986, 1987 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 April 6, 1987 12:33:49 pm PDT
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 [
--the original nwell tesselation
nwell: CD.Layer,
wellTess: CStitching.Tesselation ← NIL,
--for unify Node
nodeFound: REF NodeRec ← NIL,
--the copied nwell tesselation
wellTess2: CStitching.Tesselation ← NIL,
--the wellcontact
nwellcont: CD.Layer,
growDist: CD.Number,
-- Diffusion
diff: CD.Layer,
diffTess: CStitching.Tesselation ← NIL,
--reporting errors
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 {
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.ToRope[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[pr, inst.ob, inst.trans];
END;
CheckAGlobalInstance: PROC [design: CD.Design, inst: CD.Instance] RETURNS [errNo: INT] =
BEGIN
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.
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] =
--and simplify refer path
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] =
--both#NIL, a#b
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 [pr: CD.DrawRef, r: CD.Rect, l: CD.Layer] =
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 [pr: CD.DrawRef, r: CD.Rect, l: CD.Layer] =
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
tess is the modified tesselation.
CStitching.EnumerateArea[plane: restrict, rect: CDBasics.universe, eachTile: RestictPerTile, data: tess, skip: NEW[INT]]
END; -- RestrictToDiff
RestictPerTile: CStitching.TileProc ~ BEGIN
PROC [tile: REF Tile, data: REF];
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] =
--rect in world coordinates
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];
CDMenus.CreateEntry[menu: $ProgramMenu, entry: "Check Well Contacts (Gismo)", key: $WellContactsCheck];
CDSequencer.ImplementCommand[key: $WellContactsCheck, proc: WellCheckCommand, queue: doQueue];
END.
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