<> <> <> <> 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.