blob: 43c6c26f8afe181c93c1918ef7f2350524bec92e [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
#===============================================
#--------------------PAD------------------------
#===============================================
# Rule PAD.4 : Top layer metal enclose pad opening is 2.0µm
logger.info('Executing rule PAD.4')
pad4_l1 = top_metal.enclosing(pad,2.0.um).polygons(0.001)
pad4_l2 = pad.not_outside(top_metal).not(top_metal)
pad4_l = pad4_l1.or(pad4_l2)
pad4_l.output('PAD.4', 'PAD.4 : Top layer metal enclose pad opening is 2.0µm')
pad4_l1.forget
pad4_l2.forget
pad4_l.forget
# Rule PAD.2 : Pad opening to pad opening is 9.0µm
logger.info('Executing rule PAD.2')
pad2_l1 = pad.space(9.0.um).polygons(0.001)
pad2_l1.output('PAD.2', 'PAD.2 : Pad opening to pad opening is 9.0µm')
pad2_l1.forget
# Rule PAD.5 : Top metal enclose top via is 0.5µm
logger.info('Executing rule PAD.5')
pad5_l1 = top_metal.enclosing(top_via,0.5.um).polygons(0.001)
pad5_l2 = top_via.not_inside(top_metal)
pad5_l = pad5_l1.or(pad5_l2)
pad5_l.output('PAD.5', 'PAD.5 : Top metal enclose top_via is 0.5µm')
pad5_l1.forget
pad5_l2.forget
pad5_l.forget
# Rule PAD.6 : Top metal-1 enclose top via is 0.5µm
logger.info('Executing rule PAD.6')
pad6_l1 = topmin1_metal.enclosing(top_via,0.5.um).polygons(0.001)
pad6_l2 = top_via.not_inside(topmin1_metal)
pad6_l = pad6_l1.or(pad6_l2)
pad6_l.output('PAD.6', 'PAD.6 : Top metal-1 enclose top_via is 0.5µm')
pad6_l1.forget
pad6_l2.forget
pad6_l.forget
# Rule PAD.15 : Min pad opening space to nearest S/L guard ring (Inner edge of GUARD_RING_MK marking) is 30µm
logger.info('Executing rule PAD.15')
pad15_l1 = pad.separation(guard_ring_mk,30.0.um).polygons(0.001)
pad15_l1.output('PAD.15','PAD.15 : Min pad opening space to nearest S/L guard ring (Inner edge of GUARD_RING_MK marking) is 30µm')
pad15_l1.forget
# Rule PAD.16 : Max pad opening space to nearest S/L guard ring (Inner edge of GUARD_RING_MK marking) is 200.0µm
logger.info('Executing rule PAD.16')
pad16_l1 = (pad.not_interacting(pad.separation(guard_ring_mk,200.01.um).polygons)).interacting(CHIP.interacting(guard_ring_mk))
# pad16_l1 = pad.separation(guard_ring_mk,1000.um).polygons(0.001).not_interacting(pad.separation(guard_ring_mk,200.001.um).polygons(0.001))
pad16_l1.output('PAD.16','PAD.16 : Max pad opening space to nearest S/L guard ring (Inner edge of GUARD_RING_MK marking) is 200.0µm')
pad16_l1.forget
# Rule PAD.19b : Pad opening to non-pad circuit Top Metal is 6.0µm
logger.info('Executing rule PAD.19b')
pad19b_l1 = pad.separation(top_metal.not_interacting(pad),6.0.um).polygons(0.001)
pad19b_l1.output('PAD.19b','PAD.19b : Pad opening to non-pad circuit Top Metal is 6.0µm')
pad19b_l1.forget
if METAL_LEVEL == '2LM'
all_mets = metal1.or(metal2)
elsif METAL_LEVEL == '3LM'
all_mets = metal1.or(metal2).or(metal3)
elsif METAL_LEVEL == '4LM'
all_mets = metal1.or(metal2).or(metal3).or(metal4)
elsif METAL_LEVEL == '5LM'
all_mets = metal1.or(metal2).or(metal3).or(metal4).or(metal5)
else
all_mets = metal1.or(metal2).or(metal3).or(metal4).or(metal5).or(top_metal)
end #METAL_LEVEL
# Rule PAD.20 : Pad metal to pad metal space is 5.0µm
logger.info('Executing rule PAD.20')
pad20_l1 = all_mets.interacting(pad).space(5.0.um).polygons(0.001)
pad20_l1.output('PAD.20','PAD.20 : Pad metal to pad metal space is 5.0µm')
pad20_l1.forget
if GOLD == 'true'
# Rule PAD.1_gold : Pad opening is 4.0µm
logger.info('Executing rule PAD.1')
pad1_l1 = pad.width(4.0.um).polygons(0.001)
pad1_l1.output('PAD.1_gold','PAD.1_gold : Pad opening is 4.0µm')
pad1_l1.forget
else
# Rule PAD.1 : Pad opening is 40.0µm
logger.info('Executing rule PAD.1')
pad1_l1 = pad.width(40.0.um).polygons(0.001)
pad1_l1.output('PAD.1','PAD.1 : Pad opening is 40.0µm')
pad1_l1.forget
# Rule PAD.7 : metal5 enclose via4 is 0.5µm
logger.info('Executing rule PAD.7')
pad7_l1 = metal5.enclosing(via4,0.5.um).polygons(0.001)
pad7_l2 = via4.not_inside(metal5)
pad7_l = pad7_l1.or(pad7_l2)
pad7_l.output('PAD.7', 'PAD.7 : metal5 enclose via4 is 0.5µm')
pad7_l1.forget
pad7_l2.forget
pad7_l.forget
# Rule PAD.8 : metal4 enclose via4 is 0.5µm
logger.info('Executing rule PAD.8')
pad8_l1 = metal4.enclosing(via4,0.5.um).polygons(0.001)
pad8_l2 = via4.not_inside(metal4)
pad8_l = pad8_l1.or(pad8_l2)
pad8_l.output('PAD.8', 'PAD.8 : metal4 enclose via4 is 0.5µm')
pad8_l1.forget
pad8_l2.forget
pad8_l.forget
# Rule PAD.9 : metal4 enclose via3 is 0.5µm
logger.info('Executing rule PAD.9')
pad9_l1 = metal4.enclosing(via3,0.5.um).polygons(0.001)
pad9_l2 = via3.not_inside(metal4)
pad9_l = pad9_l1.or(pad9_l2)
pad9_l.output('PAD.9', 'PAD.9 : metal4 enclose via3 is 0.5µm')
pad9_l1.forget
pad9_l2.forget
pad9_l.forget
# Rule PAD.10 : metal3 enclose via3 is 0.5µm
logger.info('Executing rule PAD.10')
pad10_l1 = metal3.enclosing(via3,0.5.um).polygons(0.001)
pad10_l2 = via3.not_inside(metal3)
pad10_l = pad10_l1.or(pad10_l2)
pad10_l.output('PAD.10', 'PAD.10 : metal3 enclose via3 is 0.5µm')
pad10_l1.forget
pad10_l2.forget
pad10_l.forget
# Rule PAD.11 : metal3 enclose via2 is 0.5µm
logger.info('Executing rule PAD.11')
pad11_l1 = metal3.enclosing(via2,0.5.um).polygons(0.001)
pad11_l2 = via2.not_inside(metal3)
pad11_l = pad11_l1.or(pad11_l2)
pad11_l.output('PAD.11', 'PAD.11 : metal3 enclose via2 is 0.5µm')
pad11_l1.forget
pad11_l2.forget
pad11_l.forget
# Rule PAD.12 : metal2 enclose via2 is 0.5µm
logger.info('Executing rule PAD.12')
pad12_l1 = metal2.enclosing(via2,0.5.um).polygons(0.001)
pad12_l2 = via2.not_inside(metal2)
pad12_l = pad12_l1.or(pad12_l2)
pad12_l.output('PAD.12', 'PAD.12 : metal2 enclose via2 is 0.5µm')
pad12_l1.forget
pad12_l2.forget
pad12_l.forget
# Rule PAD.13 : metal2 enclose via1 is 0.5µm
logger.info('Executing rule PAD.13')
pad13_l1 = metal2.enclosing(via1,0.5.um).polygons(0.001)
pad13_l2 = via1.not_inside(metal2)
pad13_l = pad13_l1.or(pad13_l2)
pad13_l.output('PAD.13', 'PAD.13 : metal2 enclose via1 is 0.5µm')
pad13_l1.forget
pad13_l2.forget
pad13_l.forget
# Rule PAD.14 : metal1 enclose via1 is 0.5µm
logger.info('Executing rule PAD.14')
pad14_l1 = metal1.enclosing(via1,0.5.um).polygons(0.001)
pad14_l2 = via1.not_inside(metal1)
pad14_l = pad14_l1.or(pad14_l2)
pad14_l.output('PAD.14', 'PAD.14 : metal1 enclose via1 is 0.5µm')
pad14_l1.forget
pad14_l2.forget
pad14_l.forget
end #GOLD
if WEDGE == 'true'
# Rule PAD.17 : Pad opening space to active circuit COMP is 15µm
logger.info('Executing rule PAD.17')
pad17_l1 = pad.separation(comp,15.0.um).polygons(0.001)
pad17_l1.output('PAD.17','PAD.17 : Pad opening space to active circuit COMP is 15µm')
pad17_l1.forget
# Rule PAD.18 : Pad opening space to active circuit poly2 is 15µm
logger.info('Executing rule PAD.18')
pad18_l1 = pad.separation(poly2,15.0.um).polygons(0.001)
pad18_l1.output('PAD.18','PAD.18 : Pad opening space to active circuit poly2 is 15µm')
pad18_l1.forget
met_19a = all_mets.not(top_metal)
# Rule PAD.19a : Pad opening to non-pad circuit Metal1, 2, 3, 4,5 up to Top Metal - 1 is 6µm
logger.info('Executing rule PAD.19')
pad19a_l1 = pad.separation(met_19a.not_interacting(pad),6.0.um).polygons(0.001)
pad19a_l1.output('PAD.19a','PAD.19a : Pad opening to non-pad circuit Metal1, 2, 3, 4,5 up to Top Metal - 1 is 6µm')
pad19a_l1.forget
end #WEDGE
end #BEOL