blob: 0eff1aeace53c33bf1171790075e57d655e9162c [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 BEOL
if METAL_LEVEL == '3LM' || METAL_LEVEL == '4LM' || METAL_LEVEL == '5LM' || METAL_LEVEL == '6LM'
#================================================
#----------------------VIA2----------------------
#================================================
# Rule V2.1: Min/max Via2 size . is 0.26µm
logger.info('Executing rule V2.1')
v2_1_l1 = via2.edges.without_length(0.26.um).extended(0, 0, 0.001, 0.001)
v2_1_l1.output('V2.1', 'V2.1 : Min/max Via2 size . : 0.26µm')
v2_1_l1.forget
# Rule V2.2: min. via2 spacing is 0.26µm
logger.info('Executing rule V2.2')
v2_2_l1 = via2.space(0.26.um, euclidian).polygons(0.001)
v2_2_l1.output('V2.2', 'V2.2 : min. via2 spacing : 0.26µm')
v2_2_l1.forget
# Rule V2.3a: metal2 overlap of via2. is 0.01um
logger.info('Executing rule V2.3a')
v2_3a_l1 = metal2.enclosing(via2, 0.01.um, euclidian).polygons(0.001).or(via2.not(metal2))
v2_3a_l1.output('V2.3a', 'V2.3a : metal2 overlap of via2. : 0.01um')
v2_3a_l1.forget
v2_3b_cond = metal2.drc( width <= 0.34.um).with_length(0.28.um,nil,both)
v2_3b_eol = metal2.edges.with_length(nil, 0.34.um).interacting(v2_3b_cond.first_edges).interacting(v2_3b_cond.second_edges).not(v2_3b_cond.first_edges).not(v2_3b_cond.second_edges)
# Rule V2.3b: metal2 (< 0.34um) end-of-line overlap. is 0.06µm
logger.info('Executing rule V2.3b')
v2_3b_l1 = v2_3b_eol.enclosing(via2.edges,0.06.um, projection).polygons(0.001)
v2_3b_l1.output('V2.3b', 'V2.3b : metal2 (< 0.34um) end-of-line overlap. : 0.06µm')
v2_3b_l1.forget
v2_3b_cond.forget
v2_3b_eol.forget
v2_3c_1 = via2.edges.interacting(via2.drc(enclosed(metal2, projection) < 0.04.um).edges.centers(0, 0.5))
v2_3c_2 = via2.edges.interacting(via2.drc(0.04.um <= enclosed(metal2, projection) < 0.06.um).centers(0, 0.5))
v2_3c_3 = v2_3c_1.extended(0, 0, 0, 0.001, joined).corners(90)
# Rule V2.3c: If metal2 overlap via2 by < 0.04um on one side, adjacent metal2 edges overlap. is 0.06µm
logger.info('Executing rule V2.3c')
v2_3c_l1 = v2_3c_2.not_in(v2_3c_1).interacting(v2_3c_1).or(v2_3c_1.interacting(v2_3c_3)).enclosed(metal2.edges, 0.06.um).polygons(0.001)
v2_3c_l1.output('V2.3c', 'V2.3c : If metal2 overlap via2 by < 0.04um on one side, adjacent metal2 edges overlap. : 0.06µm')
v2_3c_l1.forget
v2_3c_1.forget
v2_3c_2.forget
v2_3c_3.forget
# rule V2.3e is not a DRC check
# Rule V2.4a: metal3 overlap of via2. is 0.01um
logger.info('Executing rule V2.4a')
v2_4a_l1 = metal3.enclosing(via2, 0.01.um, euclidian).polygons(0.001)
v2_4a_l2 = via2.interacting(metal3).not(metal3)
v2_4a_l = v2_4a_l1.join(v2_4a_l2)
v2_4a_l.output('V2.4a', 'V2.4a : metal3 overlap of via2. : 0.01um')
v2_4a_l1.forget
v2_4a_l2.forget
v2_4a_l.forget
v2_4b_cond = metal3.drc( width <= 0.34.um).with_length(0.28.um,nil,both)
v2_4b_eol = metal3.edges.with_length(nil, 0.34.um).interacting(v2_4b_cond.first_edges).interacting(v2_4b_cond.second_edges).not(v2_4b_cond.first_edges).not(v2_4b_cond.second_edges)
# Rule V2.4b: metal3 (< 0.34um) end-of-line overlap. is 0.06µm
logger.info('Executing rule V2.4b')
v2_4b_l1 = v2_4b_eol.enclosing(via2.edges,0.06.um, projection).polygons(0.001)
v2_4b_l1.output('V2.4b', 'V2.4b : metal3 (< 0.34um) end-of-line overlap. : 0.06µm')
v2_4b_l1.forget
v2_4b_cond.forget
v2_4b_eol.forget
v2_4c_1 = via2.edges.interacting(via2.drc(enclosed(metal3, projection) < 0.04.um).edges.centers(0, 0.5))
v2_4c_2 = via2.edges.interacting(via2.drc(0.04.um <= enclosed(metal3, projection) < 0.06.um).centers(0, 0.5))
v2_4c_3 = v2_4c_1.extended(0, 0, 0, 0.001, joined).corners(90)
# Rule V2.4c: If metal3 overlap via2 by < 0.04um on one side, adjacent metal3 edges overlap. is 0.06µm
logger.info('Executing rule V2.4c')
v2_4c_l1 = v2_4c_2.not_in(v2_4c_1).interacting(v2_4c_1).or(v2_4c_1.interacting(v2_4c_3)).enclosed(metal3.edges, 0.06.um).polygons(0.001)
v2_4c_l1.output('V2.4c', 'V2.4c : If metal3 overlap via2 by < 0.04um on one side, adjacent metal3 edges overlap. : 0.06µm')
v2_4c_l1.forget
v2_4c_1.forget
v2_4c_2.forget
v2_4c_3.forget
# rule V2.4d is not a DRC check
# rule V2.5 is not a DRC check
end #METAL_LEVEL
end #BEOL