Size Shapes in PCell

NMFNMF
edited October 2016 in Ruby Scripting

I spent a good two hours on the forums today looking for the answer to this because I think it is a simple syntax, but how can I size a shape in my PCell?

So I create a block:

  #Create Block shape
  block = []
  block.push(Point.from_dpoint(DPoint.new(  -l_dbu/2-excl_dbu,   -wl_dbu/2-excl_dbu  )   )   )
  block.push(Point.from_dpoint(DPoint.new(  -l_dbu/2-excl_dbu,   wl_dbu/2+excl_dbu  )   )   )
  block.push(Point.from_dpoint(DPoint.new(  l_dbu/2+excl_dbu,   wr_dbu/2+excl_dbu)   )   )
  block.push(Point.from_dpoint(DPoint.new(  l_dbu/2+excl_dbu,   -wr_dbu/2-excl_dbu  )   )   )

Now I have another layer that needs to be 0.5um inside "block". In this case it isn't hard to just generate "block2" where I add/subtract 0.5 from each coordinate, but for more complex shapes why can't I do:

  block2 = block.sized(var)

The only thing I could think of was that "block" isn't an object; just an array of points, right? I draw the shape using:

  cell.shapes(layout.layer(blocklayer.layer, blocklayer.datatype)).insert(Polygon.new(block))

So can I throw the .sized call in that line somewhere? Or do I need to break it up? 1) Make the polygon 2) Draw the shape 3) Size the polygon 4) Draw the sized shape

I would assume I'm mixing up the understanding and use of shapes and polygons.

Thanks in advance for the help. I'm a little rusty and rushing to tape out (plus a toddler at home that didn't think I needed sleep last night...)

Comments

  • edited October 2016

    Hi,

    I can help out with the first problem - there is no quick fix available for sleepless kids, I'm afraid. But that problem will be solved just 15 years later. At this time it will be hard to get them out of bed :-)

    For the sizing problem:

    Sizing is a rather trivial operation on boxes and a less trivial operation on polygons. Boxes may vanish upon too string negative sizing, but that's the only issue. So I'd suggest to work with a Box object, rather than a polygon.

    Here is some suggestion:

    # using a box instead of a polygon:
    box = RBA::Box::new(-l_dbu/2-excl_dbu, -wl_dbu/2-excl_dbu, l_dbu/2+excl_dbu, wr_dbu/2+excl_dbu)
    cell.shapes(layout.layer(blocklayer.layer, blocklayer.datatype)).insert(box)
    

    With a box, sizing is pretty simple:

    # "size" the box: enlarge accepts two values for horizontal and vertical enlargement.
    # The enlargement is the amount by which the edges will be shifted - i.e. the width
    # will be width+var*2 afterwards:
    box.enlarge(var, var)
    

    Please note that for large negative numbers, the box will finally vanish. You can check this with box.is_empty?.

    If you really want to size polygons, the matter is slightly more difficult. In general, a polygon may not stay a single polygon on size operations. On negative sizing, polygons may fall apart into multiple pieces for example. Hence, the size operation is not well defined on a single polygon. Instead, KLayout comes with the RBA::Region class which represents a set of polygons. This class offers a sizing method, boolean operations and much more. If you want to use this class, this is the way to go:

    # build the region and fill it with polygons, boxes, paths ...
    region = RBA::Region::new
    region.insert(box)
    
    # ... insert more ...
    
    # now size the region
    region.size(var)
    # and insert the region into the output cell (means: insert every polygon the region consists of):
    cell.shapes(layout.layer(blocklayer.layer, blocklayer.datatype)).insert(region)
    

    The region is a very mighty, but also somewhat heavy object. If you're just dealing with boxes, I'd stay with them. Specifically since a region size implies merging of the polygons which may not be desired.

    Regards,

    Matthias

  • NMFNMF
    edited November -1

    Thanks, as usual Matthias.

    Unfortunately my more complex PCells generate polygons so I'll have to head down this rabbit hole. I do think it could be an opportunity to streamline my code though now that I think about it.

    Long story short I'm drawing long complex optical wiring. After I draw the wire I then re-draw the blockfill shape, and now am trying to apply a different blockfill shape that has a slightly smaller size (hence the idea to size the original blockfill). In my application, however, merging is ideal and would probably shrink the filesize. I could just draw the wire as a region, size up for the first blockfill, and then size up again for the next blockfill.

    Thanks again, I'm sure I'll be back soon!

    PS - The child is already difficult to wake up. I assume as a teenager it will be much worse (somehow).

Sign In or Register to comment.