| ################################################################################################ |
| # 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 |
| |
| #================================================ |
| #----------------------COMP---------------------- |
| #================================================ |
| |
| # Rule FATAL.ERROR: Nplus can’t overlap with pplus |
| logger.info('Executing rule FATAL.ERROR') |
| fatalerror_l1 = nplus.and(pplus) |
| fatalerror_l1.output('FATAL.ERROR', 'FATAL.ERROR : Nplus can’t overlap with pplus') |
| fatalerror_l1.forget |
| |
| # Rule DF.1a: Min. COMP Width. is 0.22µm |
| logger.info('Executing rule DF.1a') |
| df1a_l1 = comp.width(0.22.um, euclidian).polygons(0.001) |
| df1a_l1.output('DF.1a', 'DF.1a : Min. COMP Width. : 0.22µm') |
| df1a_l1.forget |
| |
| # rule DF.1b is not a DRC check |
| |
| df_2 = comp.not(poly2).edges.and(tgate.edges) |
| # Rule DF.2: Min Channel Width. is nil,0.22µm |
| logger.info('Executing rule DF.2') |
| df2_l1 = df_2.with_length(nil,0.22.um).extended(0, 0, 0.001, 0.001) |
| df2_l1.output('DF.2', 'DF.2 : Min Channel Width. : nil,0.22µm') |
| df2_l1.forget |
| df_2.forget |
| |
| # Rule DF.3a: Min. COMP Space P-substrate tap (PCOMP outside NWELL and DNWELL) can be butted for different voltage devices as the potential is same. is 0.28µm |
| logger.info('Executing rule DF.3a') |
| df3a_l1 = comp.outside(sramcore).space(0.28.um, euclidian).polygons(0.001) |
| df3a_l1.output('DF.3a', 'DF.3a : Min. COMP Space P-substrate tap (PCOMP outside NWELL and DNWELL) can be butted for different voltage devices as the potential is same. : 0.28µm') |
| df3a_l1.forget |
| |
| # Rule DF.3b: Min./Max. NCOMP Space to PCOMP in the same well for butted COMP. |
| logger.info('Executing rule DF.3b') |
| df3b_l1 = ncomp.inside(nwell).not_outside(pcomp.inside(nwell)).or(ncomp.not_outside(pcomp)) |
| df3b_l1.output('DF.3b', 'DF.3b : Min./Max. NCOMP Space to PCOMP in the same well for butted COMP.') |
| df3b_l1.forget |
| |
| # Rule DF.4: Min. Nwell overlap of NCOMP. is 0.12µm |
| logger.info('Executing rule DF.4') |
| df4d_l1 = nwell.enclosing(ncomp, 0.12.um, euclidian).polygons(0.001) |
| df4d_l2 = ncomp.not_outside(nwell).not(nwell) |
| df4d_l = df4d_l1.or(df4d_l2) |
| df4d_l.output('DF.4', 'DF.4 : Min. Nwell overlap of NCOMP. : 0.12µm') |
| df4d_l1.forget |
| df4d_l2.forget |
| df4d_l.forget |
| |
| pcomp_df5 = pcomp.outside(nwell) |
| # Rule DF.5: Min. space from Nwell to PCOMP well tap. is 0.12µm |
| logger.info('Executing rule DF.5') |
| df5_l1 = pcomp_df5.separation(nwell, 0.12.um, euclidian).polygons(0.001) |
| df5_l1.output('DF.5', 'DF.5 : Min. space from Nwell to PCOMP well tap. : 0.12µm') |
| df5_l1.forget |
| |
| # Rule DF.6: Min. COMP extend beyond gate (it also means source/drain overhang). is 0.24µm |
| logger.info('Executing rule DF.6') |
| df6_l1 = comp.enclosing(poly2, 0.24.um, euclidian).polygons(0.001) |
| df6_l1.output('DF.6', 'DF.6 : Min. COMP extend beyond gate (it also means source/drain overhang). : 0.24µm') |
| df6_l1.forget |
| |
| # Rule DF.7: Min. Nwell overlap of PCOMP inside NWELL. is 0.43µm |
| logger.info('Executing rule DF.7') |
| df4c_l1 = nwell.outside(sramcore).enclosing(pcomp.inside(nwell), 0.43.um, euclidian).polygons(0.001) |
| df4c_l2 = pcomp.inside(nwell).not_outside(nwell.outside(sramcore)).not(nwell.outside(sramcore)) |
| df4c_l = df4c_l1.or(df4c_l2) |
| df4c_l.output('DF.7', 'DF.7 : Min. Nwell overlap of PCOMP inside NWELL. is 0.43µm') |
| df4c_l1.forget |
| df4c_l2.forget |
| df4c_l.forget |
| |
| # Rule DF.8: Min. space from Nwell to NCOMP outside Nwell. is 0.43µm |
| logger.info('Executing rule DF.8') |
| df8_l1 = ncomp.outside(nwell).outside(sramcore).separation(nwell, 0.43.um, euclidian).polygons(0.001) |
| df8_l1.output('DF.8', 'DF.8 : Min. space from (Nwell outside DNWELL) to (NCOMP outside Nwell and DNWELL). : 0.43µm') |
| df8_l1.forget |
| |
| # Rule DF.9: Min. COMP area (um2). is 0.2025µm² |
| logger.info('Executing rule DF.9') |
| df9_l1 = comp.with_area(nil, 0.2025.um) |
| df9_l1.output('DF.9', 'DF.9 : Min. COMP area (um2). : 0.2025µm²') |
| df9_l1.forget |
| |
| # Rule DF.10: Min. field area (um2). is 0.26µm² |
| logger.info('Executing rule DF.10') |
| df10_l1 = comp.holes.not(comp).with_area(nil, 0.26.um) |
| df10_l1.output('DF.10', 'DF.10 : Min. field area (um2). : 0.26µm²') |
| df10_l1.forget |
| |
| comp_butt = comp.interacting(ncomp.interacting(pcomp).outside(pcomp)) |
| # Rule DF.11: Min. Length of butting COMP edge. is 0.3µm |
| logger.info('Executing rule DF.11') |
| df11_l1 = comp_butt.width(0.3.um, euclidian).polygons(0.001) |
| df11_l1.output('DF.11', 'DF.11 : Min. Length of butting COMP edge. : 0.3µm') |
| df11_l1.forget |
| |
| comp_butt.forget |
| |
| # Rule DF.12: COMP not covered by Nplus or Pplus is forbidden. |
| logger.info('Executing rule DF.12') |
| df12_l1 = comp.not(nplus.or(pplus)) |
| df12_l1.output('DF.12', 'DF.12 : COMP not covered by Nplus or Pplus is forbidden.') |
| df12_l1.forget |
| |
| end #FEOL |