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