DRC abutting edges.

Hello,

Let's say that we have two layers A and B. I would like to detect shapes of layer B that are between two layer A shapes - assuming that we are only dealing with rectangular shapes.

This is the shape I would like to be detected.

I was considering using interacting (using min and max) and outside/inside (to exclude overlapping shapes) operations but I am not entirely sure how to avoid detecting this scenario

Thank you

Comments

  • Hi @kareemfarid,

    Here is one solution that is based on the separation of edges into horizontal and vertical ones:

    report("discussion 2669")
    
    l1 = input(1, 0)  # reddish
    l2 = input(2, 0)  # blueish
    
    l1e = l1.edges
    l2e = l2.edges
    
    # split l2e into horizontal and vertical edges
    l2e_h = l2e.with_angle(0)
    l2e_v = l2e.without_angle(0)
    
    # split l1e into horizontal and vertical edges
    l1e_h = l1e.with_angle(0)
    l1e_v = l1e.without_angle(0)
    
    # selects full edges of L2 that touch L1
    l2e_on_l1e_h = l2e_h.interacting(l1e_h)
    l2e_on_l1e_v = l2e_v.interacting(l1e_v)
    
    # l2 two-side butting l1 horizontally, but not vertically
    l2butt_h = l2.interacting(l2e_on_l1e_h, 2).not_interacting(l2e_on_l1e_v)
    
    # l2 two-side butting l1 vertically, but not horizontally
    l2butt_v = l2.interacting(l2e_on_l1e_v, 2).not_interacting(l2e_on_l1e_h)
    
    # combines both versions
    l2butt = l2butt_h + l2butt_v
    
    l2butt.output("L2 butting L1 opposite")
    

    It renders this result:

    If you want the L1 rectangle selected, add:

    l2rect = l2.interacting(l2butt)
    

    The following, somewhat more esoteric solution, renders the same result in a more efficient way:

    report("discussion 2669")
    
    l1 = input(1, 0)  # reddish
    l2 = input(2, 0)  # blueish
    
    # select l2 shapes where exactly two l1 edges are touching
    l2_with_two_l1_edges = l2.interacting(l1.edges, 2, 3)
    
    # from this, use a zero-distance (<1 DBU) separation check 
    # with opposite-only filter to select the l2 edges in opposite
    # configuration
    l2_with_l1_opposite = l2_with_two_l1_edges.sep(l1, 1.dbu, whole_edges, only_opposite).first_edges
    
    l2_with_l1_opposite.output("L2 butting L1 opposite (2)")
    

    Matthias

  • edited February 9

    Thanks a lot.

    I got another question. In the case of, this implementation:

    report("discussion 2669")
    
    l1 = input(1, 0)  # reddish
    l2 = input(2, 0)  # blueish
    
    # select l2 shapes where exactly two l1 edges are touching
    l2_with_two_l1_edges = l2.interacting(l1.edges, 2, 3)
    
    # from this, use a zero-distance (<1 DBU) separation check 
    # with opposite-only filter to select the l2 edges in opposite
    # configuration
    l2_with_l1_opposite = l2_with_two_l1_edges.sep(l1, 1.dbu, whole_edges, only_opposite).first_edges
    
    l2_with_l1_opposite.output("L2 butting L1 opposite (2)")
    

    How to compute the distance between l2_with_l1_opposite edges. I thought space will not work since the edges belong to same polygon shape (not sure if this is a right assumption). But then width didn't work either.

    Thank you

  • Hi @kareemfarid,

    First I should correct the above (second) solution. It has this be this:

    # select l2 shapes where exactly two l1 edges are touching
    # (NOTE: the boolean AND between L1 and L2 edges selects
    # only L1 edges that are parallel to L2 edges)
    l2_with_two_l1_edges = l2.interacting(l1.edges & l2.edges, 2, 3)
    
    # from this, use a zero-distance (<1 DBU) separation check 
    # with opposite-only filter to select the l2 edges in opposite
    # configuration
    l2_with_l1_opposite = l2_with_two_l1_edges.sep(l1, 1.dbu, whole_edges, only_opposite).first_edges
    
    l2_with_l1_opposite.output("L2 butting L1 opposite (2)")
    

    Reason: the interacting test will otherwise fail in the general case as l1.edges that are perpendicular to l2.edges are counted as well.

    However, testing the resulting edges with "width" works for me:

    # Width check
    l2_with_l1_opposite.width(2.um).output("w<2µm")
    

    This gives me this:

    Matthias

  • Yes width appears to be working. Perhaps I missed something while testing. Thanks a lot

Sign In or Register to comment.