blob: 7cb63f4c9575bbcec83b0e2ffd5d29d9194ee5fa [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
#================================================
#----------------------ESD-----------------------
#================================================
# Rule ESD.1: Minimum width of an ESD implant area. is 0.6µm
logger.info('Executing rule ESD.1')
esd1_l1 = esd.width(0.6.um, euclidian).polygons(0.001)
esd1_l1.output('ESD.1', 'ESD.1 : Minimum width of an ESD implant area. : 0.6µm')
esd1_l1.forget
# Rule ESD.2: Minimum space between two ESD implant areas. (Merge if the space is less than 0.6um). is 0.6µm
logger.info('Executing rule ESD.2')
esd2_l1 = esd.space(0.6.um, euclidian).polygons(0.001)
esd2_l1.output('ESD.2', 'ESD.2 : Minimum space between two ESD implant areas. (Merge if the space is less than 0.6um). : 0.6µm')
esd2_l1.forget
# Rule ESD.3a: Minimum space to NCOMP. is 0.6µm
logger.info('Executing rule ESD.3a')
esd3a_l1 = esd.separation(ncomp, 0.6.um, euclidian).polygons(0.001)
esd3a_l1.output('ESD.3a', 'ESD.3a : Minimum space to NCOMP. : 0.6µm')
esd3a_l1.forget
# Rule ESD.3b: Min/max space to a butted PCOMP.
logger.info('Executing rule ESD.3b')
esd3b_l1 = esd.not_outside(pcomp)
esd3b_l1.output('ESD.3b', 'ESD.3b : Min/max space to a butted PCOMP.')
esd3b_l1.forget
# Rule ESD.4a: Extension beyond NCOMP. is 0.24µm
logger.info('Executing rule ESD.4a')
esd4a_l1 = esd.edges.not_interacting(pcomp).enclosing(ncomp.edges, 0.24.um, euclidian).polygons(0.001)
esd4a_l1.output('ESD.4a', 'ESD.4a : Extension beyond NCOMP. : 0.24µm')
esd4a_l1.forget
# Rule ESD.4b: Minimum overlap of an ESD implant edge to a COMP. is 0.45µm
logger.info('Executing rule ESD.4b')
esd4b_l1 = esd.overlap(comp, 0.45.um, euclidian).polygons(0.001)
esd4b_l1.output('ESD.4b', 'ESD.4b : Minimum overlap of an ESD implant edge to a COMP. : 0.45µm')
esd4b_l1.forget
# Rule ESD.5a: Minimum ESD area (um2). is 0.49µm²
logger.info('Executing rule ESD.5a')
esd5a_l1 = esd.with_area(nil, 0.49.um)
esd5a_l1.output('ESD.5a', 'ESD.5a : Minimum ESD area (um2). : 0.49µm²')
esd5a_l1.forget
# Rule ESD.5b: Minimum field area enclosed by ESD implant (um2). is 0.49µm²
logger.info('Executing rule ESD.5b')
esd5b_l1 = esd.holes.with_area(nil, 0.49.um)
esd5b_l1.output('ESD.5b', 'ESD.5b : Minimum field area enclosed by ESD implant (um2). : 0.49µm²')
esd5b_l1.forget
# Rule ESD.6: Extension perpendicular to Poly2 gate. is 0.45µm
logger.info('Executing rule ESD.6')
esd6_l1 = esd.edges.enclosing(poly2.edges.interacting(tgate.edges), 0.45.um, projection).polygons(0.001)
esd6_l1.output('ESD.6', 'ESD.6 : Extension perpendicular to Poly2 gate. : 0.45µm')
esd6_l1.forget
# Rule ESD.7: No ESD implant inside PCOMP.
logger.info('Executing rule ESD.7')
esd7_l1 = esd.not_outside(pcomp)
esd7_l1.output('ESD.7', 'ESD.7 : No ESD implant inside PCOMP.')
esd7_l1.forget
# Rule ESD.8: Minimum space to Nplus/Pplus. is 0.3µm
logger.info('Executing rule ESD.8')
esd8_l1 = esd.separation(nplus.or(pplus), 0.3.um).polygons
esd8_l1.output('ESD.8', 'ESD.8 : Minimum space to Nplus/Pplus. : 0.3µm')
esd8_l1.forget
# Rule ESD.PL_LV: Minimum gate length of 3.3V gate NMOS# is 0.4µm
logger.info('Executing rule ESD.PL_LV')
esdpl_l1 = poly2.interacting(esd).edges.and(tgate.edges).width(0.4.um, euclidian).polygons(0.001).overlapping(dualgate)
esdpl_l1.output('ESD.PL_LV', 'ESD.PL_LV : Minimum gate length of 3.3V gate NMOS#. : 0.4µm')
esdpl_l1.forget
# Rule ESD.PL_MV: Minimum gate length of 5/6V gate NMOS* is 0.8um
logger.info('Executing rule ESD.PL_MV')
esdpl_l1 = poly2.interacting(esd).edges.and(tgate.edges).width(0.8.um, euclidian).polygons(0.001).overlapping(dualgate_2)
esdpl_l1.output('ESD.PL_MV', 'ESD.PL_MV : Minimum gate length of 5/6V gate NMOS*. : 0.8µm')
esdpl_l1.forget
# Rule ESD.9: ESD implant layer must be overlapped by DV2 or Dualgate layer (as ESD implant option is only for 5/6V and 3.3V) devices)
logger.info('Executing rule ESD.9')
esd9_l1 = esd.not_overlapping(dualgate.or(dualgate_2))
esd9_l1.output('ESD.9', 'ESD.9 : ESD implant layer must be overlapped by DV2 or Dualgate layer (as ESD implant option is only for 5/6V and 3.3V) devices)')
esd9_l1.forget
# Rule ESD.10: LVS_IO shall be drawn covering I/O MOS active area by minimum overlap.
logger.info('Executing rule ESD.10')
esd10_l1 = comp.and(esd).not_outside(lvs_io).not(lvs_io)
esd10_l1.output('ESD.10', 'ESD.10 : LVS_IO shall be drawn covering I/O MOS active area by minimum overlap.')
esd10_l1.forget
end #FEOL