blob: a415028fff11b092014b9c2855e830aaa930b4e4 [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
#================================================
#----------------------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