DRC for circle design

I have written a DRC code for myself that includes a line which checks the width of my via layer:

via_layer.drc(width < min_via_width).output("Error: Width violations on via layer")

However, all of my vias are circular in shape, and the DRC check returns an error even though the width is correct for circular shapes. Here is an example of the error message:

Is there a way to modify the code to avoid these errors while still checking the width of my vias?


  • Not knowing anything, I'd ask whether there is a pattern of
    highlighting the "not full ortho width" regions of the via
    (width done on Cartesian basis, maybe doesn't play with
    round objects?) but calling the cardinal "flat edges" OK.
    What heppens if you upsize the via by a bit? Does more of
    if become "accepted"? This all goes to methods and the
    need to recognize a class of shape in my imagining.

    Now a side question is, is your litho process accepting of
    non-standard-size-ortho vias? Not the case for many / most
    of the technologies I've used in the more recent decades -
    like, I stopped seeing "freehand" contact and via shapes
    of any size, allowed on 6" wafers and above - only a uniform
    min x min, use however many you like.

    Is there a "diameter" check that could be used, on shapes which
    appear "non-ortho", instead?

  • Regarding your inquiry:
    I can make the via bigger and increase the unbreakable rule part for it, but the pink section which shows the error remains. The error doesn’t depend on the circle’s size.
    For your second inquiry, they do accept the non-standard-size-ortho vias and even asked for them! They favor circular vias over rectangular ones.
    Your third question is also what I want to know! I’m waiting for @Matthias to respond.

  • edited March 8

    @ashkan No, there is no "diameter" check. "Line width" is defined not in terms of radius, but in terms of edges facing each other. You can narrow down the interactions by using projection metrics - this means that only opposite edges are considered:

    via_layer.drc(width < min_via_width, projection)...

    But your design rule is not quite specific. So what is the actual condition? Does the via have to be circular and needs to have a minimum diameter?

    An "is circular" condition can probably be checked by exploiting two facts: first, the bounding box of a circle is a square and second, the ratio of bounding box vs. polygon area has a specific value for a circle:

    l1 = input(1, 0)
    square_bboxes = l1.extents.squares
    maybe_circles = l1 & square_bboxes
    # a circle has a bbox to polygon area ratio of 
    # d^2 / (d^2*PI/4) = 4/PI = 1.27324 (we use 1.27..1.28)
    circles = maybe_circles.with_area_ratio(1.27, 1.28)
    l1.not_interacting(circles).output(100, 0)

    Once you know the circles you can use an area check to filter out circles with a diameter less the desired value.

    In general you will be in trouble if you don't have a precise understanding of your condition. After all, KLayout gives you access to all polygon points, so whatever you can check with a formula can be checked by a DRC script too. But that should be the last resort.


    BTW: the check above basically works and flags non-circles:

  • Hello,

    Maybe better to use:

    square_bboxes = layer1.extents.raw.squares

    else circles with overlapping bboxes are skipped...



  • edited March 10

    @tomas2004 Yes, you're right. I'm asking myself however whether overlapping circles should be treated as errors. In that case, not using "raw" is the the right approach.


  • edited March 14

    Thank you @Matthias and @tomas2004. I used

    layers["layer"].drc(width(projection) < min_via_width).output("Error: Width violations on via layer")

    And actually I used second method also to check the via layer is circle. Thanks.

    However, I have another problem now. I looked at DRC manual and I couldn't find anything that I can check the minimum of edges of one layer. Like this one:

    Is there any function that can check this? (The minimum edge must be bigger than for example 2.5 um, which in this example is 0.214um)

  • Hello,




  • Hello,

    @Matthias: since the ".raw" is behind ".extents" overlapping circles are flagged as should be.
    The script below flags everything which is not a 2um circle:

    layer1 = input(1, 0)
    square_bboxes = layer1.extents.raw.squares
    potential_circles = layer1 & square_bboxes
    all_circles = potential_circles.with_area_ratio(1.2700, 1.2766)
    layer1.not_interacting(drc_circles).output(100, 0)



  • Hi @tomas2004
    in my side , cause all the circle is created by my code , so I knew what the side (vertix, in my side, we using 100 vertix for the circle shape) in the shape.
    so , that is my idea..
    hope it can help to you.

    passivation_pi_via.data.each do |data|
    if data.width!=data.height && ll!=100 && data.area!=OOOO(what the circle area in your case) then
Sign In or Register to comment.