PCell manipulation !(python scripting)

edited November 2014 in General
Hello,
I'm quite new to Klayout and I'm fascinated already! Adding to my interest is the python integration. That's great! And so, I'd like to ask about possibilities in manipulating a Pcell with python macros. Regardless of using instance is it possible to script a macros that enables PCells manipulation. Any general advise is appreciated. Thanks.

Comments

  • edited November 2014

    Hi beginner :-)

    Thanks for the feedback.

    Let me warn you about PCell's and scripting: right now, the PCell API is not quite simple and I recognized that as a weakness of the design. I will update that in the next major release and provide a simplified API.

    Also, Python support is in a pretty early stage. So there is no separate Python documentation - you'll have to take the Ruby documentation and translate it into Python following the rules mentioned in http://www.klayout.de/resources.html.

    The main target of script support for PCell's was to code them in Ruby (or Python now). See http://www.klayout.de/doc/programming/ruby_pcells.html. A Python sample can be found when creating a new Python script - when asked for a template, choose "Python PCell Sample".

    Instantiating PCell's through scripts was not the main target, but it appears to be of major interest. So I'll try to explain that little here.

    For understanding how PCell's are instantiated in KLayout, please have a look at the little documentation inside the description of the Cell class (http://www.klayout.de/doc/programming/database_api.html#h2-481].

    The basic problem if the current implementation is that PCell instantiation is pretty formal. There are three basic steps:

    • Locate the PCell and get the PCell declaration object. This object provides information about the PCell, specifically the parameters it expects.
    • Create a PCell variant cell. This cell is the container for the actual (generated) layout of the PCell. When the variant cell is created, the PCell code will be executed and the container cell will be filled. Apart from that, a PCell variant cell is a normal cell.
    • Finally instantiate the PCell variant cell like a normal cell.

    The PCell variant creation step expects the parameters as an array in the order the declaration lists them. This is the key problem: You cannot simple create a PCell instance and assign parameters to it. You'll have to prepare a proper structure and pass that to "add_pcell_variant" which creates the PCell.

    Here is some code (Python)

    # finding the PCell declaration object ...
    
    lib = pya.Library.library_by_name("Basic")
    if lib == None:
      raise Exception("Unknown lib 'Basic'")
    pcell_decl = lib.layout().pcell_declaration("TEXT");
    if pcell_decl == None:
      raise Exception("Unknown PCell 'TEXT'")
    
    # translating named parameters into an ordered sequence ...
    
    # named parameters
    param = { 
      "text": "SomeText", 
      "layer": pya.LayerInfo(17, 5),  # target layer of the text: layer 17, datatype 5 
      "mag": 1 
    }
    
    # translate to array (to pv)
    pv = []
    for p in self.pcell_decl.get_parameters():
      if p.name in param:
        pv.append(param[p.name])
      else:
        pv.append(p.default)
    
    # create the PCell variant cell
    pcell_var = self.layout.add_pcell_variant(self.lib, self.pcell_decl.id(), pv)
    
    # instantiating that cell ...
    
    # transformation
    t = pya.Trans(pya.Trans.r0(), -1000 + xpos, -1000 + ypos)
    
    # insert into "top_cell" (must be provided by the caller)
    pcell_inst = top_cell.insert(pya.CellInstArray(pcell_var, t))
    

    Once you have a PCell instance there is a certain level of support for named parameters using "Cell.change_pcell_parameter(instance, name, value)":

    top_cell.change_pcell_parameter(pcell_inst, "text", "FooBar")
    

    Regards,

    Matthias

  • edited November -1
    This is gonna help me a lot! Thank you Matthias :)
  • edited November 2014
    Hello,
    I already have a PCell and can get instances out of this PCell. And with your input I could manipulate it. But now I'm trying to script a macro file that would enable me to make instances and control it too(like specifying parameters like spacing , width, height or the like). My approach was, 1)finding the PCell declaration object 2)refering to the current libraray and PCell 3) some transformations --> t = pya.Trans(pya.Trans.r0(), -1000 + xpos, -1000 + ypos)
    and then I used
    top_cell = pya.CellView.active().layout().cell_by_name("name")
    pcell_inst = top_cell.insert(pya.CellInstArray(pcell_var, t))

    I lost my way when I had to specify the top_cell ! I just cannot deduce how would I get the top_cell which would be the layer PCell is residing currently (Since my piece of script just creates a PCell as an instance and I have no idea how to move further). In short, I've a PCell macro and how could I script another macro that'd make instances of it ? How would I point to PCell layer in a macro(just like using the import function) ? Looking forward to your advise. Thanks.
  • edited November 2014

    Hi,

    "top_cell" just means the cell where you want to put the PCell into. That may be a "top" cell (means this cell is not called itself), but this can also be a child cell somewhere in the tree.

    You can take the current cell:

    top_cell = pya.CellView.active().cell
    

    The current cell is the one displayed in the view.

    The actual solution depends on your application. If your goal is to produce a layout file, you can also work with a layout object detached from the view. Here is a complete sample for such a case:

    import pya
    
    ly = pya.Layout()
    
    # create the top cell
    top_cell = ly.create_cell("TOP")
    
    # locate the Basic library
    lib = pya.Library.library_by_name("Basic")
    if lib == None:
      raise Exception("Unknown lib 'Basic'")
    
    # locate the declaration
    pcell_decl = lib.layout().pcell_declaration("TEXT");
    if pcell_decl == None:
      raise Exception("Unknown PCell 'TEXT'")
    
    # create the PCell variant
    param = { 
      "text": "KLAYOUT RULES!",          # the text to produce
      "layer": pya.LayerInfo(17, 0),     # target layer of the TEXT
      "mag": 1 
    }
    
    pv = []
    for p in pcell_decl.get_parameters():
      if p.name in param:
        pv.append(param[p.name])
      else:
        pv.append(p.default)
    
    text_cell_index = ly.add_pcell_variant(lib, pcell_decl.id(), pv)
    
    # place the PCell
    t = pya.Trans(pya.Trans.R0, 1000, 2000)
    top_cell.insert(pya.CellInstArray(text_cell_index, t))
    
    # write the layout
    ly.write("out.oas")
    

    Matthias

Sign In or Register to comment.