DRC for via

klayout 0.30.4

Implementing via check
apparently klayout does not provide a check for via, in the sense the width is fix for instance 0.26um.

The obvious solution will be to check for size > 0.26 and < 0.26.

via1.drc(width > 0.26).output("VIA1.W.1", "VIA1 width > 0.26") (expected true if via width > 0.26um) failed !
via1.drc(width < 0.26).output("VIA1.W.2", "VIA1 width < 0.26") (expected true if via width < 0.26um) works !
or
via1.drc(width != 0.26).output("VIA1.W.3", "VIA1 width != 0.26") (expected true if via width != 0.26um) failed !

projection, no help
Does width work only for < ?

if yes then there is some problem with these examples

errors = in.drc(width < 0.2.um)
errors = in.drc(width <= 0.2.um)
errors = in.drc(width > 0.2.um)
errors = in.drc(width >= 0.2.um)
errors = in.drc(width == 0.2.um)
errors = in.drc(width != 0.2.um)
errors = in.drc(0.1.um <= width < 0.2.um)

Comments

  • edited March 21

    @alto The way DRC is behaving doesn't seem to be working as you expect; you can use the layer.width function to perform a width check as follows:

    report("DRC Check")

    VIA0 = input(51,0)
    a= VIA0.width(0.26+1.dbu,projection).with_angle(90).polygons #find width <=0.26 with angle = 90, vertical width check
    b= a.width(0.26+1.dbu,projection).with_angle(0).polygons #find width <=0.26 with angle = 90, horizontal width check

    / with 2 step, We remove all VIA0s with a width >0.26 in both vertical and horizontal directions.
    now, to get VIA0 have excactly width == 0.026, we do these steps/

    c= b.width(0.26).with_angle(90).polygons
    d=c.width(0.26).with_angle(0).polygons
    e= b-(c+d)
    e.output("VIA have width = 0.26")

    By using this process of elimination, you will find the width by a value equal to, greater than, or less than 0.
    Note that: The value 1.dbu is unclear; it's generally greater than 0. Something like 0.00000000001 (I'm not really clear, just use it for numbers different from 0).

    goodluck,

  • @alto could you please provide some screenshots or some sample files? This description is not enough to understand your problem. I you ask for help here, please try to be helpful as well. There are good examples of nicely prepared requests in this forum.

    I assume you are confusing width and dimension. The width of a rectangle is it's smaller dimension. So if you have a rectangle like 0.26x0.3, the width is still 0.26. So "width" is not the right way to check vias.

    The easiest way to check your vias is this:

    via_dim = 0.26
    
    via.non_squares.output("Vias must be squares")
    via.squares.drc(area != via_dim**2).output("Via is not #{via_dim}x#{via_dim}")
    

    Matthias

  • width definitively is not working. I tried various approaches. That is why I think
    these examples are kind misleading

    errors = in.drc(width > 0.2.um)
    errors = in.drc(width != 0.2.um)
    errors = in.drc(0.1.um <= width < 0.2.um)

    They seem a perfect fit for this task but they are not.
    It is not clear what is the scope of those checks, maybe is still work-in-progress.

    Via check is so common (all foundries I know have this rule) that I looked how
    it was implemented in skywater130. There you go ...

    via1.edges.without_length(0.26).output("VIA1.W.1", "VIA1 width == 0.26")

    It is odd to convert the polygon into edges to "measure" the length of them with without_length
    but, it does the job. A drawback is the number of errors is 2x (each edge generate an error)

    I think it is important to minimize the number of derived layers and/or operations.
    It is relatively easy to have many millions of vias, if the check is not 'efficient' it will take forever ...
    In other words, it is better to use simple primitive rather then doing convoluted operations.

    I tried Matthias suggestion, it works and it generate 1 error per via, which is good but,
    to my surprise I found that

    via.squares.drc(area != via_dim**2).output("Via is not #{via_dim}x#{via_dim}")
    is not enough to generate the error !

    It requires

    via.non_squares.output("Vias must be squares")
    via.squares.drc(area != via_dim**2).output("Via is not #{via_dim}x#{via_dim}")

    What 'via.non_squares.output("Vias must be squares")' actually does ? I do not see the connection
    between these commands.

  • Are you an AI agent? I don't feel like taking to someone who tries to understand what I am writing.

    "width" is not work in progress. You have the wrong expectations. What do you call the width of a piece of wire made from a rectangle? It's is not the length, it's the thickness of the wire. That is what a DRC check is doing: it checks if the width of a wire is big enough for manufacturing. It checks the smaller dimension. A wire with a width equal to 0.26µm can be a hundred micrometers long. It still has a width equal to 0.26µm. So that is the not the function you are looking for. It is not "a perfect fit", just because you call it that.

    And if you care to understand what "squares" does - read the documentation - you will see that it selects squares. In the same way, "non_squares" selects everything that is not a square. Every non-square via is an error, if the design rule says vias need to be squares. Every square can have exactly one dimension, hence one specific area. And the second check will tell you for which vias that is not the case.

    And this is why I have two checks and yes, one is not enough.

  • No I am not AI agent.

    Width is not thickness in this contest.

    For me width without and constrain is the distance between 2 internal parallel
    edges in any direction.
    In 2D length and width are interchangeable because there is not concept
    of up down or left right.

    It seems that klayout width is similar to calibre internal.

    calibre width check :

    M2.W.alto { @ Min. M2 width < 2.2
    INT M2 < 2.2
    }
    (width violation have not direction any parallel pairs of violation is flagged independently
    by the size of the other one )

    but

    M2.W.alto { @ Min. M2 width > 2.2
    INT M2 > 2.2
    }
    **is a syntax error **

    in klayout
    via1.drc(width < 0.26).output("VIA1.W.1", "VIA1 width < 0.26")
    it behaves like calibre INT

    but
    via1.drc(width > 0.26).output("VIA1.W.1", "VIA1 width > 0.26")
    it not a syntax error but it does not catch a rectangular via.
    Unless both pairs of parallel edges are > 0.26.
    What is a practical application of this check ?

    ABOUT:

    via.non_squares.output("Vias must be squares")
    via.squares.drc(area != via_dim**2).output("Via is not #{via_dim}x#{via_dim}")

    This is my fault. There was an error in my test-case. In this picture

    shape A is clearly rectangular but B was suppose to be square with WxL=0.25x0.25 but
    it was not. The shape was 0.25x0.24. The errors were generated both by via.non_squares.
    This was the reason for the confusion I was under the impression that both command are needed,
    without understanding how they interact. In fact they do not interact.
    When I fix the size of shape B, I got 2 separate errors, one from via.non_squares and one from via.squares.drc as expected.

Sign In or Register to comment.