| ################################################################################################ |
| # 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 |