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