blob: 99e7d3c07f6411f7a09febd7f658e898c1f07b0e [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
#================================================
#----------------------SAB-----------------------
#================================================
# Rule SB.1: min. sab width is 0.43µm
logger.info('Executing rule SB.1')
sb1_l1 = sab.width(0.43.um, euclidian).polygons(0.001)
sb1_l1.output('SB.1', 'SB.1 : min. sab width : 0.42µm')
sb1_l1.forget
# Rule SB.2: min. sab spacing outside ELMD2_MK is 0.43µm
logger.info('Executing rule SB.2')
sb2_l1 = sab.outside(elmd2_mk).space(0.43.um, euclidian).polygons(0.001)
sb2_l1.output('SB.2', 'SB.2 : min. sab spacing outside ELMD2_MK : 0.43µm')
sb2_l1.forget
# Rule SB.3: Space from salicide block to unrelated COMP except under ESD_HBM_MK , interact MOS_MK_TYPE4 is 0.22µm
logger.info('Executing rule SB.3')
sb3_l1 = sab.outside(comp).outside(esd_hbm_mk).interacting(mos_mk_type4).separation(comp.outside(sab), 0.22.um, euclidian).polygons(0.001)
sb3_l1.output('SB.3', 'SB.3 : Space from salicide block to unrelated COMP except under ESD_HBM_MK , interact MOS_MK_TYPE4 : 0.22µm')
sb3_l1.forget
# Rule SB.4: Space from salicide block to contact outside ELMD2_MK is 0.22um
logger.info('Executing rule SB.4')
sb4_l1 = sab.outside(elmd2_mk).separation(contact, 0.22.um, euclidian).polygons(0.001).or(sab.and(contact))
sb4_l1.output('SB.4', 'SB.4 : Space from salicide block to contact outside ELMD2_MK : 0.22um')
sb4_l1.forget
# Rule SB.5a: Space from salicide block to unrelated Poly2 on field. is 0.3µm
logger.info('Executing rule SB.5a')
sb5a_l1 = sab.outside(poly2.not(comp)).separation(poly2.not(comp).outside(sab), 0.3.um, euclidian).polygons(0.001)
sb5a_l1.output('SB.5a', 'SB.5a : Space from salicide block to unrelated Poly2 on field. : 0.3µm')
sb5a_l1.forget
# Rule SB.5b: Space from salicide block to unrelated Poly2 on COMP. is 0.4µm
logger.info('Executing rule SB.5b')
sb5b_l1 = sab.outside(tgate).separation(tgate.outside(sab), 0.4.um, euclidian).polygons(0.001)
sb5b_l1.output('SB.5b', 'SB.5b : Space from salicide block to unrelated Poly2 on COMP. : 0.4µm')
sb5b_l1.forget
# Rule SB.6: Salicide block extension beyond related COMP. is 0.22µm
logger.info('Executing rule SB.6')
sb6_l1 = sab.enclosing(comp, 0.22.um, euclidian).polygons(0.001)
sb6_l1.output('SB.6', 'SB.6 : Salicide block extension beyond related COMP. : 0.22µm')
sb6_l1.forget
# Rule SB.7: COMP extension beyond related salicide block. is 0.22µm
logger.info('Executing rule SB.7')
sb7_l1 = comp.enclosing(sab, 0.22.um, euclidian).polygons
sb7_l1.output('SB.7', 'SB.7 : COMP extension beyond related salicide block. : 0.22µm')
sb7_l1.forget
# Rule SB.8: Non-salicided contacts are forbidden.
logger.info('Executing rule SB.8')
sb8_l1 = contact.inside(sab)
sb8_l1.output('SB.8', 'SB.8 : Non-salicided contacts are forbidden.')
sb8_l1.forget
# Rule SB.9: Salicide block extension beyond unsalicided Poly2. is 0.22µm
logger.info('Executing rule SB.9')
sb9_l1 = poly2.and(sab).enclosed(sab, 0.22.um, euclidian).polygons
sb9_l1.output('SB.9', 'SB.9 : Salicide block extension beyond unsalicided Poly2. : 0.22µm')
sb9_l1.forget
# Rule SB.10: Poly2 extension beyond related salicide block except under ESD_HBM_MK , interact MOS_MK_TYPE4 is 0.22µm
logger.info('Executing rule SB.10')
sb10_l1 = poly2.enclosing(sab.outside(esd_hbm_mk).interacting(mos_mk_type4) , 0.22.um, euclidian).polygons(0.001)
sb10_l1.output('SB.10', 'SB.10 : Poly2 extension beyond related salicide block except under ESD_HBM_MK , interact MOS_MK_TYPE4 : 0.22µm')
sb10_l1.forget
# Rule SB.11: Min SAB enclose with COMP. is 0.22µm
logger.info('Executing rule SB.11')
sb11_l1 = sab.overlap(comp, 0.22.um, euclidian).polygons
sb11_l1.output('SB.11', 'SB.11 : Min SAB enclose with COMP. : 0.22µm')
sb11_l1.forget
# Rule SB.12: Overlap with Poly2 outside esd_hbm_mk. is 0.22µm
logger.info('Executing rule SB.12')
sb12_l1 = sab.outside(esd_hbm_mk).overlap(poly2.outside(esd_hbm_mk), 0.22.um, euclidian).polygons
sb12_l1.output('SB.12', 'SB.12 : Overlap with Poly2 outside esd_hbm_mk. : 0.22µm')
sb12_l1.forget
# Rule SB.13: Min. area (um2). is 2µm²
logger.info('Executing rule SB.13')
sb13_l1 = sab.with_area(nil, 2.um)
sb13_l1.output('SB.13', 'SB.13 : Min. area (um2). : 2µm²')
sb13_l1.forget
# Rule SB.14a: Space from unsalicided Nplus Poly2 to unsalicided Pplus Poly2. (Unsalicided Nplus Poly2 must not fall within a square of 0.56um x 0.56um at unsalicided Pplus Poly2 corners). is 0.56µm
logger.info('Executing rule SB.14a')
sb14a_l1 = poly2.and(nplus).and(sab).separation(poly2.and(pplus).and(sab), 0.56.um, square).polygons
sb14a_l1.output('SB.14a', 'SB.14a : Space from unsalicided Nplus Poly2 to unsalicided Pplus Poly2. (Unsalicided Nplus Poly2 must not fall within a square of 0.56um x 0.56um at unsalicided Pplus Poly2 corners). : 0.56µm')
sb14a_l1.forget
# Rule SB.14b: Space from unsalicided Nplus Poly2 to P-channel gate.
## (Unsalicided Nplus Poly2 must not fall within a square of 0.56um x 0.56um
## at P-channel gate corners). is 0.56µm
logger.info('Executing rule SB.14b')
sb14b_l1 = poly2.and(sab).and(nplus).separation(pgate, 0.56.um, square)
sb14b_l1.output('SB.14b', "SB.14b : Space from unsalicided Nplus Poly2 to P-channel gate.
(Unsalicided Nplus Poly2 must not fall within a square of 0.56um x 0.56um
at P-channel gate corners). : 0.56µm")
sb14b_l1.forget
# Rule SB.15a: Space from unsalicided Poly2 to unrelated Nplus/Pplus. is 0.18µm
logger.info('Executing rule SB.15a')
sb15a_l1 = poly2.and(sab).separation(nplus.or(pplus), 0.18.um, euclidian).polygons(0.001)
sb15a_l1.output('SB.15a', 'SB.15a : Space from unsalicided Poly2 to unrelated Nplus/Pplus. : 0.18µm')
sb15a_l1.forget
# Rule SB.15b: Space from unsalicided Poly2 to unrelated Nplus/Pplus along Poly2 line is 0.32 um
logger.info('Executing rule SB.15b')
sb15b_np = nplus.or(pplus).interacting(poly2.interacting(poly2.and(sab)))
sb15b_poly = poly2.overlapping(sb15b_np).and(poly2.and(sab))
sb15b_l1 = sb15b_poly.separation(sb15b_np, 0.32.um, euclidian)
sb15b_l1.output('SB.15b', 'SB.15b : Space from unsalicided Poly2 to unrelated Nplus/Pplus. : 0.32µm')
sb15b_l1.forget
sb15b_np.forget
sb15b_poly.forget
# Rule SB.16: SAB layer cannot exist on 1.8V,6V and 30V CMOS transistors' active area
## of the core circuit (Excluding the transistors used for ESD purpose). It can only exist on CMOS transistors
## marked by LVS_IO, OTP_MK, ELMD_MK, ELMD2_MK, DNI, ESD_HBM_MK layers.
logger.info('Executing rule SB.16')
sb16_exclude = sab.outside(otp_mk.or(lvs_io).or(esd_hbm_mk))
sb16_l1 = sb16_exclude.interacting(tgate)
sb16_l1.output('SB.16', "SB.16 : SAB layer cannot exist on 3.3V and 5V/6V CMOS transistors'
Poly and COMP area of the core circuit (Excluding the transistors used for ESD purpose).
It can only exist on CMOS transistors marked by LVS_IO, OTP_MK, ESD_MK layers.")
sb16_l1.forget
sb16_exclude.forget
sb_pl2 = poly2.and(sab).not_interacting(diode_mk)
# Rule SB.17a : Min Nplus enclosure (pol2 AND SAB) is 0.1 µm
sb17a_l1 = sb_pl2.enclosed(nplus,0.1.um).polygons(0.001)
sb17a_l2 = sb_pl2.not_outside(nplus).not(nplus)
sb17a = sb17a_l1.or(sb17a_l2)
sb17a.output('SB.17a','SB.17a : Min Nplus enclosure (pol2 AND SAB) is 0.1 µm')
sb_pl2.forget
sb17a_l1.forget
sb17a_l2.forget
sb17a.forget
sb_comp = comp.and(sab)
# Rule SB.17b : Minimum Nplus enclosure (NCOMP AND SAB) is 0.1 µm
sb17b_l1 = (nplus.interacting(sb_comp)).enclosing(sb_comp,0.1.um).polygons(0.001)
sb17b_l2 = sb_comp.not_inside(nplus.interacting(sb_comp))
sb17b = sb17b_l1.or(sb17b_l2)
sb17b.output('SB.17b','SB.17b : Minimum Nplus enclosure (NCOMP AND SAB) is 0.1 µm')
sb_comp.forget
sb17b_l1.forget
sb17b_l2.forget
sb17b.forget
end #FEOL