blob: 0aad2fc6c95f9e3560246742f4562fab47579ba5 [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 overlap of 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_inside(top_metal)
pad4_l = pad4_l1.or(pad4_l2)
pad4_l.output('PAD.4', 'PAD.4 : Top layer metal overlap of pad opening is 2.0µm')
pad4_l1.forget
pad4_l2.forget
pad4_l.forget
# Rule PAD.1 : Pad opening is 50.0µm (assembly house rules)
logger.info('Executing rule PAD.1')
pad1_l1 = pad.width(50.0.um).polygons(0.001)
pad1_l1.output('PAD.1','PAD.1 : Pad opening is 50.0µm (assembly house rules)')
pad1_l1.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
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.3 : Only MetalTop is allowed underneath bond pad opening
logger.info('Executing rule PAD.3')
pad3_l1 = all_mets.not(top_metal).interacting(pad)
pad3_l1.output('PAD.3','PAD.3 : Only TopMetal is allowed underneath bond pad opening ')
pad3_l1.forget
if METAL_LEVEL == '6LM'
# Rule PAD.5 : MetalTop overlap of Via5 is 0.5µm
logger.info('Executing rule PAD.5')
pad5_l1 = top_metal.enclosing(via5,0.5.um).polygons(0.001)
pad5_l2 = via5.not_inside(top_metal)
pad5_l = pad5_l1.or(pad5_l2)
pad5_l.output('PAD.5','PAD.5 : MetalTop overlap of Via5 is 0.5µm')
pad5_l1.forget
pad5_l2.forget
pad5_l.forget
# Rule PAD.6 : Metal5 overlap of Via5 is 0.5µm
logger.info('Executing rule PAD.6')
pad6_l1 = metal5.enclosing(via5,0.5.um).polygons(0.001)
pad6_l2 = via5.not_inside(metal5)
pad6_l = pad6_l1.or(pad6_l2)
pad6_l.output('PAD.6','PAD.6 : Metal5 overlap of Via5 is 0.5µm')
pad6_l1.forget
pad6_l2.forget
pad6_l.forget
end #METAL_LEVEL
if METAL_LEVEL == '5LM' || METAL_LEVEL == '6LM'
# Rule PAD.7 : Metal5 overlap of 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 overlap of Via4 is 0.5µm')
pad7_l1.forget
pad7_l2.forget
pad7_l.forget
# Rule PAD.8 : Metal4 overlap of 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 overlap of Via4 is 0.5µm')
pad8_l1.forget
pad8_l2.forget
pad8_l.forget
end #METAL_LEVEL
if METAL_LEVEL == '4LM' || METAL_LEVEL == '5LM' || METAL_LEVEL == '6LM'
# Rule PAD.9 : Metal4 overlap of 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 overlap of Via3 is 0.5µm')
pad9_l1.forget
pad9_l2.forget
pad9_l.forget
# Rule PAD.10 : Metal3 overlap of Via 3is 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 overlap of Via3 is 0.5µm')
pad10_l1.forget
pad10_l2.forget
pad10_l.forget
end #METAL_LEVEL
if METAL_LEVEL == '3LM' || METAL_LEVEL == '4LM' || METAL_LEVEL == '5LM' || METAL_LEVEL == '6LM'
# Rule PAD.11 : Metal3 overlap of 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 overlap of Via2 is 0.5µm')
pad11_l1.forget
pad11_l2.forget
pad11_l.forget
# Rule PAD.12 : Metal2 overlap of 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 overlap of Via2 is 0.5µm')
pad12_l1.forget
pad12_l2.forget
pad12_l.forget
end #METAL_LEVEL
# Rule PAD.13 : Metal2 overlap of 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 overlap of Via1 is 0.5µm')
pad13_l1.forget
pad13_l2.forget
pad13_l.forget
# Rule PAD.14 : Metal1 overlap of 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 overlap of Via1 is 0.5µm')
pad14_l1.forget
pad14_l2.forget
pad14_l.forget
# Rule PAD.15 : Min pad opening space to nearest S/L guard ring 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 is 30µm')
pad15_l1.forget
# Rule PAD.16 : Max pad opening space to nearest S/L guard ring 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 is 200.0µm')
pad16_l1.forget
# Rule PAD.17 : Pad opening space to active 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 is 15µm')
pad17_l1.forget
# Rule PAD.18 : Pad opening space to poly 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 poly is 15µm')
pad18_l1.forget
# Rule PAD.19 : Pad opening to non-pad metal 1, 2, 3, 4, 5 and MetalTop is 6µm
logger.info('Executing rule PAD.19')
pad19_l1 = pad.separation(all_mets.not_interacting(pad),6.0.um).polygons(0.001)
pad19_l1.output('PAD.19','PAD.19 : Pad opening to non-pad metal 1, 2, 3, 4, 5 and MetalTop is 6µm')
pad19_l1.forget
# 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
end #BEOL