blob: 7dec956d8235e67ddb305f483116f41142cb8baa [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 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