difSpinifex: SX.SpinifexLayerIndex ~ SX.SpinifexLayerIndex.FIRST;
polSpinifex: SX.SpinifexLayerIndex ~ difSpinifex.SUCC;
metSpinifex: SX.SpinifexLayerIndex ~ polSpinifex.SUCC;
Init:
PROCEDURE ~ {
GeometricRule: TYPE ~ SX.GeometricRule;
difSpacingRule, difWidthRule: REF GeometricRule;
polSpacingRule, polWidthRule, polDifSepRuleA, polDifSepRuleB, polOverDifRule, polBuriedSpacingRuleA, polBuriedSpacingRuleB: REF GeometricRule;
metSpacingRule, metWidthRule, bcCutSpacingRule, bcMetalCutSpacingRuleA, bcMetalCutSpacingRuleB: REF GeometricRule;
detectOpaqueViolation: REF GeometricRule;
TriggerMap: TYPE ~ PACKED ARRAY SX.ConstraintIndex OF BOOLEAN ← ALL[FALSE];
spaceRuleTrigger: TriggerMap;
widthRuleTrigger: TriggerMap;
polOverDifTrigger1, polOverDifTrigger2, polDifSepTriggerA, polDifSepTriggerB: TriggerMap;
difSpaceTrigger1: TriggerMap;
polWidthTrigger: TriggerMap;
polBuriedSpaceTriggerA, polBuriedSpaceTriggerB, polSpaceTrigger, metSpaceTrigger, metWidthTrigger: TriggerMap;
bcSpaceTrigger, bcMetalCutSpacingTriggerA, bcMetalCutSpacingTriggerB: TriggerMap;
difResolution: REF SX.ConstraintResolution;
polyResolution: REF SX.ConstraintResolution;
metResolution: REF SX.ConstraintResolution;
Construction of the Layer Constraints.
dCnstr[dCh] ← NEW[ Constraint ← [ $DifChannel, dCh]];
pCnstr[pExcl] ← NEW[ Constraint ← [ $ExcludePol, pExcl]];
pCnstr[pExCon] ← NEW[ Constraint ← [ $ExcludePolByContact, pExCon]];
pCnstr[pDPErr] ← NEW[ Constraint ← [ $PolDifError, pDPErr]];
pCnstr[pChE] ← NEW[ Constraint ← [ $ChannelEdge, pChE]];
pCnstr[pDxorP]← NEW[ Constraint ← [ $PolXorDif, pDxorP]];
pCnstr[pDandP] ← NEW[ Constraint ← [ $PolAndDif, pDandP, TRUE, polSpinifex]];
pCnstr[pBCExcl] ← NEW[ Constraint ← [ $PolyBCExcl, pBCExcl, TRUE]];
pCnstr[pBCErr] ← NEW[ Constraint ← [ $PolyBCErr, pBCErr, TRUE]];
pCnstr[pBCCut] ← NEW[ Constraint ← [ $PolyBCCut, pBCCut]];
mCnstr[mBCEx] ← NEW[ Constraint ← [ $BCExclCut, mBCEx]];
mCnstr[mBCErr] ← NEW[ Constraint ← [ $BCErr, mBCErr]];
mCnstr[mBCCut] ← NEW[ Constraint ← [ $BCCut, mBCCut]];
mCnstr[mCutEx] ← NEW[ Constraint ← [ $CutExcl, mCutEx]];
mCnstr[mCut] ← NEW[ Constraint ← [ $Cut, mCut]];
mCnstr[mBCExM] ← NEW[ Constraint ← [ $BCExclCutM, mBCExM]];
mCnstr[mBCErrM] ← NEW[ Constraint ← [ $BCErrM, mBCErrM]];
mCnstr[mBCCutM] ← NEW[ Constraint ← [ $BCCutM, mBCCutM]];
mCnstr[mCutExM] ← NEW[ Constraint ← [ $CutExclM, mCutExM]];
mCnstr[mCutM] ← NEW[ Constraint ← [ $CutM, mCutM]];
{
nd: SX.ConstraintIndex ~ SX.nodeIndex;
sp: SX.ConstraintIndex ~ SX.spaceIndex;
dResTab: SXTechnology.ResolutionTable ~ [
[ sp, nd, dCh, ,,,,,,,,,,,,],
[ nd, nd, dCh, ,,,,,,,,,,,,],
[ dCh, dCh, dCh, ,,,,,,,,,,,,],
,,,,,,,,,,,,
];
pResTab: SXTechnology.ResolutionTable = [
[ sp, nd, pExcl, pExCon, pDPErr, pChE, pDxorP, pDandP, pBCExcl, pBCErr, ,,,,,],
[ nd, nd, pDPErr, pDPErr, pDPErr, pDPErr, nd, pDandP, pBCErr, pBCErr, ,,,,,],
[ pExcl, pDPErr, pExcl, pExCon, pDPErr, pChE, pChE, pDandP, pExcl, pExcl, ,,,,,],
[ pExCon, pDPErr, pExCon, pExCon, pDPErr, pExCon, pExCon, pDandP, pExCon, pExCon, ,,,,,],
[ pDPErr, pDPErr, pDPErr, pDPErr, pDPErr, pDPErr, pDPErr, pDandP, pDPErr, pDPErr, ,,,,,],
[ pChE, pDPErr, pChE, pExCon, pDPErr, pChE, pChE, pDandP, pChE, pChE, ,,,,,],
[ pDxorP, nd, pChE, pExCon, pDPErr, pChE, pDxorP, pDandP, pDxorP, pDxorP, ,,,,,],
[ pDandP, pDandP, pDandP, pDandP, pDandP, pDandP, pDandP, pDandP, pDandP, pDandP, ,,,,,],
[ pBCExcl, pBCErr, pExcl, pExCon, pDPErr, pChE, pDxorP, pDandP, pBCExcl, pBCErr, ,,,,,],
[ pBCErr, pBCErr, pExcl, pExCon, pDPErr, pChE, pDxorP, pDandP, pBCErr, pBCErr, ,,,,,],
,,,,,
];
mResTab: SXTechnology.ResolutionTable = [
[ sp, nd, mBCEx, mBCErr, mBCCut, mCutEx, mCut, mBCExM, mBCErrM, mBCCutM, mCutExM, mCutM,,,,],
[ nd, nd, mBCExM, mBCErrM, mBCCutM, mCutExM, mCutM, mBCExM, mBCErrM, mBCCutM, mCutExM, mCutM,,,,],
[ mBCEx, mBCExM, mBCErr, mBCErr, mBCCut, mBCErr, mCut, mBCErrM, mBCErrM, mBCCutM, mBCErrM, mCutM,,,,],
[ mBCErr, mBCErrM, mBCErr, mBCErr, mBCCut, mBCErr, mCut, mBCErrM, mBCErrM, mBCCutM, mBCErrM, mCutM,,,,],
[ mBCCut, mBCCutM, mBCCut, mBCCut, mBCCut, mBCCut, mCut, mBCCutM, mBCCutM, mBCCutM, mBCCutM, mCutM,,,,],
[ mCutEx, mCutExM, mBCErr, mBCErr, mBCCut, mCutEx, mCut, mBCErrM, mBCErrM, mBCCutM, mCutExM, mCutM,,,,],
[ mCut, mCutM, mCut, mCut, mCut, mCut, mCut, mCutM, mCutM, mCutM, mCutM, mCutM,,,,],
[ mBCExM, mBCExM, mBCErrM, mBCErrM, mBCCutM, mBCErrM, mCutM, mBCErrM, mBCErrM, mBCCutM, mBCErrM, mCutM,,,,],
[ mBCErrM, mBCErrM, mBCErrM, mBCErrM, mBCCutM, mBCErrM, mCutM, mBCErrM, mBCErrM, mBCCutM, mBCErrM, mCutM,,,,],
[ mBCCutM, mBCCutM, mBCCutM, mBCCutM, mBCCutM, mBCCutM, mCutM, mBCCutM, mBCCutM, mBCCutM, mBCCutM, mCutM,,,,],
[ mCutExM, mCutExM, mBCErrM, mBCErrM, mBCCutM, mCutExM, mCutM, mBCErrM, mBCErrM, mBCCutM, mBCExM, mCutM,,,,],
[ mCutM, mCutM, mCutM, mCutM, mCutM, mCutM, mCutM, mCutM, mCutM, mCutM, mCutM, mCutM,,,,],
,,,
];
difResolution ← SXTechnology.SetUpResolution[ dCnstr, dResTab];
polyResolution ← SXTechnology.SetUpResolution[ pCnstr, pResTab];
metResolution ← SXTechnology.SetUpResolution[ mCnstr, mResTab];
};
Basic nMosHandle & cdLayerMappings.
nMosHandle ← NEW[SX.TechHandle ← [numSpinifexLayers~3, layerInterestBloat~[(CDSimpleRules.MinDist[NMos.dif, NMos.dif]/2), (CDSimpleRules.MinDist[NMos.pol, NMos.pol]/2), (CDSimpleRules.MinDist[NMos.met, NMos.met]/2), ,,,,]] ];
nMosHandle.illegalLayer[NMos.dif] ← FALSE;
nMosHandle.illegalLayer[NMos.pol] ← FALSE;
nMosHandle.illegalLayer[NMos.met] ← FALSE;
nMosHandle.illegalLayer[NMos.ovg] ← FALSE;
nMosHandle.cdLayerMapping[NMos.dif] ← LIST[ [difSpinifex, (CDSimpleRules.MinDist[NMos.dif, NMos.dif]/2)], [polSpinifex,difToPolExtSep,pCnstr[pExcl]]];
nMosHandle.cdLayerMapping[NMos.pol] ← LIST[ [polSpinifex,(CDSimpleRules.MinDist[NMos.pol, NMos.pol]/2)]];
nMosHandle.cdLayerMapping[NMos.met] ← LIST[ [metSpinifex,(CDSimpleRules.MinDist[NMos.met, NMos.met]/2)]];
Spinifex Layer Identification.
nMosHandle.spinifexLayerNames[difSpinifex].layerId ← $Diffusion;
nMosHandle.spinifexLayerNames[polSpinifex].layerId ← $Poly;
nMosHandle.spinifexLayerNames[metSpinifex].layerId ← $Metal;
Thyme stray capacitance layer names.
nMosHandle.spinifexLayerNames[difSpinifex].thymeName ← "D";
nMosHandle.spinifexLayerNames[polSpinifex].thymeName ← "P";
nMosHandle.spinifexLayerNames[metSpinifex].thymeName ← "M";
Set Constraint Resolutions for each layer into the TechHandle.
nMosHandle.constraintResolutions[difSpinifex] ← difResolution;
nMosHandle.constraintResolutions[polSpinifex] ← polyResolution;
nMosHandle.constraintResolutions[metSpinifex] ← metResolution;
Geometric rule triggers.
spaceRuleTrigger[SX.nodeIndex] ← TRUE;
widthRuleTrigger[SX.spaceIndex] ← TRUE;
Corners are defined by union of dif and gate, but checking only looks at dif
difSpaceTrigger1[SX.nodeIndex] ← TRUE;
difSpaceTrigger1[dCh] ← TRUE;
polWidthTrigger ← ALL[TRUE];
polWidthTrigger[ SX.nodeIndex] ← FALSE;
polWidthTrigger [pDandP] ← FALSE; -- newly added by gbb
polWidthTrigger[pBCErr] ← FALSE; -- added by Bowers
polDifSepTriggerA[ SX.nodeIndex] ← TRUE;
polDifSepTriggerB[ pExcl] ← TRUE;
polDifSepTriggerB[ pExCon] ← TRUE;
Purely local errors are not handled in a natural manner by the corner-based scheme, so for every corner we find in pCnstr[pDPErr] we generate an error if there is anything on any layer nearby, of course there is always something so we get our error.
polOverDifTrigger1[ pDPErr] ← TRUE;
polOverDifTrigger2 ← ALL[TRUE];
bcSpaceTrigger[mBCCut] ← TRUE;
bcMetalCutSpacingTriggerA[mCut] ← TRUE;
bcMetalCutSpacingTriggerB[mBCCut] ← TRUE;
polBuriedSpaceTriggerA[pBCErr] ← TRUE;
polBuriedSpaceTriggerA[pBCExcl] ← TRUE;
polBuriedSpaceTriggerB[SX.nodeIndex] ← TRUE;
polSpaceTrigger[SX.nodeIndex] ← TRUE;
polSpaceTrigger[pBCErr] ← TRUE;
metSpaceTrigger[SX.nodeIndex] ← TRUE;
metSpaceTrigger[mBCExM] ← TRUE;
metSpaceTrigger[mBCErrM] ← TRUE;
metSpaceTrigger[mBCCutM] ← TRUE;
metSpaceTrigger[mCutExM] ← TRUE;
metSpaceTrigger[mCutM] ← TRUE;
metWidthTrigger[SX.spaceIndex] ← TRUE;
metWidthTrigger[mBCEx] ← TRUE;
metWidthTrigger[mBCErr] ← TRUE;
metWidthTrigger[mBCCut] ← TRUE;
metWidthTrigger[mCutEx] ← TRUE;
metWidthTrigger[mCut] ← TRUE;
The geometric rules.
difSpacingRule ← NEW[ GeometricRule ← [extent~CDSimpleRules.MinDist[NMos.dif, NMos.dif], message~"Diffusion spacing", okIfConnected~TRUE, trigger1~difSpaceTrigger1, trigger2~spaceRuleTrigger]];
difWidthRule ← NEW[ GeometricRule ← [extent~CDSimpleRules.MinWidth[NMos.dif], message~"Diffusion width", trigger1~widthRuleTrigger, trigger2~widthRuleTrigger]];
polSpacingRule ← NEW[ GeometricRule ← [extent~CDSimpleRules.MinDist[NMos.pol, NMos.pol], message~"Poly spacing", okIfConnected~TRUE, trigger1~polSpaceTrigger, trigger2~polSpaceTrigger]];
polWidthRule ← NEW[ GeometricRule ← [extent~CDSimpleRules.MinWidth[NMos.pol], message~"Poly width", trigger1~polWidthTrigger, trigger2~polWidthTrigger]];
polDifSepRuleA ← NEW[ GeometricRule ← [extent~CDSimpleRules.MinDist[NMos.pol, NMos.dif], message~"Poly/Diffusion spacing[debug:A]", trigger1~polDifSepTriggerA, trigger2~polDifSepTriggerB]];
polDifSepRuleB ← NEW[ GeometricRule ← [extent~CDSimpleRules.MinDist[NMos.pol, NMos.dif], message~"Poly/Diffusion spacing[debug:B]", trigger1~polDifSepTriggerB, trigger2~polDifSepTriggerA]];
polOverDifRule ← NEW[ GeometricRule ← [extent~polOverDif, message~"Poly over Diffusion", trigger1~polOverDifTrigger1, trigger2~polOverDifTrigger2]];
metSpacingRule ← NEW[ GeometricRule ← [extent~CDSimpleRules.MinDist[NMos.met, NMos.met], message~"Metal spacing", okIfConnected~TRUE, trigger1~metSpaceTrigger, trigger2~metSpaceTrigger]];
metWidthRule ← NEW[ GeometricRule ← [extent~CDSimpleRules.MinWidth[NMos.met], message~"Metal width", trigger1~metWidthTrigger, trigger2~metWidthTrigger]];
bcCutSpacingRule ← NEW[ GeometricRule ← [extent: 2*l, message: "Buried Contact Cut Spacing", okIfConnected: FALSE, trigger1~bcSpaceTrigger, trigger2~bcSpaceTrigger]];
bcMetalCutSpacingRuleA ← NEW[ GeometricRule ← [extent: 3*l/2, message: "Buried Contact Cut/Metal Cut Spacing[debug: A]", okIfConnected: FALSE, trigger1~bcMetalCutSpacingTriggerA, trigger2~bcMetalCutSpacingTriggerB]];
bcMetalCutSpacingRuleB ← NEW[ GeometricRule ← [extent: 3*l/2, message: "Buried Contact Cut/Metal Cut Separation[debug: B]", okIfConnected: FALSE, trigger1~bcMetalCutSpacingTriggerB, trigger2~bcMetalCutSpacingTriggerA]];
polBuriedSpacingRuleA ← NEW[ GeometricRule ← [extent: l/2, message: "Buried Contact Cut/Unrelated Poly Spacing[debug:A]", okIfConnected: TRUE, trigger1~polBuriedSpaceTriggerA, trigger2~polBuriedSpaceTriggerB]];
polBuriedSpacingRuleB ← NEW[ GeometricRule ← [extent: l/2, message: "Buried Contact Cut/Unrelated Poly Spacing[debug:B]", okIfConnected: TRUE, trigger1~polBuriedSpaceTriggerB, trigger2~polBuriedSpaceTriggerA]];
detectOpaqueViolation ← NEW[ GeometricRule ← [ extent~ l, message~ "Opaque cell boundary violated", trigger1~ ALL[TRUE], trigger2~ ALL[TRUE]]];
We set violateIndex = FALSE, ALL else TRUE so that corner checks face inward, which should result in more logically pleasing error reports.
detectOpaqueViolation.trigger1[SX.violateIndex] ← FALSE;
nMosHandle.rules[ difSpinifex] ← LIST[difSpacingRule, difWidthRule, detectOpaqueViolation];
nMosHandle.rules[ polSpinifex] ← LIST[polSpacingRule, polWidthRule, polDifSepRuleA, polDifSepRuleB, polOverDifRule, polBuriedSpacingRuleA, polBuriedSpacingRuleB, detectOpaqueViolation];
nMosHandle.rules[ metSpinifex] ← LIST[metSpacingRule, metWidthRule, bcCutSpacingRule, bcMetalCutSpacingRuleA, bcMetalCutSpacingRuleB, detectOpaqueViolation];
Technology handle is attached to the ChipNDale technology.
SXTechnology.RegisterTechnologyHandle[cdTech~ NMos.nmos, technologyHandle~ nMosHandle];
Technology specific objects.
SXTechnology.RegisterSpinifexObjectProcs[ cdTech~ NMos.nmos, objectType~$NMosTransistor, conv~ConvertNMosTransistor, thyme~ThymeNMosTransistor, rose~RoseNMosTransistor, fini~SXOutputPrivate.UnNameTransType];
SXTechnology.RegisterSpinifexObjectProcs[ cdTech~ NMos.nmos, objectType~$NMosATransistor, conv~ConvertNMosTransistor, thyme~ThymeNMosTransistor, rose~RoseNMosTransistor];
SXTechnology.RegisterSpinifexObjectProcs[ cdTech~ NMos.nmos, objectType~$NMosPullUp, conv~ConvertNMosTransistor, thyme~ThymeNMosTransistor, rose~RoseNMosTransistor];
SXTechnology.RegisterSpinifexObjectProcs[ cdTech~ NMos.nmos, objectType~$NMosContactDifAndPol, conv~ConvertNMosContactDifAndPol];
SXTechnology.RegisterSpinifexObjectProcs[ cdTech~ NMos.nmos, objectType~$NMosContactBut, conv~ConvertNMosButtingContact];
SXTechnology.RegisterSpinifexObjectProcs[ cdTech~ NMos.nmos, objectType~$NMosBurContact, conv~ConvertNMosBuriedContact];
SXTechnology.RegisterSpinifexObjectProcs[ cdTech~ NMos.nmos, objectType~$NMosMmContact, conv~ConvertNMosMmContact];
};