MECSimpleRulesImpl.mesa
Copyright Ó 1988 by Xerox Corporation. All rights reserved.
Created by Louis Monier, August 2, 1988 5:33:31 pm PDT
Last edited Louis Monier, August 3, 1988 11:14:56 am PDT
DIRECTORY
CD, CDCells, CDRects, CDSimpleRules, CDSimpleRulesBackdoor, CMosB, CMosBExtras, CMosBObjects;
MECSimpleRulesImpl: CEDAR PROGRAM
IMPORTS CDCells, CDRects, CDSimpleRulesBackdoor, CMosB, CMosBExtras, CMosBObjects =
BEGIN
lambda: CD.Number = CMosB.lambda;
IRules: TYPE = CDSimpleRulesBackdoor.IRules;
Rules: TYPE = CDSimpleRules.Rules;
MinWidth: PROC [rules: Rules, layer: CD.Layer] RETURNS [CD.Number] = {
RETURN [SELECT layer FROM
CMosB.met => 3*lambda,
CMosB.met2 => 5*lambda, -- ugly hack to accomodate fat vias
CMosB.pol => 2*lambda,
CMosB.ndif, CMosB.pdif, CMosB.wndif, CMosB.wpdif => 2*lambda,
CMosB.pwellCont, CMosB.nwellCont, CMosB.wpwellCont, CMosB.wnwellCont => 2*lambda,
CMosB.nwell, CMosB.pwell => 12*lambda,
CMosB.cut, CMosB.cut2 => 2*lambda,
CMosBExtras.bond => 4*lambda,
ENDCASE => 0
]
};
MaxWidth: PROC [rules: Rules, layer: CD.Layer] RETURNS [CD.Number] = {
RETURN [SELECT layer FROM
CMosB.cut => 5*lambda,
CMosB.cut2 => 5*lambda,
ENDCASE => CD.Number.LAST
]
};
IsDiff: PROC [layer: CD.Layer] RETURNS [BOOL] = INLINE {
RETURN[layer=CMosB.ndif
OR layer=CMosB.pdif
OR layer=CMosB.wndif
OR layer=CMosB.wpdif
OR layer=CMosB.pwellCont
OR layer=CMosB.nwellCont
OR layer=CMosB.wpwellCont
OR layer=CMosB.wnwellCont
];
};
MinSpace: PROC [rules: Rules, l1, l2: CD.Layer] RETURNS [CD.Number] = {
BaseLayer: PROC [layer: CD.Layer] RETURNS [CD.Layer] = INLINE {
IF layer=CMosB.wndif THEN RETURN [CMosB.ndif];
IF layer=CMosB.wpdif THEN RETURN [CMosB.pdif];
IF layer=CMosB.wnwellCont THEN RETURN [CMosB.nwellCont];
IF layer=CMosB.wpwellCont THEN RETURN [CMosB.pwellCont];
RETURN [layer]
};
l1 ← BaseLayer[l1];
l2 ← BaseLayer[l2];
IF l1=l2 THEN
RETURN [SELECT l1 FROM
CMosB.met => 3*lambda,
CMosB.met2 => 3*lambda,
CMosB.pol => 2*lambda,
CMosB.ndif, CMosB.pdif, CMosB.pwellCont, CMosB.nwellCont => 3*lambda+lambda/2,
CMosB.pwell, CMosB.nwell => 10*lambda,
CMosB.cut => 2*lambda,
CMosB.cut2 => 2*lambda,
CMosB.imp, CMosB.ovg, CMosB.bur => 0,
CMosBExtras.bond => 8*lambda,
ENDCASE => 0
];
IF l2=CMosB.pol THEN {l2 ← l1; l1 ← CMosB.pol};
IF l1=CMosB.pol THEN {
IF IsDiff[l2] THEN RETURN[lambda];
IF l2=CMosB.cut THEN RETURN[2*lambda];
RETURN[0];
};
IF l2=CMosB.ndif THEN {l2 ← l1; l1 ← CMosB.ndif};
IF l1=CMosB.ndif THEN {
RETURN [SELECT l2 FROM
CMosB.pdif => 10*lambda,
CMosB.nwell => 5*lambda,
CMosB.pwellCont => 7*lambda/2,
CMosB.nwellCont => 9*lambda,
CMosB.cut => 2*lambda,
ENDCASE => 0
];
};
IF l2=CMosB.pdif THEN {l2 ← l1; l1 ← CMosB.pdif};
IF l1=CMosB.pdif THEN {
RETURN [SELECT l2 FROM
CMosB.pwell => 5*lambda,
CMosB.pwellCont => 9*lambda,
CMosB.nwellCont => 7*lambda/2,
CMosB.cut => 2*lambda,
ENDCASE => 0
];
};
IF l2=CMosB.pwellCont THEN {l2 ← l1; l1 ← CMosB.pwellCont};
IF l1=CMosB.pwellCont THEN {
RETURN [SELECT l2 FROM
CMosB.nwell => 4*lambda,
CMosB.nwellCont => 8*lambda,
CMosB.cut => 2*lambda,
ENDCASE => 0
];
};
IF l2=CMosB.nwellCont THEN {l2 ← l1; l1 ← CMosB.nwellCont};
IF l1=CMosB.nwellCont THEN {
RETURN [SELECT l2 FROM
CMosB.pwell => 4*lambda,
CMosB.cut => 2*lambda,
ENDCASE => 0
];
};
IF l2=CMosB.cut THEN {l2 ← l1; l1 ← CMosB.pdif};
IF l1=CMosB.cut THEN {
IF l2=CMosB.cut2 THEN RETURN[2*lambda];
RETURN [0];
};
RETURN [0]
};
mecVia: CD.Object ← NIL;
MECVia: PROC [] RETURNS [ob: CD.Object] ~ {
via: CD.Object ← CMosBObjects.CreateVia[];
m1: CD.Object ← CDRects.CreateRect[size: [5*lambda, 5*lambda], l: CMosB.met];
m2: CD.Object ← CDRects.CreateRect[size: [5*lambda, 5*lambda], l: CMosB.met2];
ob ← CDCells.CreateEmptyCell[];
[] ← CDCells.IncludeOb[design: NIL, cell: ob, ob: m1, trans: [], mode: doit];
[] ← CDCells.IncludeOb[design: NIL, cell: ob, ob: m2, trans: [], mode: doit];
[] ← CDCells.IncludeOb[design: NIL, cell: ob, ob: via, trans: [[lambda/2, lambda/2]], mode: doit];
};
Contact: PROC [rules: Rules, l1, l2: CD.Layer] RETURNS [ob: CD.Object ← NIL] = {
IF l1#CMosB.met AND l2=CMosB.met THEN RETURN [Contact[rules, l2, l1]];
IF l1=CMosB.met THEN {
IF l2=CMosB.met2 THEN RETURN [mecVia];
IF l2=CMosB.pol THEN RETURN [CMosBObjects.CreatePolyCon[]];
IF l2=CMosB.ndif OR l2=CMosB.pdif OR l2=CMosB.wpdif OR l2=CMosB.wndif THEN
RETURN [CMosBObjects.CreateDifCon[difLayer: l2]];
};
};
Init: PROC [] = {
mecVia ← MECVia[];
CDSimpleRulesBackdoor.RegisterLayerName["n-diff", CMosB.ndif];
CDSimpleRulesBackdoor.RegisterLayerName["p-diff", CMosB.wpdif];
CDSimpleRulesBackdoor.RegisterLayerName["n-well", CMosB.nwell];
CDSimpleRulesBackdoor.RegisterLayerName["nwell", CMosB.nwell];
CDSimpleRulesBackdoor.RegisterLayerName["p-well", CMosB.pwell];
CDSimpleRulesBackdoor.RegisterLayerName["pwell", CMosB.pwell];
CDSimpleRulesBackdoor.RegisterLayerName["poly", CMosB.pol];
CDSimpleRulesBackdoor.RegisterLayerName["metal", CMosB.met];
CDSimpleRulesBackdoor.RegisterLayerName["metal2", CMosB.met2];
CDSimpleRulesBackdoor.RegisterLayerName["pwellCont", CMosB.pwellCont];
CDSimpleRulesBackdoor.RegisterLayerName["nwellCont", CMosB.nwellCont];
CDSimpleRulesBackdoor.RegisterRules[[
key: NIL,
technology: CMosB.cmosB,
minWidth: MinWidth,
minSpace: MinSpace,
maxWidth: MaxWidth,
contact: Contact
]];
};
Init[];
END.