Attach pya.Cell to existing layout

edited May 2022 in Python scripting

What's the best way to create a layout procedurally?

What I want to do is essentially instantiating cells in other cells without directly having a (top cell) layout object (yet). I want to first create leaf cells in individual modules and then have a top cell instantiate the cells and add references.

But the problem I noticed is that if I create a cell e.g. with c = pya.Cell() the layout object of the cell is (understandably) not instantiated. Is there a way to a) make the layout object of the cell a valid instantiated object and then b) once I have the actual parent cell instantiated, i.e. something like parent_cell.copy_tree(child_cell) without each cell having their individual layout object and then repeating child_cell = layout.create_cell(chil_cell_name) and then use copy tree in the parent cell after creating the empty child cell there?

To make it easier to understand I would like to do the following

### Module of leaf cell

leaf_cell = pya.Cell()
# Do something with the cell here, e.g. add and transform shapes
### Module of parent cell
from leaf_cell import leaf_cell

parent_cell = pya.Cell()
# instantiate a leaf_cell in parent_cell with something like parent_cell.copy_tree(leaf_cell) here

As far as I can tell this doesn't work because neither parent_cell nor child_cell have a valid layout object because they weren't created through layout.create_cell(cell_name)

Best,
Sebastian

Comments

  • edited May 2022

    @sebastian No you cannot do that. A cell cannot live without a Layout object. The layout object provides the context (layers, database unit, cell name space etc.) for the cell. A cell cannot exist without this connection.

    You can basically create small layouts to capture your partial layout and later copy them together everything, but I doubt you will gain much from that.

    I wonder why your design cannot have a some context object which keeps the layout object and potentially much more information. There is nothing wrong with passing such a thing around if that is only a single object reference. That is quite a common design in many frameworks.

    My design would be something like:

    context.py:
    
    class Context(object):
      def __init__(self):
         self.layout = pya.Layout()
         ...
    
    generator1.py:
    
    class Generator1(object):
       def generate(self, context):
          cell = context.layout.create_cell("generator1")
          ...
          return cell
    
    generator2.py:
    
    class Generator2(object):
       def generate(self, context):
          cell = context.layout.create_cell("generator1")
          ...
          return cell
    
    main.py:
    
    from context import *
    from generator1 import *
    from generator2 import *
    
    ctx = Context()
    top = ctx.layout.create_cell("TOP")
    
    cell1 = Generator1().generate(ctx)
    top.insert(pya.CellInstArray(cell1.cell_index(), ...))
    
    cell2 = Generator2().generate(ctx)
    top.insert(pya.CellInstArray(cell2.cell_index(), ...))
    

    Or something like this.

    Matthias

Sign In or Register to comment.