DrcCmosbRulesImpl.Mesa
Copyright Ó 1988 by Xerox Corporation. All rights reserved.
Opera di Giordano Bruno Beretta January 18, 1988 3:25:17 pm PST
gbb January 21, 1988 3:24:13 pm PST
Spinned out of DrcCMOSBimpl.Mesa because of "Storage overflow in pass 4" of compiler.
DIRECTORY
CD USING [Layer, Number, undefLayer],
CDProperties USING [RegisterProperty],
CMosB USING [cut, cut2, lambda, met, met2, ndif, nwell, nwellCont, ovg, pdif, pol, pwell, pwellCont],
CoreProperties USING [propPrint, PropPrintProc, Props, RegisterProperty, StoreProperties],
DesignRules USING [DesignRuleError, GetScaledValue, MaxWidth, MinSpace, MinWidth, Rules],
Drc USING [CellProc, CoreCell, Rect, State, Tech, TechRec, Wire, WireInstance, WirePairProc, WireProc],
DrcCmosb,
DrcCmosbMain USING [CompleteSeparation, FullWireCheck, SimpleMaterialSeparation, SimpleWidthCheck, VerifyWells],
DrcUtilities USING [IsWell, PrintChecked],
Rope USING [Cat, ROPE],
Saguaro USING [gate];
DrcCmosbRulesImpl: CEDAR PROGRAM
IMPORTS CDProperties, CMosB, CoreProperties, DesignRules, DrcCmosbMain, DrcUtilities, Rope, Saguaro
EXPORTS DrcCmosb
SHARES Drc
~ BEGIN OPEN CMosB, Drc, DrcCmosb, DrcCmosbMain, DrcUtilities;
gate: Layer ~ Saguaro.gate;
Layer: TYPE ~ CD.Layer;
ROPE: TYPE ~ Rope.ROPE;
cMosBsimpleKey: PUBLIC ATOM ~ CoreProperties.RegisterProperty [$simpleGenista];
cMosBcompleteKey: PUBLIC ATOM ~ CoreProperties.RegisterProperty [$completeGenista];
cMosBsimple does the same thing SoS did; cMosBcomplete verifies all VTI rules eccept for wells and transistors, which are not in Core.
CMosbTable: PUBLIC TYPE ~ REF CMosbTableRec;
Rule: TYPE ~ DrcCmosb.Rule;
CMosbTableRec: TYPE ~ DrcCmosb.CMosbTableRec;
Ze rulez
cachedTech: RECORD [t: Tech ← NIL, tk: ATOMNIL];
NewTechnology: PUBLIC PROC [key: ATOM, rules: DesignRules.Rules] RETURNS [tech: Tech] ~ BEGIN
Allocation of technology records. Fills the rule tables for a given set of design rules. Must be called before calling CheckDesignRules. The key must be one of those exported from a technology dependent part of Genista. Returns NIL if a key is invalid.
rt: CMosbTable;
toto: Rule;
ComputeMaxSeparation: PROC [key: ATOM] RETURNS [max: CD.Number] ~ BEGIN
Conservative (looks at all layers, not only the legal ones).
sep: CD.Number;
max ← 0;
FOR s1: Layer IN Layer DO
IF tech.illegalLayer[s1] THEN LOOP;
FOR s2: Layer IN Layer DO
IF tech.illegalLayer[s2] THEN LOOP;
SELECT key FROM
cMosBsimpleKey => NULL; -- all standard
cMosBcompleteKey =>
Extractor cannot handle wells adequately.
IF (IsWell [s1] AND IsWell [s2]) THEN LOOP;
ENDCASE => ERROR;
Try to filter out inappropriate layers.
sep DesignRules.MinSpace [rules, s1, s2 ! DesignRules.DesignRuleError => LOOP].s;
max ← MAX [max, sep]
ENDLOOP
ENDLOOP
END; -- ComputeMaxSeparation
IF (key # cMosBsimpleKey) AND (key # cMosBcompleteKey) THEN RETURN [NIL];
IF (cachedTech.t # NIL) AND (key = cachedTech.t.checkedBy) AND (rules.id = cachedTech.tk) THEN BEGIN
IF (key = cMosBcompleteKey) AND (cachedTech.t.verifyCell = NIL) THEN
cachedTech.t.verifyCell ← VerifyWells;
RETURN [cachedTech.t]
END;
tech ← NEW [TechRec];
tech.illegalLayer[ndif] ← tech.illegalLayer[pdif] ← tech.illegalLayer[nwell] ← tech.illegalLayer[pwellCont] ← tech.illegalLayer[nwellCont] ← tech.illegalLayer[pol] ← tech.illegalLayer[met] ← tech.illegalLayer[met2] ← tech.illegalLayer[cut] ← tech.illegalLayer[cut2] ← tech.illegalLayer[ovg] ← tech.illegalLayer[gate] ← FALSE;
tech.lambda ← lambda;
SELECT key FROM
cMosBsimpleKey => BEGIN
tech.checkedBy ← cMosBsimpleKey;
tech.maxSeparation ← ComputeMaxSeparation [cMosBsimpleKey];
tech.ttMaxSep ← tech.ctMaxSep ← tech.maxSeparation;
tech.verifyWire ← SimpleWidthCheck;
tech.verifyWirePair ← SimpleMaterialSeparation
END;
cMosBcompleteKey => BEGIN
tech.checkedBy ← cMosBcompleteKey;
tech.maxSeparation ← ComputeMaxSeparation [cMosBcompleteKey];
tech.ttMaxSep ← tech.ctMaxSep ← tech.maxSeparation; -- fixed later
tech.verifyWire ← FullWireCheck;
tech.verifyWirePair ← CompleteSeparation;
tech.verifyCell ← VerifyWells
END;
ENDCASE => ERROR;
rt ← NEW [CMosbTableRec];
FOR i: Layer IN Layer DO rt.separation[i] ← NEW [ARRAY Layer OF Rule] ENDLOOP;
FOR i: Layer IN Layer DO
IF tech.illegalLayer[i] THEN LOOP;
[toto.extent, toto.msg] ← DesignRules.MinWidth [rules, i
! DesignRules.DesignRuleError => LOOP];
rt.minWidth[i] ← toto;
[toto.extent, toto.msg] ← DesignRules.MaxWidth [rules, i
! DesignRules.DesignRuleError => LOOP];
rt.maxWidth[i] ← toto;
IF (rt.maxWidth[i].extent = 0) THEN rt.maxWidth[i].extent ← CD.Number.LAST / lambda;
rt.separation[i] ← NEW [ARRAY Layer OF Rule];
FOR j: Layer IN [0 .. i] DO
IF tech.illegalLayer[j] THEN LOOP;
[toto.extent, toto.msg] ← DesignRules.MinSpace [rules, i, j
! DesignRules.DesignRuleError => LOOP];
rt.separation[i][j] ← rt.separation[j][i] ← toto
ENDLOOP
ENDLOOP;
FOR i: Layer IN Layer DO
IF tech.illegalLayer[i] THEN LOOP;
rt.separation[i][gate] ← rt.separation[gate][i] ← rt.separation[pol][i]
ENDLOOP;
IF rt.separation[nwellCont][gate].extent = 0 THEN
rt.separation[nwellCont][gate] ← rt.separation[pwellCont][gate] ← rt.separation[gate][nwellCont] ← rt.separation[gate][pwellCont] ← [3 * lambda, "VTI 6.5.2.3"];
rt.minWidth[gate] ← rt.minWidth[pol];
rt.maxWidth[gate] ← rt.maxWidth[pol];
rt.separation[nwell][nwell].msg ← "Well spacing or notch";
rt.minWidth[nwell].msg ← "Missing well (well width)";
Via flatness rules
In  units from the minimal metal border of the via (not from the cut).
rt.viaOnFieldOxideAvoidsDiff ← DesignRules.GetScaledValue [rules, $DifViaSpace];
[toto.extent, toto.msg] ← DesignRules.GetScaledValue [rules, $DifViaSpace];
rt.viaOnFieldOxideAvoidsDiff ← toto;
rt.viaOnFieldOxideAvoidsDiff.msg ← rt.viaOnFieldOxideAvoidsDiff.msg.Cat [" Separation to diff (advisory)"];
rt.viaOnFieldOxideAvoidsPoly ← DesignRules.GetScaledValue [rules, $PolyViaSpace];
[toto.extent, toto.msg] ← DesignRules.GetScaledValue [rules, $PolyViaSpace];
rt.viaOnFieldOxideAvoidsPoly ← toto;
rt.viaOnFieldOxideAvoidsPoly.msg ← rt.viaOnFieldOxideAvoidsPoly.msg.Cat [" Separation to poly (advisory)"];
rt.fieldOxideSurroundsViaOnFieldOxide ← [MAX [rt.viaOnFieldOxideAvoidsDiff.extent, rt.viaOnFieldOxideAvoidsPoly.extent], "Separation to poly or diff (advisory)"];
rt.diffSurroundsViaOnDiff ← DesignRules.GetScaledValue [rules, $DifViaSurround];
[toto.extent, toto.msg] ← DesignRules.GetScaledValue [rules, $DifViaSurround];
rt.diffSurroundsViaOnDiff ← toto;
rt.diffSurroundsViaOnDiff.msg ← rt.diffSurroundsViaOnDiff.msg.Cat [" Insufficient diff surround (advisory)"];
rt.polySurroundsViaOnPoly ← DesignRules.GetScaledValue [rules, $PolyViaSurround];
[toto.extent, toto.msg] ← DesignRules.GetScaledValue [rules, $PolyViaSurround];
rt.polySurroundsViaOnPoly ← toto;
rt.polySurroundsViaOnPoly.msg ← rt.polySurroundsViaOnPoly.msg.Cat [" Insufficient poly surround (advisory)"];
In the following rules the extent is used only to determine the overlap of the error rectangle.
rt.viaOnPolyAndDiff ← [1 * lambda, "Topology not flat (advisory)"]; -- more for the sake of robustness
rt.viaSeparation ← [1 * lambda, "Via to via separation"]; -- only overlaps checked
rt.viaOverGate ← [1 * lambda, "Via not allowed over gate"];
rt.viaOverPoly ← [1 * lambda, "Via not allowed over poly (advisory)"];
Well rules
rt.pWellSurround ← DesignRules.GetScaledValue [rules, $NWellNDifSpace];
rt.pWellSurround.msg ← rt.pWellSurround.msg.Cat ["n-well too small or p-diffusion too close to p-well "];
rt.nWellSurround ← DesignRules.GetScaledValue [rules, $NWellPDifSurround];
[toto.extent, toto.msg] ← DesignRules.GetScaledValue [rules, $NWellPDifSurround];
rt.nWellSurround ← toto;
rt.nWellContact ← DesignRules.GetScaledValue [rules, $NWellNWellDifSurround];
[toto.extent, toto.msg] ← DesignRules.GetScaledValue [rules, $NWellNWellDifSurround];
rt.nWellContact ← toto;
rt.pWellContact ← DesignRules.GetScaledValue [rules, $PWellDifNWellSpace];
rt.wellContactSpacing ← DesignRules.GetScaledValue [rules, $NWellMaxConnect];
[toto.extent, toto.msg] ← DesignRules.GetScaledValue [rules, $NWellMaxConnect];
rt.wellContactSpacing ← toto;
rt.wellContactSpacing.msg ← rt.wellContactSpacing.msg.Cat [" Well contact required (advisory)"]; -- 6.13.3.1
In the following rules the extent is used only to determine the overlap of the error rectangle.
rt.wellConflict ← [2 * lambda, "p-well overlaps n-well"];
rt.NinN ← [2 * lambda, "n-diffusion in n-well"];
rt.PinP ← [2 * lambda, "p-diffusion in p-well"];
rt.isolatedWell ← [2 * lambda, "Isolated well"];
Exception to gate rules:
rt.diffCutToGate ← DesignRules.GetScaledValue [rules, $ContactGateSpace]; -- rule 6.5.1.6
[toto.extent, toto.msg] ← DesignRules.GetScaledValue [rules, $ContactGateSpace]; -- rule 6.5.1.6
rt.diffCutToGate ← toto; -- rule 6.5.1.6
rt.largeDiffCutToGate ← rt.diffCutToGate; -- rule 6.5.1.6
Miscellaneous rules:
rt.difCutViaSpace ← DesignRules.GetScaledValue [rules, $DifCutViaSpace]; -- rule 6.7.8
[toto.extent, toto.msg] ← DesignRules.GetScaledValue [rules, $DifCutViaSpace]; -- rule 6.7.8
rt.difCutViaSpace ← toto; -- rule 6.7.8
rt.minPadSize.extent ← DesignRules.GetScaledValue [rules, $PadMetalWidth].v
- 2 * DesignRules.GetScaledValue [rules, $PadMetalViaSurround].v; -- rule 6.9.2 - 2* 6.9.3
Compute max separation
tech.ttMaxSep ← tech.ctMaxSep ← 0;
FOR s: Layer IN Layer DO
IF tech.illegalLayer[s] THEN LOOP;
tech.ctMaxSep ← MAX [tech.ctMaxSep, rt.separation[pol][s].extent];
tech.ctMaxSep ← MAX [tech.ctMaxSep, rt.separation[gate][s].extent];
tech.ctMaxSep ← MAX [tech.ctMaxSep, rt.separation[pdif][s].extent]
ENDLOOP;
tech.ttMaxSep ← MAX [rt.separation[pol][pdif].extent, rt.separation[gate][pdif].extent, rt.separation[pol][pol].extent, rt.separation[pdif][pdif].extent];
tech.ruleTables ← rt; cachedTech ← [tech, rules.id]
END; -- NewTechnology
FlushTechCache: PUBLIC PROC ~ BEGIN
cachedTech ← [t: NIL, tk: NIL]
END; -- FlushTechCache
Initialisation
IF NOT CDProperties.RegisterProperty [cMosBsimpleKey, $gbb] THEN FlushTechCache;
[] ← CDProperties.RegisterProperty [cMosBcompleteKey, $gbb];
CoreProperties.StoreProperties [prop: cMosBsimpleKey, properties: CoreProperties.Props [[CoreProperties.propPrint, NEW [CoreProperties.PropPrintProc ← PrintChecked]]]];
CoreProperties.StoreProperties [prop: cMosBcompleteKey, properties: CoreProperties.Props [[CoreProperties.propPrint, NEW [CoreProperties.PropPrintProc ← PrintChecked]]]];
IF (CD.undefLayer # 0) THEN ERROR-- check the definition of specialLayers
END.