| ################################################################################################ |
| # 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 |