blob: 959c45d67f81e84dcc10cde471bd437807619c46 [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 ESD width 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 ESD width : 0.6µm')
esd1_l1.forget
# Rule ESD.2: Minimum ESD space (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 ESD space. (Merge if the space is less than 0.6um). : 0.6µm')
esd2_l1.forget
# Rule ESD.3a: Minimum ESD 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 ESD space to NCOMP. : 0.6µm')
esd3a_l1.forget
# Rule ESD.3b: Min/max space to a butted PCOMP is 0um.
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: 0um.')
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(ncomp).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 NCOMP is 0.45µm
logger.info('Executing rule ESD.4b')
esd4b_l1 = esd.overlap(ncomp, 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 ESD hole (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 beyond Poly2 gate. is 0.45µm
logger.info('Executing rule ESD.6')
esd6_l1 = esd.edges.not_interacting(tgate).enclosing(poly2.edges.interacting(tgate.edges), 0.45.um, projection).polygons(0.001)
esd6_l1.output('ESD.6', 'ESD.6 : Extension beyond 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: Minimum gate length of MV gate NMOS. is 0.8µm
logger.info('Executing rule ESD.pl')
esdpl_l1 = poly2.interacting(esd).edges.and(tgate.edges).width(0.8.um, euclidian).polygons(0.001).overlapping(dualgate2_d)
esdpl_l1.output('ESD.pl', 'ESD.pl : Minimum gate length of MV gate NMOS. : 0.8µm')
esdpl_l1.forget
# Rule ESD.9: ESD implant layer must be overlapped by dualgate2_d layer (as ESD implant option is only for MV devices).
logger.info('Executing rule ESD.9')
esd9_l1 = esd.not_inside(dualgate2_d)
esd9_l1.output('ESD.9', 'ESD.9 : ESD implant layer must be enclosed by dualgate2_d layer (as ESD implant option is only for MV devices).')
esd9_l1.forget
# Rule ESD.10: LVS_IO shall be drawn covering I/O MOS active area by minimum overlap except under ESD_HBM_MK layer.
logger.info('Executing rule ESD.10')
esd10_l1 = comp.and(esd).not_interacting(esd_hbm_mk).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