contact/via DRC : min enclosure on 2 opposite sides


How to write a DRC check for contact/via with a minimum enclosure on at least 2 opposite side ?
For instance, a via has to be enclosed by metal by 0.01µm on 2 opposite sides and can be 0 or whatever positive value on the2 other sides.

Best regards,


  • edited March 2019

    Hi Laurent,

    there is no out-of-the-box function yet, but there are several solutions based on the available features.

    I hope this code explains two of them:

    report("Via enclosure demo")
    via = input(5)
    metal = input(1)
    # this ensures there is no "negative" enclosure
    (via - metal).output("Via needs metal")
    # select those via edges (or parts) with less enclosure
    via_edges_with_less_enclosure = metal.enclosing(via, 10.nm, projection).second_edges
    # Option 1:
    # we know that via's are of a dimension so we can use "width"+"projection" to select
    # opposite edges (here: via size =
    good_via_edges = via.edges - via_edges_with_less_enclosure
    opposite = good_via_edges.width( + 1.dbu, projection).polygons
    solution1 = via.not_interacting(opposite)
    solution1.output("Min enclosure 10nm on at least two opposite edges - solution 1")
    # Option 2:
    # (does not need a value for the via size):
    # There is a problem if two edges with different orientation 
    # touch. There is no "interact" on the same edge set yet, but
    # you can use "width" with an "ignore_angle" of more than 90
    # degree to detect such touching corners:
    error_corners = via_edges_with_less_enclosure.width(angle_limit(100.0), 1.dbu)
    solution2 = via.interacting(error_corners.polygons(1.dbu))
    solution2.output("Min enclosure 10nm on at least two opposite edges - solution 2")

    Best regards,


  • Hi all,
    I see 4 ways to satisfy contact / via enclosure rule (as shown below). I am trying to write a DRC check for contact / via with enclosure but I have not thought of a way to check these 4 cases. Can you help me ?
    Thank you so much

  • Have you tried to options mentioned in my first reply?


  • Hi Matthias,
    I tried to options mentioned in your first reply. But it does not cover 2 case that I circle below.

    Best regards,


  • edited September 2020


    Maybe you need to explain what's the expected outcome.

    I rebuilt your sample (file attached) and with the script above I get this result:

    which looks perfectly fine to me. According to your description only the rightmost one violates the rule because it's the one where only one side encloses the via more than 10nm.


  • Hi sir,
    Sorry for my ambiguity. According to rules file, I can draw metal enclose via by 2 ways: (enclosure 4 edge >= 0.02 um) or (2 opposite sides> = 0.025um, other 2 edges> = 0.005um)

    I have created the wrong case in the attachment.

    Thanks sir

  • Hi Nam,

    Here is the way I have encoded it and used for some time in an other process, so I have adjusted the sizes to your process :

    cont_edges_with_less_enclosure = metal1.enclosing(cont, 0.025, projection).second_edges.extents(0.0125)
    contwithout025 = cont.interacting(cont.not(cont_edges_with_less_enclosure).with_area(nil,0.003))
    cont.interacting((metal1.enclosing(contwithout025, 0.02, euclidian).polygons).or(metal1.enclosing(cont, 0.005, euclidian).polygons)).output("M1_enc_CO", "Metal1 enclosing Contact : enclosure 4 edges >= 0.02 um or 2 opposite sides> = 0.025um with other 2 edges> = 0.005um")

    I cannot remember exactly the layout case that push me to add "with_area" during the debug, but I guess it was to find the opposite edges.
    Maybe, our master Matthias has a more efficient way to code it ;) ?


  • I wish I had ...

    I am considering the code a special option inside the enclosure check. I think that is basically the most efficient way. I'm just wondering how much variations there are and how flexible such an option has to be.

    Best regards,


Sign In or Register to comment.