<> <> <> <> DIRECTORY CD, CDSimpleRules, CDSimpleRulesBackdoor, CMos, CMosObjects; CMosSimpleRulesImpl: CEDAR PROGRAM IMPORTS CDSimpleRulesBackdoor, CMos, CMosObjects = BEGIN lambda: CD.Number = CMos.lambda; IRules: TYPE = CDSimpleRulesBackdoor.IRules; Rules: TYPE = CDSimpleRules.Rules; MinWidth: PROC [rules: Rules, layer: CD.Layer] RETURNS [CD.Number] = BEGIN RETURN [SELECT layer FROM CMos.met => 3*lambda, CMos.met2 => 4*lambda, CMos.pol => 2*lambda, CMos.ndif, CMos.pdif, CMos.wndif, CMos.wpdif => 2*lambda, CMos.pwellCont, CMos.nwellCont => 2*lambda, CMos.nwell, CMos.pwell => 12*lambda, ENDCASE => 0 ] END; BaseLayer: PROC [layer: CD.Layer] RETURNS [CD.Layer] = INLINE BEGIN IF layer=CMos.wndif OR layer=CMos.pwellCont THEN RETURN [CMos.ndif]; IF layer=CMos.wpdif OR layer=CMos.nwellCont THEN RETURN [CMos.pdif]; RETURN [layer] END; IsDiff: PROC [layer: CD.Layer] RETURNS [BOOL] = BEGIN RETURN[layer=CMos.ndif OR layer=CMos.pdif OR layer=CMos.wndif OR layer=CMos.wpdif OR layer=CMos.pwellCont OR layer=CMos.nwellCont]; END; MinSpace: PROC [rules: Rules, l1, l2: CD.Layer] RETURNS [CD.Number] = BEGIN l1 _ BaseLayer[l1]; l2 _ BaseLayer[l2]; IF l1=l2 THEN RETURN [SELECT l1 FROM CMos.met => 3*lambda, CMos.met2 => 4*lambda, CMos.pol => 2*lambda, CMos.ndif, CMos.pdif => 3*lambda, CMos.pwell, CMos.nwell => 10*lambda, CMos.cut => 3*lambda, CMos.cut2, CMos.imp, CMos.ovg, CMos.bur => 0, ENDCASE => 0 ]; IF l2=CMos.met THEN {l2 _ l1; l1 _ CMos.met}; IF l1=CMos.met THEN RETURN [SELECT l2 FROM CMos.cut => 2*lambda, ENDCASE => 0 ]; IF l2=CMos.met2 THEN {l2 _ l1; l1 _ CMos.met2}; IF l1=CMos.met2 THEN RETURN [SELECT l2 FROM CMos.cut2 => 2*lambda, ENDCASE => 0 ]; IF l2=CMos.pol THEN {l2 _ l1; l1 _ CMos.pol}; IF l1=CMos.pol THEN { IF IsDiff[l2] THEN RETURN[lambda]; IF l2=CMos.cut OR l2=CMos.bur THEN RETURN[2*lambda]; RETURN[0]; }; IF l2=CMos.ndif THEN {l2 _ l1; l1 _ CMos.ndif}; IF l1=CMos.ndif THEN { RETURN [SELECT l2 FROM CMos.pdif => 10*lambda, CMos.nwell => 5*lambda, CMos.cut, CMos.bur => 2*lambda, ENDCASE => 0 ]; }; IF l2=CMos.pdif THEN {l2 _ l1; l1 _ CMos.pdif}; IF l1=CMos.pdif THEN { RETURN [SELECT l2 FROM CMos.pwell => 5*lambda, CMos.cut, CMos.bur => 2*lambda, ENDCASE => 0 ]; }; RETURN [0] END; Contact: PROC [rules: Rules, l1, l2: CD.Layer] RETURNS [ob: CD.Object _ NIL] = BEGIN IF l1#CMos.met AND l2=CMos.met THEN RETURN [Contact[rules, l2, l1]]; IF l1=CMos.met THEN { IF l2=CMos.pol THEN RETURN [CMosObjects.CreatePolyCon[]]; IF l2=CMos.met2 THEN RETURN [CMosObjects.CreateMmCon[]]; IF l2=CMos.ndif OR l2=CMos.pdif OR l2=CMos.wpdif OR l2=CMos.wndif THEN RETURN [CMosObjects.CreateDifCon[difLayer: l2]]; }; END; Init: PROC [] = BEGIN CDSimpleRulesBackdoor.RegisterLayerName["n-diff", CMos.ndif]; CDSimpleRulesBackdoor.RegisterLayerName["p-diff", CMos.wpdif]; CDSimpleRulesBackdoor.RegisterLayerName["n-well", CMos.nwell]; CDSimpleRulesBackdoor.RegisterLayerName["nwell", CMos.nwell]; CDSimpleRulesBackdoor.RegisterLayerName["p-well", CMos.pwell]; CDSimpleRulesBackdoor.RegisterLayerName["pwell", CMos.pwell]; CDSimpleRulesBackdoor.RegisterLayerName["poly", CMos.pol]; CDSimpleRulesBackdoor.RegisterLayerName["metal", CMos.met]; CDSimpleRulesBackdoor.RegisterLayerName["metal2", CMos.met2]; CDSimpleRulesBackdoor.RegisterLayerName["pwellCont", CMos.pwellCont]; CDSimpleRulesBackdoor.RegisterLayerName["nwellCont", CMos.nwellCont]; CDSimpleRulesBackdoor.RegisterRules[[ key: NIL, technology: CMos.cmos, minWidth: MinWidth, minSpace: MinSpace, contact: Contact ]]; END; Init[]; END.