| ################################################################################################ |
| # 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 FEOL |
| |
| #================================================ |
| #-----------------SRAM CORE CELLS---------------- |
| #================================================ |
| |
| # Rule S.DF.1a: Minimum COMP width inside SramCore AND OPC_drc marking layers is 0.02 µm |
| logger.info('Executing rule S.DF.1a') |
| s_df_1a = comp.inside(sramcore).inside(opc_drc).width(0.02.um).polygons(0.001) |
| s_df_1a.output('S.DF.1a','S.DF.1a: Minimum COMP width inside SramCore AND OPC_drc marking layers is 0.02 µm') |
| |
| s_df_1a.forget |
| |
| # Rule S.DF.3a.i : Space between COMP inside SRAM is 0.26 µm |
| logger.info('Executing rule S.DF.3a.i') |
| s_df_3ai = comp.inside(sramcore).outside(opc_drc).space(0.26.um).polygons(0.001) |
| s_df_3ai.output('S.DF.3a.i','S.DF.3a.i : Space between COMP inside SRAM is 0.26 µm') |
| |
| s_df_3ai.forget |
| |
| # Rule S.DF.3a.ii : Space between COMP (inside SramCore making) to COMP (outside SramCore marking) is 0.28µm |
| logger.info('Executing rule S.DF.3a.ii') |
| s_df_3aii = comp.inside(sramcore).separation(comp.outside(sramcore),0.28.um).polygons(0.001) |
| s_df_3aii.output('S.DF.3a.ii', 'S.DF.3a.ii : Space between COMP (inside SramCore making) to COMP (outside SramCore marking) is 0.28µm') |
| |
| s_df_3aii.forget |
| |
| # Rule S.DF.3a.iii : Space between COMP inside SramCore AND OPC_drc marking layers is 0.02µm |
| logger.info('Executing rule S.DF.3a.iii') |
| s_df_3aiii = comp.inside(sramcore).inside(opc_drc).space(0.02.um).polygons(0.001) |
| s_df_3aiii.output('S.DF.3a.iii','S.DF.3a.iii : Space between COMP inside SramCore AND OPC_drc marking layers is 0.02µm') |
| |
| s_df_3aiii.forget |
| |
| # Rule S.DF.4c : Nwell overlap of PCOMP inside Nwell is 0.25µm |
| logger.info('Executing rule S.DF.4c') |
| s_df_4a = nwell.inside(sramcore).enclosing(pcomp.inside(sramcore),0.25.um).polygons(0.001) |
| s_df_4a.output('S.DF.4c','S.DF.4c : Nwell overlap of PCOMP inside Nwell is 0.25µm') |
| |
| s_df_4a.forget |
| |
| # Rule S.DF.6 : Extension beyond gate or source/drain overhang inside SramCore AND OPC_drc marking layers is 0.03µm |
| logger.info('Executing rule S.DF.6') |
| s_df_6 = comp.interacting(poly2).inside(sramcore).inside(opc_drc).enclosing(poly2.inside(sramcore).inside(opc_drc),0.03.um).polygons(0.001) |
| s_df_6.output('S.DF.6','S.DF.6 : Extension beyond gate or source/drain overhang inside SramCore AND OPC_drc marking layers is 0.03µm') |
| |
| s_df_6.forget |
| |
| # Rule S.DF.7 : Space from LVPWELL to PCOMP inside DNWELL is 0.25µm |
| logger.info('Executing rule S.DF.7') |
| s_df_7 = pcomp.inside(dnwell).inside(sramcore).separation(lvpwell.inside(dnwell).inside(sramcore),0.25.um).polygons(0.001) |
| s_df_7.output('S.DF.7','S.DF.7 : Space from LVPWELL to PCOMP inside DNWELL is 0.25µm') |
| |
| s_df_7.forget |
| |
| # Rule S.DF.8 : LVPWELL overlap of NCOMP inside LVPWELL is 0.355 µm |
| logger.info('Executing rule S.DF.8') |
| s_df_8_l1 = lvpwell.inside(sramcore).enclosing(ncomp.inside(sramcore),0.355.um).polygons(0.001) |
| s_df_8_l2 = ncomp.inside(sramcore).interacting(lvpwell.inside(sramcore)).not_inside(lvpwell.inside(sramcore)) |
| s_df_8 = s_df_8_l1.or(s_df_8_l2) |
| s_df_8.output('S.DF.8','S.DF.8 : LVPWELL overlap of NCOMP inside LVPWELL is 0.355 µm') |
| |
| s_df_8_l1.forget |
| s_df_8_l2.forget |
| s_df_8.forget |
| |
| # Rule S.PL.1i : Poly2 interconnect width in parallel direction is 0.18 µm |
| logger.info('Executing rule S.PL.1i') |
| s_pl_1i = poly2.inside(sramcore).outside(opc_drc).width(0.18.um, projection) |
| s_pl_1i.output('S.PL.1i','S.PL.1i : Poly2 interconnect width in parallel direction is 0.18 µm') |
| |
| s_pl_1i.forget |
| |
| # Rule S.PL.1ii : Inside SramCore AND OPC_drc marking layers, Poly2 interconnect width in parallel direction is 0.05µm |
| logger.info('Executing rule S.PL.1ii') |
| s_pl_1ii = poly2.inside(sramcore).inside(opc_drc).width(0.05.um, projection) |
| s_pl_1ii.output('S.PL.1ii','S.PL.1ii : Inside SramCore AND OPC_drc marking layers, Poly2 interconnect width in parallel direction is 0.05µm') |
| |
| s_pl_1ii.forget |
| |
| # Rule S.PL.3a.ii : Poly2 to Poly2 space on field (Poly2 width < 0.5) is 0.19µm |
| logger.info('Executing rule S.PL.3a.ii') |
| s_pl_3aii = poly2.not(comp).inside(sramcore).outside(opc_drc).width(0.5.um).polygons(0.0001).space(0.19.um).polygons(0.0001) |
| s_pl_3aii.output('S.PL.3a.ii','S.PL.3a.ii : Poly2 to Poly2 space on field (Poly2 width < 0.5) is 0.19µm') |
| |
| s_pl_3aii.forget |
| |
| # Rule S.PL.3a.iii : Poly2 (inside SramCore making) to Poly2 (outside SramCore making) space on field is 0.25µm |
| logger.info('Executing rule S.PL.3a.iii') |
| s_pl_3aiii = poly2.not(comp).inside(sramcore).separation(poly2.not(comp).outside(sramcore),0.25.um).polygons(0.001) |
| s_pl_3aiii.output('S.PL.3a.iii','S.PL.3a.iii : Poly2 (inside SramCore making) to Poly2 (outside SramCore making) space on field is 0.25µm') |
| |
| s_df_3aiii.forget |
| |
| # Rule S.PL.3a.iv : Inside SramCore AND OPC_drc marking layers, Poly2 to Poly2 space on field (Poly2 width < 0.5) is 0.03µm |
| logger.info('Executing rule S.PL.3a.iv') |
| s_pl_3aiv = poly2.not(comp).inside(sramcore).inside(opc_drc).width(0.5.um).polygons(0.0001).space(0.03.um).polygons(0.0001) |
| s_pl_3aiv.output('S.PL.3a.iv','S.PL.3a.iv : Inside SramCore AND OPC_drc marking layers, Poly2 to Poly2 space on field (Poly2 width < 0.5) is 0.03µm') |
| |
| s_pl_3aiv.forget |
| |
| # Rule S.PL.4 : Poly2 end cap (width parallel to COMP) is 0.22µm |
| logger.info('Executing rule S.PL.4') |
| s_pl_4 = poly2.inside(sramcore).outside(opc_drc).enclosing(comp.interacting(poly2).inside(sramcore).outside(opc_drc),0.22.um,projection) |
| s_pl_4.output('S.PL.4','S.PL.4 : Poly2 end cap (width parallel to COMP) is 0.22µm') |
| |
| s_pl_4.forget |
| |
| # Rule S.PL.4i : Min width of chopped end cap (parallel to channel length direction) is 0.10µm |
| logger.info('Executing rule S.PL.4i') |
| s_pl_4i = poly2.inside(sramcore).interacting(comp).edges.not_interacting(comp).interacting(poly2.edges.interacting(comp)).with_length(nil,0.1) |
| s_pl_4i.output('S.PL.4i','S.PL.4i : Min width of chopped end cap (parallel to channel length direction) is 0.10µm') |
| |
| s_pl_4i.forget |
| |
| # Rule S.PL.4ii : Inside SramCore AND OPC_drc marking layers, Poly2 end cap (width parallel to COMP) is 0.03µm |
| logger.info('Executing rule S.PL.4ii') |
| s_pl_4ii = poly2.inside(sramcore).inside(opc_drc).enclosing(comp.interacting(poly2).inside(sramcore).inside(opc_drc),0.03.um,projection) |
| s_pl_4ii.output('S.PL.4ii','S.PL.4ii : Inside SramCore AND OPC_drc marking layers, Poly2 end cap (width parallel to COMP) is 0.03µm') |
| |
| s_pl_4ii.forget |
| |
| # Rule S.PL.5b: Space from field Poly2 to related COMP. is 0.04µm |
| logger.info('Executing rule S.PL.5b') |
| s_pl5b_l1 = poly2.inside(sramcore).separation(comp, 0.04.um, euclidian).polygons(0.001) |
| s_pl5b_l1.output('S.PL.5b', 'S.PL.5b : Space from field Poly2 to related COMP. : 0.04µm') |
| s_pl5b_l1.forget |
| |
| # Rule S.NP.12: Overlap with P-channel poly2 gate extension is forbidden within 0.25um of P-channel gate. |
| logger.info('Executing rule S.NP.12') |
| s_np12_l1 = nplus.inside(sramcore).interacting(nplus.inside(sramcore).edges.separation(pgate.edges.and(pcomp.edges), 0.25.um, euclidian).polygons(0.001)) |
| s_np12_l1.output('S.NP.12', 'S.NP.12 : Overlap with P-channel poly2 gate extension is forbidden within 0.25um of P-channel gate.') |
| s_np12_l1.forget |
| |
| # Rule S.CO.1 : Min contact width in parallel direction is 0.21 um |
| logger.info('Executing rule S.CO.1') |
| s_co1_l1 = contact.inside(sramcore).width(0.21.um, projection) |
| s_co1_l1.output('S.CO.1','S.CO.1 : Min contact width in parallel direction is 0.21 um ') |
| s_co1_l1.forget |
| |
| # Rule S.CO.1i: Min. contact area (um2). is 0.0483µm² |
| logger.info('Executing rule S.CO.1i') |
| s_co_1i_l1 = contact.inside(sramcore).with_area(nil, 0.0483.um) |
| s_co_1i_l1.output('S.CO.1i', 'S.CO.1i : Min. contact area (um2). : 0.0483µm²') |
| s_co_1i_l1.forget |
| |
| # Rule S.CO.1ii: Max. contact area (um2). is 0.0638µm² |
| logger.info('Executing rule S.CO.1ii') |
| s_co_1ii_l1 = contact.inside(sramcore).with_area(0.06381 .um, nil) |
| s_co_1ii_l1.output('S.CO.1ii', 'S.CO.1ii : Max. contact area (um2). : 0.0638µm²') |
| s_co_1ii_l1.forget |
| |
| # Rule S.CO.2a : Contact to Contact space inside SramCore marking is 0.21µm |
| logger.info('Executing rule S.CO.2a') |
| s_co_2a = contact.inside(sramcore).space(0.21.um).polygons(0.001) |
| s_co_2a.output('S.CO.2a','S.CO.2a : Contact to Contact space inside SramCore marking is 0.21µm') |
| |
| s_co_2a.forget |
| |
| # Rule S.CO.3: Poly2 overlap of contact. is 0µm |
| logger.info('Executing rule S.CO.3') |
| s_co3_l = contact.inside(sramcore).interacting(poly2).not(poly2) |
| s_co3_l.output('S.CO.3', 'S.CO.3 : Poly2 overlap of contact. : 0µm') |
| s_co3_l.forget |
| |
| s_co3i_1 = contact.inside(sramcore).outside(opc_drc).edges.interacting(contact.drc(enclosed(poly2, projection) < 0.06.um).edges.centers(0, 0.5)) |
| s_co3i_2 = contact.inside(sramcore).outside(opc_drc).edges.interacting(contact.drc(0.04.um <= enclosed(poly2, projection) < 0.06.um).centers(0, 0.5)) |
| s_co3i_3 = s_co3i_1.extended(0, 0, 0, 0.001, joined).corners(90) |
| # Rule S.CO.3i: If Poly2 enclose of contact by < 0.06um on one side, adjacent Poly2 edges’ overlap is 0.06µm |
| logger.info('Executing rule S.CO.3i') |
| s_co3i_l1 = s_co3i_2.not_in(s_co3i_1).interacting(s_co3i_1).or(s_co3i_1.interacting(s_co3i_3)).enclosed(poly2.inside(sramcore).outside(opc_drc).edges, 0.06.um).polygons(0.001) |
| s_co3i_l1.output('S.CO.3i', 'S.CO.3i : If Poly2 enclose of contact by < 0.06um on one side, adjacent Poly2 edges’ overlap : 0.06µm') |
| s_co3i_l1.forget |
| s_co3i_1.forget |
| s_co3i_2.forget |
| s_co3i_3.forget |
| |
| s_co3ii_1 = contact.inside(sramcore).inside(opc_drc).edges.interacting(contact.drc(enclosed(poly2, projection) < 0.01.um).edges.centers(0, 0.5)) |
| s_co3ii_2 = contact.inside(sramcore).inside(opc_drc).edges.interacting(contact.drc(0.01.um <= enclosed(poly2, projection) < 0.06.um).centers(0, 0.5)) |
| s_co3ii_3 = s_co3ii_1.extended(0, 0, 0, 0.001, joined).corners(90) |
| # Rule S.CO.3ii: Inside SramCore AND OPC_drc If Poly2 enclose of contact by < 0.06um on one side, adjacent Poly2 edges’ overlap is 0.01µm |
| logger.info('Executing rule S.CO.3ii') |
| s_co3ii_l1 = s_co3ii_2.not_in(s_co3ii_1).interacting(s_co3ii_1).or(s_co3ii_1.interacting(s_co3ii_3)).enclosed(poly2.inside(sramcore).inside(opc_drc).edges, 0.06.um).polygons(0.001) |
| s_co3ii_l1.output('S.CO.3ii', 'S.CO.3ii : If Poly2 enclose of contact by < 0.06um on one side, adjacent Poly2 edges’ overlap : 0.01µm') |
| s_co3ii_l1.forget |
| s_co3ii_1.forget |
| s_co3ii_2.forget |
| s_co3ii_3.forget |
| |
| # Rule S.CO.4: COMP overlap of contact. is 0µm |
| logger.info('Executing rule S.CO.4') |
| s_co4_l = contact.inside(sramcore).interacting(comp).not(comp) |
| s_co4_l.output('S.CO.4', 'S.CO.4 : COMP overlap of contact. : 0µm') |
| s_co4_l.forget |
| |
| s_co4i_1 = contact.inside(sramcore).outside(opc_drc).edges.interacting(contact.drc(enclosed(comp, projection) < 0.06.um).edges.centers(0, 0.5)) |
| s_co4i_2 = contact.inside(sramcore).outside(opc_drc).edges.interacting(contact.drc(0.04.um <= enclosed(comp, projection) < 0.06.um).centers(0, 0.5)) |
| s_co4i_3 = s_co4i_1.extended(0, 0, 0, 0.001, joined).corners(90) |
| # Rule S.CO.4i: If COMP enclose contact by < 0.06um on one side, adjacent COMP edges’ overlap is 0.06µm |
| logger.info('Executing rule S.CO.4i') |
| s_co4i_l1 = s_co4i_2.not_in(s_co4i_1).interacting(s_co4i_1).or(s_co4i_1.interacting(s_co4i_3)).enclosed(comp.inside(sramcore).outside(opc_drc).edges, 0.06.um).polygons(0.001) |
| s_co4i_l1.output('S.CO.4i', 'S.CO.4i : If COMP enclose contact by < 0.06um on one side, adjacent COMP edges’ overlap : 0.06µm') |
| s_co4i_l1.forget |
| s_co4i_1.forget |
| s_co4i_2.forget |
| s_co4i_3.forget |
| |
| s_co4ii_1 = contact.inside(sramcore).inside(opc_drc).edges.interacting(contact.drc(enclosed(comp, projection) < 0.01.um).edges.centers(0, 0.5)) |
| s_co4ii_2 = contact.inside(sramcore).inside(opc_drc).edges.interacting(contact.drc(0.01.um <= enclosed(comp, projection) < 0.06.um).centers(0, 0.5)) |
| s_co4ii_3 = s_co4ii_1.extended(0, 0, 0, 0.001, joined).corners(90) |
| # Rule S.CO.4ii: Inside SramCore AND OPC_drc marking layers, If COMP enclose contact by < 0.06um on one side, adjacent COMP edges’ enclosure is 0.01µm |
| logger.info('Executing rule S.CO.4ii') |
| s_co4ii_l1 = s_co4ii_2.not_in(s_co4ii_1).interacting(s_co4ii_1).or(s_co4ii_1.interacting(s_co4ii_3)).enclosed(comp.inside(sramcore).inside(opc_drc).edges, 0.06.um).polygons(0.001) |
| s_co4ii_l1.output('S.CO.4ii', 'S.CO.4ii : If COMP enclose contact by < 0.06um on one side, adjacent COMP edges’ overlap : 0.01µm') |
| s_co4ii_l1.forget |
| s_co4ii_1.forget |
| s_co4ii_2.forget |
| s_co4ii_3.forget |
| |
| # Rule S.CO.6: Metal1 overlap of contact. is 0µm |
| logger.info('Executing rule S.CO.6') |
| s_co6_l = contact.inside(sramcore).interacting(metal1).not(metal1) |
| s_co6_l.output('S.CO.6', 'S.CO.6 : Metal1 overlap of contact. : 0µm') |
| s_co6_l.forget |
| |
| s_co6i_m1_ = metal1.inside(sramcore).drc( width <= 0.34.um).edges.interacting(metal1.corners(90)) |
| s_co6i_m1 = metal1.inside(sramcore).edges.interacting(s_co6i_m1_) |
| # Rule S.CO.6i : Metal 1 (< 0.34µm) overlap of contact at end-of-line side is 0µm |
| logger.info('Executing rule S.CO.6i') |
| s_co6i_l1 = (contact.inside(sramcore).not_outside(metal1).not(metal1)) |
| s_co6i_l1.output('S.CO.6i','S.CO.6i: Metal 1 (< 0.34µm) overlap of contact at end-of-line side is 0µm') |
| |
| s_co6i_m1.forget |
| s_co6i_l1.forget |
| |
| s_co_6ii_ed = contact.inside(sramcore).edges.not(metal1.inside(sramcore).edges) |
| # Rule S.CO.6ii : If metal 1 enclose contact by < 0.04µm on one side, adjacent metal1 edges enclosure is 0µm |
| logger.info('Executing rule S.CO.6ii') |
| s_co_6ii_l1 = metal1.inside(sramcore).edges.enclosing(s_co_6ii_ed,0.04.um,projection).polygons(0.001) |
| s_co_6ii = contact.inside(sramcore).not_outside(metal1.inside(sramcore)).not(metal1).interacting(s_co_6ii_l1) |
| s_co_6ii.output('S.CO.6ii','S.CO.6ii : If metal 1 enclose contact by < 0.04µm on one side, adjacent metal1 edges enclosure is 0µm') |
| |
| s_co_6ii_ed.forget |
| s_co_6ii_l1.forget |
| s_co_6ii.forget |
| |
| # Rule S.CO.7: Space from COMP contact to Poly2 . is 0.12µm |
| logger.info('Executing rule S.CO.7') |
| s_co7_l1 = contact.inside(sramcore).outside(opc_drc).not_outside(comp).separation(poly2, 0.12.um, euclidian).polygons(0.001) |
| s_co7_l1.output('S.CO.7', 'S.CO.7 : Space from COMP contact to Poly2 . : 0.12µm') |
| s_co7_l1.forget |
| |
| # Rule S.CO.7i: Inside SramCore AND OPC_drc marking layers, Space from COMP contact to Poly2 . is 0.07µm |
| logger.info('Executing rule S.CO.7i') |
| s_co7i_l1 = contact.inside(sramcore).inside(opc_drc).not_outside(comp).separation(poly2, 0.07.um, euclidian).polygons(0.001) |
| s_co7i_l1.output('S.CO.7i', 'S.CO.7i :Inside SramCore AND OPC_drc marking layers, Space from COMP contact to Poly2 . : 0.07µm') |
| s_co7i_l1.forget |
| |
| # Rule S.CO.8: Space from Poly2 contact to COMP. is 0.13µm |
| logger.info('Executing rule S.CO.8') |
| s_co8_l1 = contact.inside(sramcore).outside(opc_drc).not_outside(poly2).separation(comp, 0.13.um, euclidian).polygons(0.001) |
| s_co8_l1.output('S.CO.8', 'S.CO.8 : Space from Poly2 contact to COMP. : 0.13µm') |
| s_co8_l1.forget |
| |
| # Rule S.CO.8i: Inside SramCore AND OPC_drc marking layers, Space from Poly2 contact to COMP. is 0.07µm |
| logger.info('Executing rule S.CO.8i') |
| s_co8i_l1 = contact.inside(sramcore).inside(opc_drc).not_outside(poly2).separation(comp, 0.07.um, euclidian).polygons(0.001) |
| s_co8i_l1.output('S.CO.8i', 'S.CO.8i: Inside SramCore AND OPC_drc marking layers, Space from Poly2 contact to COMP. is 0.07µm') |
| s_co8i_l1.forget |
| |
| # Rule S.M1.1: Metal1 width in parallel direction is 0.21µm |
| logger.info('Executing rule S.M1.1') |
| s_m11_l1 = metal1.inside(sramcore).outside(opc_drc).width(0.21.um, projection) |
| s_m11_l1.output('S.M1.1', 'S.M1.1 : Metal1 width in parallel direction : 0.21µm') |
| s_m11_l1.forget |
| |
| # Rule S.M1.1i: Inside SramCore AND OPC_drc marking layers, Metal1 width in parallel direction is 0.035µm |
| logger.info('Executing rule S.M1.1i') |
| s_m11i_l1 = metal1.inside(sramcore).inside(opc_drc).width(0.035.um, projection) |
| s_m11i_l1.output('S.M1.1i', 'S.M1.1i : Metal1 width in parallel direction : 0.035µm') |
| s_m11i_l1.forget |
| |
| # Rule S.M1.2a.i : Metal1 space in parallel direction is 0.20µm |
| logger.info('Executing rule S.M1.2a.i') |
| s_m1_2ai = metal1.inside(sramcore).outside(opc_drc).space(0.20.um, projection) |
| s_m1_2ai.output('S.M1.2a.i','S.M1.2a.i : Metal1 space in parallel direction is 0.20µm') |
| s_m1_2ai.forget |
| |
| # Rule S.M1.2a.ii : Metal1 (inside SramCore marking) to Metal1 (outside SramCore marking) space in parallel direction is 0.23µm |
| logger.info('Executing rule S.M1.2a.ii') |
| s_m1_2aii = metal1.and(sramcore).separation(metal1.not(sramcore),0.23.um, projection) |
| s_m1_2aii.output('S.M1.2a.ii','S.M1.2a.ii : Metal1 (inside SramCore marking) to Metal1 (outside SramCore marking) space in parallel direction is 0.23µm') |
| s_m1_2aii.forget |
| |
| # Rule S.M1.2a.iii : Metal1 (inside SramCore marking) to wide Metal1 (outside SramCore marking, length & width >10um) space in parallel direction is 0.30µm |
| logger.info('Executing rule S.M1.2a.iii') |
| s_m1_2aiii = metal1.and(sramcore).edges.separation(metal1.not(sramcore).edges.with_length(10.um,nil),0.3.um, projection) |
| s_m1_2aiii.output('S.M1.2a.iii','S.M1.2a.iii : Metal1 (inside SramCore marking) to wide Metal1 (outside SramCore marking, length & width >10um) space in parallel direction is 0.30µm') |
| s_m1_2aiii.forget |
| |
| # Rule S.M1.2a.iv : Inside SramCore AND OPC_drc marking layers, Metal1 space in parallel direction is 0.13µm |
| logger.info('Executing rule S.M1.2a.iv') |
| s_m1_2aiv = metal1.inside(sramcore).inside(opc_drc).space(0.13.um, projection) |
| s_m1_2aiv.output('S.M1.2a.iv','S.M1.2a.iv : Inside SramCore AND OPC_drc marking layers,Metal1 space in parallel direction is 0.13µm') |
| s_m1_2aiv.forget |
| |
| # Rule S.M2.2a.i : Metal2 (inside SramCore marking) to Metal2 (outside SramCore marking) space in parallel direction is 0.28µm |
| logger.info('Executing rule S.M2.2a.i') |
| s_m2_2ai = metal2.and(sramcore).separation(metal2.not(sramcore),0.28.um, projection) |
| s_m2_2ai.output('S.M2.2a.i','S.M2.2a.i : Metal2 (inside SramCore marking) to Metal2 (outside SramCore marking) space in parallel direction is 0.28µm') |
| s_m2_2ai.forget |
| |
| # Rule S.M2.3 : Minimum Metal2 Area is 0.12µm² |
| logger.info('Executing rule S.M2.3') |
| s_m2_3 = metal2.inside(sramcore).with_area(nil,0.12.um) |
| s_m2_3.output('S.M2.3','S.M2.3 : Minimum Metal2 Area is 0.12µm²') |
| s_m2_3.forget |
| |
| # Rule S.V1.3 : Metal1 enclose VIA1 is 0µm |
| logger.info('Executing rule S.V1.3') |
| s_v1_3 = via1.inside(sramcore).interacting(metal1.inside(sramcore)).not(metal1.inside(sramcore)) |
| s_v1_3.output('S.V1.3','S.V1.3 : Metal1 enclose VIA1 is 0µm') |
| s_v1_3.forget |
| |
| |
| s_v13i_m1 = metal1.inside(sramcore).width(0.341.um).polygons(0.001) |
| # Rule S.V1.3i : Metal 1 (< 0.34µm) enclose via1 at end-of-line side is 0µm |
| logger.info('Executing rule S.V1.3i') |
| s_v13i_l1 = (via1.inside(sramcore).not_outside(s_v13i_m1).not(s_v13i_m1)) |
| s_v13i_l1.output('S.V1.3i','S.V1.3i: Metal 1 (< 0.34µm) enclose Via1 at end-of-line side is 0µm') |
| |
| s_v13i_m1.forget |
| s_v13i_l1.forget |
| |
| s_v1_3ii_ed = via1.inside(sramcore).edges.not(metal1.inside(sramcore).edges).interacting(contact.inside(sramcore).edges.and(metal1.inside(sramcore).edges)) |
| # Rule S.V1.3ii : If metal1 enclose via1 by < 0.04µm on one side, adjacent metal1 edges enclosure is 0µm |
| logger.info('Executing rule S.V1.3ii') |
| s_v1_3ii_l1 = metal1.inside(sramcore).edges.enclosing(s_v1_3ii_ed,0.04.um,projection).polygons(0.001) |
| s_v1_3ii = s_v1_3ii_l1.or(via1.inside(sramcore).not_outside(metal1.inside(sramcore)).not(metal1)) |
| s_v1_3ii.output('S.V1.3ii','S.V1.3ii : If metal1 enclose via1 by < 0.04µm on one side, adjacent metal1 edges enclosure is 0µm') |
| |
| s_v1_3ii_ed.forget |
| s_v1_3ii_l1.forget |
| s_v1_3ii.forget |
| |
| end #FEOL |