<> <> <> <<>> <<-- Add the rules for difContact!>> <<>> DIRECTORY CD, CDAtomicObjects, CDBasics, CDCells, CDLayers, CDSimpleRules, CDSymbolicObjects, CMosB, CMosBObjects, CDDesignRules; CDDesignRulesImpl: CEDAR PROGRAM IMPORTS CD, CDBasics, CDCells, CDLayers, CDSimpleRules, CDSymbolicObjects, CMosB, CMosBObjects EXPORTS CDDesignRules = BEGIN OPEN CDDesignRules; <> FindRules: PUBLIC PROC [a: ATOM] RETURNS [dr: DesignRules] ~ { targetTech: CD.Technology _ CD.FetchTechnology[a]; -- extract techno from atom instead! lambda: INT _ targetTech.lambda; dr _ NEW [DesignRulesRep _ [ atom: a, techno: targetTech, lambda: lambda, gateSDNodeSp: 3*lambda, standardTrSize: [4*lambda, 2*lambda], trPolExt: 2*lambda, trDifExt: 3*lambda, pol: GetLayer[targetTech, $pol], met: GetLayer[targetTech, $met], met2: GetLayer[targetTech, $met2], cut: GetLayer[targetTech, $cut], cut2: GetLayer[targetTech, $cut2], gate: CD.NewLayer[CMosB.cmosB, $gate], ndif: GetLayer[targetTech, $ndif], pdif: GetLayer[targetTech, $pdif], wndif: GetLayer[targetTech, $wndif], wpdif: GetLayer[targetTech, $wpdif], nwell: GetLayer[targetTech, $nwel], pwell: GetLayer[targetTech, $pwel], nwellCont: GetLayer[targetTech, $nwelCont], pwellCont: GetLayer[targetTech, $pwelCont] ]]; }; <> MinWidth: PUBLIC PROC [dr: DesignRules, layer: CD.Layer] RETURNS [dist: CD.Number] = { dist _ CDSimpleRules.MinWidth[layer]; }; <<-- Layers are electrically non-connected>> MinDist: PUBLIC PROC [dr: DesignRules, l1, l2: CD.Layer] RETURNS [dist: CD.Number] = { OPEN dr; IF l1=gate OR l2=gate THEN RETURN [0]; -- think more! IF l1=nwell OR l2=nwell THEN RETURN [0]; -- strange! IF l1=l2 THEN RETURN [SELECT l1 FROM met => 3*lambda, met2 => 4*lambda, pol => 2*lambda+lambda/2, ndif, pdif => 3*lambda+lambda/2, pwell, nwell => 10*lambda, cut => 3*lambda, cut2 => 4*lambda, ENDCASE => 0 ]; <<-- both layers are distinct>> IF l2=cut2 THEN {l2 _ l1; l1 _ cut2}; IF l1=cut2 THEN { IF IsDiff[dr, l2] THEN RETURN[2*lambda]; IF l2=pol THEN RETURN[2*lambda]; }; <<-- no more cut2 (via)>> IF l1=met OR l2=met THEN RETURN [0]; IF l1=met2 OR l2=met2 THEN RETURN [0]; <<-- no more met or met2>> IF l2=pol THEN {l2 _ l1; l1 _ pol}; IF l1=pol THEN {IF IsDiff[dr, l2] THEN RETURN[lambda] ELSE RETURN[0]}; <<-- no more poly>> IF l2=ndif THEN {l2 _ l1; l1 _ ndif}; IF l1=ndif THEN { RETURN [SELECT l2 FROM pdif => 10*lambda, nwell => 5*lambda, ENDCASE => 0 ]; }; <<-- no more ndif>> IF l2=pdif THEN {l2 _ l1; l1 _ pdif}; IF l1=pdif THEN { RETURN [SELECT l2 FROM pwell => 5*lambda, ENDCASE => 0 ]; }; RETURN [0] }; <<-- Layers are electrically connected>> MinConnectedDist: PUBLIC PROC [dr: DesignRules, l1, l2: CD.Layer] RETURNS [dist: CD.Number] = { OPEN dr; IF l1=nwell OR l2=nwell THEN RETURN [0]; -- good enough for now! IF l1=met OR l2=met THEN RETURN [0]; IF l1=met2 OR l2=met2 THEN RETURN [0]; <<-- no more met or met2>> IF l1=l2 THEN RETURN [0]; <<-- both layers are distinct>> IF l2=cut2 THEN {l2 _ l1; l1 _ cut2}; IF l1=cut2 THEN { -- flatness rules IF IsDiff[dr, l2] THEN RETURN[2*lambda]; IF l2=pol THEN RETURN[2*lambda]; }; <<-- no more cut2 (via)>> IF l2=pol THEN {l2 _ l1; l1 _ pol}; IF l1=pol THEN {IF IsDiff[dr, l2] THEN RETURN[lambda] ELSE RETURN[0]}; -- other than dif? <<-- no more poly>> IF l2=ndif THEN {l2 _ l1; l1 _ ndif}; IF l1=ndif THEN { RETURN [SELECT l2 FROM pdif => 10*lambda, nwell => 5*lambda, ENDCASE => 0 ]; }; <<-- no more ndif>> IF l2=pdif THEN {l2 _ l1; l1 _ pdif}; IF l1=pdif THEN { RETURN [SELECT l2 FROM pwell => 5*lambda, ENDCASE => 0 ]; }; RETURN [0] }; <> GetTechnology: PUBLIC PROC [dr: DesignRules] RETURNS [CD.Technology] ~ { RETURN[dr.techno]; }; <<-- used when laying out a chip in a target technology (also duplicated in StixImpl)>> GetLayer: PUBLIC PROC [technology, layer: REF] RETURNS [CD.Layer] ~ { targetTech: CD.Technology _ NARROW[technology]; color: ATOM _ NARROW[layer]; RETURN [CDSimpleRules.GetLayer[targetTech, color]]; }; <<-- all dimensions in CD units, i.e. the multiplication by lambda has been done>> <<-- zero means default value>> Pin: PUBLIC PROC [size: CD.Position] RETURNS [CD.Object] ~ { RETURN [CDSymbolicObjects.CreatePin[size]]; }; Rect: PUBLIC PROC [size: CD.Position, layer: CD.Layer] RETURNS [CD.Object] ~ { RETURN [CDSimpleRules.Rect[size, layer]]; }; Contact: PUBLIC PROC [dr: DesignRules, l1, l2: CD.Layer, size: CD.Position] RETURNS [CD.Object] = { RETURN [CDSimpleRules.Contact[l1, l2]]; }; <<-- size is [w, l], not the IRect>> Transistor: PUBLIC PROC [dr: DesignRules, difL: CD.Layer, w, l: INT] RETURNS [CD.Object] = { OPEN dr; IF w= 0 THEN w _ standardTrSize.x; IF l= 0 THEN l _ standardTrSize.y; RETURN [CMosBObjects.CreateTransistor[size: [w+2*trPolExt, l+2*trDifExt], difLayer: difL]]; }; <> <<-- Explode the StickPtr into a dummy cells containing only pins>> Explode: PUBLIC PROC [dr: DesignRules, object: CD.Object] RETURNS [dummy: CD.Object] ~ { OPEN dr; dummy _ CDCells.CreateEmptyCell[]; SELECT TRUE FROM IsMosContact[object] => { -- any contact dRects: DRects _ NARROW[object.specificRef, CDAtomicObjects.AtomicObsPtr].rList; FOR l: DRects _ dRects, l.rest WHILE l#NIL DO InsertPin[dummy, "contact", l.first.r, l.first.lev]; ENDLOOP; }; IsWire[object] => { -- any rectangle inLayer: CD.Layer _ InsideLayer[object.layer]; rect: CD.Rect _ CD.InterestRect[object]; surList: LIST OF LayerAndDistance _ NeedSurround[dr, object.layer]; InsertPin[dummy, "wire", rect, inLayer]; IF surList#NIL THEN { rect _ CDBasics.Extend[rect, surList.first.amount]; -- 5 InsertPin[dummy, "wire", rect, surList.first.layer]; -- nWell }; }; IsMosTransistor[object] => { inLayer: CD.Layer _ InsideLayer[object.layer]; dGate: INT _ lambda; -- a hack gate, ch1, ch2: CD.Rect _ CD.InterestRect[object]; -- bouding box of the transistor gate _ [gate.x1, gate.y1+trDifExt, gate.x2, gate.y2-trDifExt]; ch1 _ [ch1.x1+trPolExt, ch1.y1, ch1.x2-trPolExt, ch1.y1+trDifExt-dGate]; ch2 _ [ch2.x1+trPolExt, ch2.y2-trDifExt+dGate, ch2.x2-trPolExt, ch2.y2]; InsertPin[dummy, "gate", gate, pol]; InsertPin[dummy, "ch1", ch1, inLayer]; InsertPin[dummy, "ch2", ch2, inLayer]; }; IsPin[object] => {}; ENDCASE => ERROR; }; <> NeedSurround: PUBLIC PROC [dr: DesignRules, layer: CD.Layer] RETURNS [surList: LIST OF LayerAndDistance] = { OPEN dr; IF layer#wpdif THEN RETURN[NIL]; surList _ LIST[[layer: nwell, amount: 5*lambda]]; }; <> IsDiff: PROC [dr: DesignRules, layer: CD.Layer] RETURNS [BOOL] = {OPEN dr; RETURN[layer=ndif OR layer=pdif OR layer=wndif OR layer=wpdif OR layer=nwellCont OR layer=pwellCont]}; InsideLayer: PROC [layer: CD.Layer] RETURNS [inLayer: CD.Layer] ~ { RETURN [CDLayers.AbstractToPaint[layer]]}; InsertPin: PROC [cell: CD.Object, name: ROPE, rect: CD.Rect, lay: CD.Layer] ~ { pinOb: CD.Object _ CDSymbolicObjects.CreatePin[CDBasics.SizeOfRect[rect]]; pin: CD.Instance _ CDCells.IncludeOb[NIL, cell, pinOb, CDBasics.BaseOfRect[rect], 0, interrestCoords, interrestCoords].newInst; CDSymbolicObjects.SetLayer[pin, lay]; CDSymbolicObjects.SetName[pin, name]; }; <> IsPin: PROC [ob: CD.Object] RETURNS [BOOL] = { RETURN[CDSymbolicObjects.IsSymbolicOb[ob]]}; IsWire: PROC [ob: CD.Object] RETURNS [BOOL] ~ { RETURN[ob.class.wireTyped AND ~ob.class.symbolic]}; IsMosContact: PROC [ob: CD.Object] RETURNS [BOOL] = { RETURN[IsMosViaContact[ob] OR IsMosCutContact[ob]]}; IsMosViaContact: PROC [ob: CD.Object] RETURNS [BOOL] = { RETURN[ob.class=CD.FetchObjectClass[$C2Via, CMosB.cmosB]]}; IsMosCutContact: PROC [ob: CD.Object] RETURNS [BOOL] = { RETURN[ob.class=CD.FetchObjectClass[$C2SimpleCon, CMosB.cmosB] OR ob.class=CD.FetchObjectClass[$C2WellSimpleCon, CMosB.cmosB]]}; IsMosTransistor: PROC [ob: CD.Object] RETURNS [BOOL] = { RETURN[ob.class=CD.FetchObjectClass[$C2Trans, CMosB.cmosB] OR ob.class=CD.FetchObjectClass[$C2WellTrans, CMosB.cmosB]]}; END. << >>