blob: df026bb79d735c71a7fecda2760689fe3c246701 [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
#================================================
#----------------------VIA1----------------------
#================================================
# Rule V1.1: Min/max Via1 size . is 0.26µm
logger.info('Executing rule V1.1')
v11_l1 = via1.edges.without_length(0.26.um)
v11_l1.output('V1.1', 'V1.1 : Min/max Via1 size . : 0.26µm')
v11_l1.forget
# Rule V1.2: min. via1 spacing is 0.26µm
logger.info('Executing rule V1.2')
v12a_l1 = via1.space(0.26.um, euclidian).polygons(0.001)
v12a_l1.output('V1.2', 'V1.2 : min. via1 spacing : 0.26µm')
v12a_l1.forget
v1p3a_cond = metal1.drc(width <= 0.34.um).with_length(0.28.um,nil,both).edges.interacting(metal1.corners(90))
v1p3a_m = metal1.edges.interacting(v1p3a_cond)
# Rule V1.3a : Min. Metal1 enclose Via1 [Metal1 with width <0.34um, Protrusion >=0.28um] is 0.06
v1p3a_l1 = v1p3a_m.enclosing(via1.edges,0.06.um,square).polygons(0.001).or(via1.not_outside(metal1).not(metal1))
v1p3a_l1.output('V1.3a','V1.3a: Min. Metal1 enclose Via1 [Metal1 with width <0.34um, Protrusion >=0.28um] is 0.06')
v1p3a_cond.forget
v1p3a_m.forget
v1p3a_l1.forget
v1p3a_l1.forget
v1p3b_ed_s1 = via1.edges.not(metal1.edges).interacting(via1.edges.and(metal1.edges))
v1p3b_ed_s2 = via1.drc(0.0.um < enclosed(metal1, projection) < 0.04.um)
# Rule V1.3b : Min. Metal1 enclose Via1 by sides (a, b, c, d) is (0,0.06,0,0.06) or (0.04,0.04,0.04,0.04)
v1p3b_l1 = metal1.edges.enclosing(v1p3b_ed_s1,0.06.um,projection).polygons(0.001)
v1p3b_l2 = metal1.edges.enclosing(v1p3b_ed_s2,0.04.um).polygons(0.001)
v1p3b_l3 = (v1p3b_l1.or(v1p3b_l2)).or(via1.not_outside(metal1).not(metal1))
v1p3b_l3.output('V1.3b','V1.3b : Min. Metal1 enclose Via1 by sides (a, b, c, d) is (0,0.06,0,0.06) or (0.04,0.04,0.04,0.04)')
v1p3b_ed_s1.forget
v1p3b_ed_s2.forget
v1p3b_l1.forget
v1p3b_l2.forget
v1p3b_l3.forget
# rule V1.3d is not a DRC check
v1p4a_cond = (metal2.drc(width <= 0.34.um).with_length(0.28.um,nil,both).edges.interacting(metal2.corners(90)))
v1p4a_m = metal2.edges.interacting(v1p4a_cond)
# Rule V1.4a : Min. Metal2 enclose Via1 [Metal2 with width <0.34um, Protrusion >=0.28um] is 0.06
v1p4a_l1 = v1p4a_m.enclosing(via1.edges,0.06.um,square).polygons(0.001).or(via1.not_outside(metal2).not(metal2))
v1p4a_l1.output('V1.4a','V1.4a : Min. Metal2 enclose Via1 [Metal2 with width <0.34um, Protrusion >=0.28um] is 0.06 ')
v1p4a_cond.forget
v1p4a_m.forget
v1p4a_l1.forget
v1p4b_ed_s1 = via1.edges.not(metal2.edges).interacting(via1.edges.and(metal2.edges))
v1p4b_ed_s2 = via1.drc(0.0.um < enclosed(metal2, projection) < 0.04.um)
# Rule V1.4b : Min. Metal2 enclose Via1 by sides (a, b, c, d) is (0,0.06,0,0.06) or (0.04,0.04,0.04,0.04)
v1p4b_l1 = metal2.edges.enclosing(v1p4b_ed_s1,0.06.um,projection).polygons(0.001)
v1p4b_l2 = metal2.edges.enclosing(v1p4b_ed_s2,0.04.um).polygons(0.001)
v1p4b_l3 = (v1p4b_l1.or(v1p4b_l2)).or(via1.not_outside(metal2).not(metal2))
v1p4b_l3.output('V1.4b','V1.4b : Min. Metal2 enclose Via1 by sides (a, b, c, d) is (0,0.06,0,0.06) or (0.04,0.04,0.04,0.04)')
v1p4b_ed_s1.forget
v1p4b_ed_s2.forget
v1p4b_l1.forget
v1p4b_l2.forget
v1p4b_l3.forget
# rule V1.4c is not a DRC check
end #BEOL