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]; }; 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 ]; 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]; }; IF l1=met OR l2=met THEN RETURN [0]; IF l1=met2 OR l2=met2 THEN RETURN [0]; IF l2=pol THEN {l2 _ l1; l1 _ pol}; IF l1=pol THEN {IF IsDiff[dr, l2] THEN RETURN[lambda] ELSE RETURN[0]}; IF l2=ndif THEN {l2 _ l1; l1 _ ndif}; IF l1=ndif THEN { RETURN [SELECT l2 FROM pdif => 10*lambda, nwell => 5*lambda, ENDCASE => 0 ]; }; IF l2=pdif THEN {l2 _ l1; l1 _ pdif}; IF l1=pdif THEN { RETURN [SELECT l2 FROM pwell => 5*lambda, ENDCASE => 0 ]; }; RETURN [0] }; 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]; IF l1=l2 THEN RETURN [0]; 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]; }; 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? IF l2=ndif THEN {l2 _ l1; l1 _ ndif}; IF l1=ndif THEN { RETURN [SELECT l2 FROM pdif => 10*lambda, nwell => 5*lambda, ENDCASE => 0 ]; }; 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]; }; GetLayer: PUBLIC PROC [technology, layer: REF] RETURNS [CD.Layer] ~ { targetTech: CD.Technology _ NARROW[technology]; color: ATOM _ NARROW[layer]; RETURN [CDSimpleRules.GetLayer[targetTech, color]]; }; 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]]; }; 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: 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 l 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. tCDDesignRulesImpl.mesa Copyright c 1985 by Xerox Corporation. All rights reserved. Louis Monier December 3, 1985 2:33:53 pm PST -- Add the rules for difContact! Design Rules Distance rules -- Layers are electrically non-connected -- both layers are distinct -- no more cut2 (via) -- no more met or met2 -- no more poly -- no more ndif -- Layers are electrically connected -- no more met or met2 -- both layers are distinct -- no more cut2 (via) -- no more poly -- no more ndif Object generators -- used when laying out a chip in a target technology (also duplicated in StixImpl) -- all dimensions in CD units, i.e. the multiplication by lambda has been done -- zero means default value -- size is [w, l], not the IRect Getting information on the inside -- Explode the StickPtr into a dummy cells containing only pins Well surround rules Private procs Decomposition in pins Κ :˜šœ™Icodešœ Οmœ1™Kšœ žœžœ $˜XKšœžœ˜ šœžœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ%˜%Kšœ˜Kšœ˜Kšœ ˜ Kšœ ˜ Kšœ"˜"Kšœ ˜ Kšœ"˜"Kšœžœ˜&Kšœ"˜"Kšœ"˜"Kšœ$˜$Kšœ$˜$Kšœ#˜#Kšœ#˜#Kšœ+˜+Kšœ*˜*Kšœ˜—K˜——š‘™š ’œž œžœžœžœ ˜VKšœ%˜%K˜—KšœΠbiœ ™(š ’œž œžœžœžœ ˜VKšžœ˜Kš žœ žœ žœžœ ˜5Kš žœ žœ žœžœ  ˜4šžœžœ˜šžœžœž˜Kšœ˜Kšœ˜Kšœ˜Kšœ!˜!Kšœ˜Kšœ˜Kšœ˜Kšžœ˜ K˜——K™Kšžœ žœ˜%šžœ žœ˜Kšžœžœžœ ˜(Kšžœžœžœ ˜ Kšœ˜—K™Kšžœžœžœžœ˜$Kšžœ žœ žœžœ˜&K™Kšžœžœ˜#Kšžœžœžœžœžœ žœžœ˜GK™Kšžœ žœ˜%šžœ žœ˜šžœžœž˜Kšœ˜Kšœ˜Kšžœ˜ K˜—Kšœ˜—K™Kšžœ žœ˜%šžœ žœ˜šžœžœž˜Kšœ˜Kšžœ˜ K˜—Kšœ˜—Kšžœ˜ K˜K˜—KšœΟb ™$š ’œž œžœžœžœ ˜_Kšžœ˜Kš žœ žœ žœžœ ˜@Kšžœžœžœžœ˜$Kšžœ žœ žœžœ˜&K™Kšžœžœžœ˜K™Kšžœ žœ˜%šžœ žœ ˜&Kšžœžœžœ ˜(Kšžœžœžœ ˜ Kšœ˜—K™Kšžœžœ˜#Kšžœžœžœžœžœ žœžœ ˜YK™Kšžœ žœ˜%šžœ žœ˜šžœžœž˜Kšœ˜Kšœ˜Kšžœ˜ K˜—Kšœ˜—K™Kšžœ žœ˜%šžœ žœ˜šžœžœž˜Kšœ˜Kšžœ˜ K˜—Kšœ˜—Kšžœ˜ K˜——š‘™š’ œž œžœžœ˜HKšžœ ˜K˜——˜K™Sš ’œžœžœžœžœžœ ˜EKšœ žœžœ ˜/Kšœžœžœ˜Kšžœ-˜3K˜—K˜K™NK™š ’œžœžœžœ žœžœ ˜=Kšžœ%˜+K˜—š’œžœžœžœžœžœžœ ˜OKšžœ#˜)K˜—š’œžœžœžœžœ žœžœ ˜cKšžœ!˜'K˜—Kšœ ™ š ’ œž œžœžœžœžœ ˜\Kšžœ˜Kšžœžœ˜"Kšžœžœ˜"KšžœU˜[K˜——š‘!™!Kšœ?™?š ’œž œžœ žœ žœ ˜XKšžœ˜Kšœ"˜"šžœžœž˜šœ ˜)Kšœžœ9˜Pšžœžœžœž˜-Kšœ4˜4Kšžœ˜—K˜—šœ ˜$Kšœ žœ#˜.Kšœžœžœ˜(Kšœ žœžœ4˜DKšœ(˜(šžœ žœžœ˜Kšœ4 Πcg˜:Kšœ5 ˜=K˜—Kšœ˜—šœ˜Kšœ žœ#˜.Kšœžœ   ˜Kšœžœžœ  ˜TKšœ>˜>KšœH˜HKšœH˜HKšœ$˜$Kšœ&˜&Kšœ&˜&Kšœ˜—Kšœ˜Kšžœžœ˜—K˜——š‘™š ’ œž œžœžœ žœžœ˜lKšžœ˜Kšžœ žœžœžœ˜ Kšœ žœ#˜1K˜——š‘ ™ š ’œžœžœžœžœ˜@Kšœžœ˜ Kš žœ žœ žœ žœ žœžœ˜f—K˜š ’ œžœ žœžœ žœ ˜CKšžœ$˜*—K˜š ’ œžœžœžœžœ žœ ˜OKšœžœA˜JKšœžœžœW˜Kšœ%˜%Kšœ%˜%K˜——šœ™K˜š ’œžœžœ žœžœ˜.Kšžœ&˜,—š ’œžœžœ žœžœ˜/Kšžœžœ˜3—š ’ œžœžœ žœžœ˜5Kšžœžœ˜4—š ’œžœžœ žœžœ˜8Kšžœ žœ)˜;—š ’œžœžœ žœžœ˜8šžœ žœ-˜?Kšžœ žœ3˜A——š ’œžœžœ žœžœ˜8šžœ žœ)˜;Kšœ žœ/˜=———J˜Kšžœ˜K™—…—ž)L