blob: c9594be46e1e834644741a6d3e96a838e8cc92df [file] [log] [blame]
################################################################################################
# Copyright 2022 GlobalFoundries PDK Authors
#
# Licensed under the Apache License, Version 2.0 (the 'License');
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an 'AS IS' BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
################################################################################################
if FEOL
#================================================
#----------------P+ POLY RESISTOR----------------
#================================================
pres_poly = poly2.and(pplus).interacting(sab).interacting(res_mk).not_interacting(resistor)
# Rule PRES.1: Minimum width of Poly2 resistor. is 0.8µm
logger.info('Executing rule PRES.1')
pres1_l1 = pres_poly.width(0.8.um, euclidian).polygons(0.001)
pres1_l1.output('PRES.1', 'PRES.1 : Minimum width of Poly2 resistor. : 0.8µm')
pres1_l1.forget
# Rule PRES.2: Minimum space between Poly2 resistors. is 0.4µm
logger.info('Executing rule PRES.2')
pres2_l1 = pres_poly.isolated(0.4.um, euclidian).polygons(0.001)
pres2_l1.output('PRES.2', 'PRES.2 : Minimum space between Poly2 resistors. : 0.4µm')
pres2_l1.forget
# Rule PRES.3: Minimum space from Poly2 resistor to COMP. is 0.6um.
logger.info('Executing rule PRES.3')
pres3_l1 = pres_poly.separation(comp, 0.6.um, euclidian).polygons(0.001).or(comp.not_outside(pres_poly))
pres3_l1.output('PRES.3', 'PRES.3 : Minimum space from Poly2 resistor to COMP.')
pres3_l1.forget
# Rule PRES.4: Minimum space from Poly2 resistor to unrelated Poly2. is 0.6µm
logger.info('Executing rule PRES.4')
pres4_l1 = pres_poly.separation(poly2.not_interacting(sab), 0.6.um, euclidian).polygons(0.001)
pres4_l1.output('PRES.4', 'PRES.4 : Minimum space from Poly2 resistor to unrelated Poly2. : 0.6µm')
pres4_l1.forget
# Rule PRES.5: Minimum Plus implant overlap of Poly2 resistor. is 0.3µm
logger.info('Executing rule PRES.5')
pres5_l1 = pplus.enclosing(pres_poly, 0.3.um, euclidian).polygons(0.001)
pres5_l2 = pres_poly.not_outside(pplus).not(pplus)
pres5_l = pres5_l1.or(pres5_l2)
pres5_l.output('PRES.5', 'PRES.5 : Minimum Plus implant overlap of Poly2 resistor. : 0.3µm')
pres5_l1.forget
pres5_l2.forget
pres5_l.forget
# Rule PRES.6: Minimum salicide block overlap of Poly2 resistor in width direction. is 0.3µm
logger.info('Executing rule PRES.6')
pres6_l1 = sab.enclosing(pres_poly,0.3.um).polygons(0.001)
pres6_l1.output('PRES.6', 'PRES.6 : Minimum salicide block overlap of Poly2 resistor in width direction. : 0.3µm')
pres6_l1.forget
# Rule PRES.7: Space from salicide block to contact on Poly2 resistor.
logger.info('Executing rule PRES.7')
pres7_l1 = contact.inside(pres_poly).separation(sab,0.22.um).polygons(0.001).or(contact.inside(pres_poly).interacting(sab))
pres7_l1.output('PRES.7', 'PRES.7 : Space from salicide block to contact on Poly2 resistor.')
pres7_l1.forget
# rule PRES.8 is not a DRC check
mk_pres9a = res_mk.edges.not(poly2.and(pplus).and(sab).edges).inside_part(poly2)
# Rule PRES.9a: Pplus Poly2 resistor shall be covered by RES_MK marking. RES_MK length shall be coincide with resistor length (Defined by SAB length) and width covering the width of Poly2.
logger.info('Executing rule PRES.9a')
pres9a_l1 = res_mk.interacting(pres_poly).interacting(mk_pres9a)
pres9a_l1.output('PRES.9a', 'PRES.9a : Pplus Poly2 resistor shall be covered by RES_MK marking. RES_MK length shall be coincide with resistor length (Defined by SAB length) and width covering the width of Poly2.')
pres9a_l1.forget
mk_pres9a.forget
# Rule PRES.9b: If the size of single RES_MK mark layer is greater than 15000um2
## and both side (X and Y) are greater than 80um.
## then the minimum spacing to adjacent RES_MK layer. is 20µm
logger.info('Executing rule PRES.9b')
pres9b = res_mk.with_area(15_000.001.um, nil).edges.with_length(80.001.um, nil)
pres9b_l1 = pres9b.separation(res_mk.edges, 20.um)
pres9b_l1.output('PRES.9b',
'PRES.9b : If the size of single RES_MK mark layer is greater than 15000um2
and both side (X and Y) are greater than 80um.
then the minimum spacing to adjacent RES_MK layer. : 20µm')
pres9b_l1.forget
pres9b.forget
pres_poly.forget
end #FEOL