blob: 338098a71246fb2cc4878989f3b27b984b4c06d4 [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 --------------------------
#==================================================
if GOLD == 'true'
# Rule PAD.1_gold : Pad opening is 4.0µm
logger.info('Executing rule PAD.1_gold')
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.3a : MetalTop enclose Via5 is 0.5µm
logger.info('Executing rule PAD.3a')
pad3a_l1 = top_metal.enclosing(via5,0.5.um).polygons(0.001)
pad3a_l1.output('PAD.3a','PAD.3a : MetalTop enclose Via5 is 0.5µm')
pad3a_l1.forget
# Rule PAD.3b : Metal5 enclose Via5 is 0.5µm
logger.info('Executing rule PAD.3b')
pad3b_l1 = metal5.enclosing(via5,0.5.um).polygons(0.001)
pad3b_l1.output('PAD.3b','PAD.3b : Metal5 enclose Via5 is 0.5µm')
pad3b_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_l1.output('PAD.7', 'PAD.7 : metal5 enclose via4 is 0.5µm')
pad7_l1.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_l1.output('PAD.8', 'PAD.8 : metal4 enclose via4 is 0.5µm')
pad8_l1.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_l1.output('PAD.9', 'PAD.9 : metal4 enclose via3 is 0.5µm')
pad9_l1.forget
# Rule PAD.10 : metal4 enclose via3 is 0.5µm
logger.info('Executing rule PAD.10')
pad10_l1 = metal3.enclosing(via3,0.5.um).polygons(0.001)
pad10_l1.output('PAD.10', 'PAD.10 : metal3 enclose via3 is 0.5µm')
pad10_l1.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_l1.output('PAD.11', 'PAD.11 : metal3 enclose via2 is 0.5µm')
pad11_l1.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_l1.output('PAD.12', 'PAD.12 : metal2 enclose via2 is 0.5µm')
pad12_l1.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_l1.output('PAD.13', 'PAD.13 : metal2 enclose via1 is 0.5µm')
pad13_l1.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_l1.output('PAD.14', 'PAD.14 : metal1 enclose via1 is 0.5µm')
pad14_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.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
end
# 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.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_l1.output('PAD.4', 'PAD.4 : Top layer metal enclose pad opening is 2.0µm')
pad4_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_l1.output('PAD.5', 'PAD.5 : Top metal enclose top_via is 0.5µm')
pad5_l1.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_l1.output('PAD.6', 'PAD.6 : Top metal-1 enclose top_via is 0.5µm')
pad6_l1.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.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 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
end #BEOL