DRC fill option

Hello Matthias et al.,

I'm playing around with the DRC fill tool and got some questions (version 0.28.17):

1) I would like to fill a layer called "layer_to_fill" (green in the screenshots below) with a tile "tile_M1" (blue in the screenshots below):

tile_M1 = fill_pattern("TILE_M1").shape(20170, 0, box(-0.244, -0.240, 0.244, 0.240))
layer_to_fill.fill(tile_M1)

This works great:

If I redo this with an offset, I see that the tiles are shifted as expected, but there are now also tiles going outside the "layer_to_fill" shapes (ellipse)...
I would not expect this to happen or am I missing something???

tile_M1 = fill_pattern("TILE_M1").shape(20170, 0, box(-0.244, -0.240, 0.244, 0.240))
tile_M1.origin(-0.3, -0.3)
layer_to_fill.fill(tile_M1)

2) Is there a way to refer to an existing cell of the layout, instead of using the fill_pattern method and add shapes one by one via code???

Cheers,

Tomas

Comments

  • Hello,

    Here's another example (with attachment): I would like to fill layer 3/0 (green) with two different tiles T1 and T2 and one out of three needs to be T2 and the T2's need to be placed diagonally, like:

    T2 T1 T1
    T1 T2 T1
    T1 T1 T2

    One way is to create a bigger 3X3 tile with the scheme above, but this will leave too much of the fill area empty so I was thinking about doing 9 (individual) tiling iterations.

    The first one works fine:

    # 1st iteration (T1 @ 0,0)
    layer_to_fill.fill(tile_T1, hstep(3.0*tile_pitch_X), vstep(3.0*tile_pitch_Y), auto_origin)
    

    But the other iterations (using .origin) create tiles outside of the layer 3/0 shape(s):

    # 2nd iteration (T1 @ 1,0)
    tile_T1.origin(-0.5*tile_size_X, -0.5*tile_size_Y-1.0*tile_pitch_Y)
    layer_to_fill.fill(tile_T1, hstep(3.0*tile_pitch_X), vstep(3.0*tile_pitch_Y), auto_origin)
    
    etc.
    

    Is this like a kind of bug? (If not,) is there another way do this?

    (For each iteration, a new cell is generated (TILE_T1$x, TILE_T2$x), hence my question to refer to an existing cell of the layout instead of using the fill_pattern method...)

    Cheers,

    Tomas

  • Hi @tomas2004,

    That's not a bug. "origin" for the fill pattern does something else than what you expected.

    First of all, this is my version:

    # 1st iteration (T1 @ 0,0)
    
    layer_to_fill.fill(tile_T1, hstep(3.0*tile_pitch_X), vstep(3.0*tile_pitch_Y), origin(0.5*tile_size_X, 0.5*tile_size_Y))
    
    # 2nd iteration (T1 @ 1,0)
    
    layer_to_fill.fill(tile_T1, hstep(3.0*tile_pitch_X), vstep(3.0*tile_pitch_Y), origin(0.5*tile_size_X, 0.5*tile_size_Y+1.0*tile_pitch_Y))
    
    # 3rd iteration (T2 @ 2,0)
    
    layer_to_fill.fill(tile_T2, hstep(3.0*tile_pitch_X), vstep(3.0*tile_pitch_Y), origin(0.5*tile_size_X, 0.5*tile_size_Y+2.0*tile_pitch_Y))
    
    # 4th iteration (T1 @ 0,1)
    
    layer_to_fill.fill(tile_T1, hstep(3.0*tile_pitch_X), vstep(3.0*tile_pitch_Y), origin(0.5*tile_size_X+1.0*tile_pitch_X, 0.5*tile_size_Y))
    
    # 5th iteration (T2 @ 1,1)
    
    layer_to_fill.fill(tile_T2, hstep(3.0*tile_pitch_X), vstep(3.0*tile_pitch_Y), origin(0.5*tile_size_X+1.0*tile_pitch_X, 0.5*tile_size_Y+1.0*tile_pitch_Y))
    
    # 6th iteration (T1 @ 2,1)
    
    layer_to_fill.fill(tile_T1, hstep(3.0*tile_pitch_X), vstep(3.0*tile_pitch_Y), origin(0.5*tile_size_X+1.0*tile_pitch_X, 0.5*tile_size_Y+2.0*tile_pitch_Y))
    
    # 7th iteration (T2 @ 0,2)
    
    layer_to_fill.fill(tile_T2, hstep(3.0*tile_pitch_X), vstep(3.0*tile_pitch_Y), origin(0.5*tile_size_X+2.0*tile_pitch_X, 0.5*tile_size_Y))
    
    # 8th iteration (T1 @ 1,2)
    
    layer_to_fill.fill(tile_T1, hstep(3.0*tile_pitch_X), vstep(3.0*tile_pitch_Y), origin(0.5*tile_size_X+2.0*tile_pitch_X, 0.5*tile_size_Y+1.0*tile_pitch_Y))
    
    # 9th iteration (T1 @ 2,2)
    
    layer_to_fill.fill(tile_T1, hstep(3.0*tile_pitch_X), vstep(3.0*tile_pitch_Y), origin(0.5*tile_size_X+2.0*tile_pitch_X, 0.5*tile_size_Y+2.0*tile_pitch_Y))
    

    Which gives this:

    "fill_pattern.origin", together with "fill_pattern.dim" specifies the pattern bounding box (the "drawn area"). You tried to shift the pattern which basically works, but it will also specify a bounding box that is not the drawn area. The drawn area is given by the shapes you add - like "box" etc. - and it will not change when you set "origin". The effect is a shift, but after that the "drawn" shapes sit outside the box, hence the do not sit inside the fill area.

    The solution is to set an origin in the "fill" function: this will decide where to place the first instance of the pattern. I had to switch the sign of the coordinates, as the effect is a positive shift then.

    Regards,

    Matthias

  • Hello Matthias,

    Thank you for the detailed explanation. It is clear to me now. :smiley:

    For each iteration a new tile is generated, although TILE_T1 to TILE_T1$5 and TILE_T2 to TILE_T2$ are identical. This is not a problem, I can "clean up" with another script. It's actually useful to visualize each iteration individually. :sunglasses:

    Cheers,

    Tomas

  • Very good :)

    The fill feature will generate new cells when you feed it with "fill_pattern" things. Technically, the "fill_pattern" is just a collection of shapes, but as the fill feature internally needs a cell, it will make a cell from it, not knowing that the fill pattern did not change between the calls.

    To avoid this, you can put the following code in front of your DRC script:

    class DRC::DRCFillCell
      if !self.instance_methods.member?(:create_cell_org)
        alias_method :create_cell_org, :create_cell
        def create_cell(layout, engine)
          return layout.cell(@cell_name) || self.create_cell_org(layout, engine)
        end
      end
    end
    

    This monkey-patches the DRC engine to skip creating a new fill cell, assuming that same name means same content.

    Matthias

  • Hi Matthias,

    Awesome! Thank you for all your help, much appreciated!

    Cheers,

    Tomas

Sign In or Register to comment.