NEED HELP WITH LAYER RE_MAPPING

edited May 2016 in General
Hi there,
I have a large layout that will move to another technology. We need to map layers in that layout to other (already defined) layers, such as:

OLD LAYER = "L1" 7/727
NEW LAYER = "LP1" 17/727

We need to reassign old to new, so that we don't have change layers for each of the shapes.
In addition, we need to do this for a large set of OLD->NEW layer pairs.
Doing it by hand (edit>layer>copy layer) is too cumbersome and it leaves shapes in the old layer.
Anyone got a code snippet that could recurse through our set of pairs ?

I guess the safer way would be to recurse through all cells and shapes, and then move them to the
new layer if they belong to the old layer ? we have a fair amount of PCELLs. I am not too familiar
on how to use scripts to change the inner parameters to also adjust pcells.

Any help would be greatly appreciated !

thanks.

tHomas.

Comments

  • edited November -1
    I wrote script that loops through all flat-list cells and changes the layers of shapes
    over to a set of other layer. No problem, but I am struggling to change a layer
    parameter of PCELLs in the script. I can detect if a cell is a PCELL with myCell.is_pcell_variant?
    but the only thing I found to change the parameter is

    myCell.each_inst do |inst|
    myCell.change_pcell_parameter(inst,myPCParmName,newParm)
    puts "changing instance #{inst}"
    end

    (I have detected that the parameter is a layer by regex /[(][0-9]*\/[0-9]*[)]/)

    However, this does not update the PCELL at all.
    Am I doing something wrong here ?
    How would you do something like that ?

    Thanks.

    Thoams.
  • edited May 2016

    Hi Thomas,

    PCell updating is somewhat cumbersome. It would be easy if there was a method to translate a cell entirely, but there isn't. That is because although PCells are mapped to PCell variants, the PCell parameters are considered properties of instances.

    So you need to iterate the instances. Here is a recipe (untested):

    from_layer = ...    # A RBA::LayerInfo object with the layer to translate
    to_layer = ...      # A RBA::LayerInfo object giving the destination layer
    
    # we don't want to create a race between original and new cells so we first collect the normal cells
    normal_cells = []
    layout.each_cell do |cell|
      cell.is_pcell_variant? || normal_cells << cell
    end
    
    # then we walk through these and treat the PCell instances there
    normal_cells.each do |cell|
      cell.each_inst do |inst|
        if inst.is_pcell?
          param = inst.pcell_parameters_by_name
          update_needed = false
          param.each do |name, value|
            # This should work because
            #  1.) Every layer parameter is a RBA::LayerInfo object
            #  2.) The RBA::LayerInfo class implements a == operator
            if value.class == RBA::LayerInfo && value == from_layer
              param[name] = to_layer
              update_needed = true
            end
          end
          if update_needed
            inst.change_pcell_parameters(param)
          end 
        end
      end
    end
    

    As I said: this code is not tested but I am fairly sure this is the way it should work.

    Matthias

  • edited November -1
    Hi Matthias,
    your code needed a little work here and there but I got it to work.
    a small hurdle is that we dont really care about the from_layer name, we
    only care that layer and layertype are correct. The individual designers that
    feed me the gds I am importing name the layers all differently, but they
    adhere to the agreed layer/type notation. I will figure it out though.

    i noticed in a test run, that for every modification of a PCELL, the original
    PCELL is shoved above the top cell. I cannot modify it anymore, delete
    by hand, or re-instance it.
    How would I purge these old original PCELLS programmatically ?

    THANK YOU SO MUCH FOR ALL YOUR HELP ! I was ready to pull my hair out
    on this one !

    Thomas.
  • edited May 2016

    Hi Thomas,

    I see I forgot a small detail above: the class of the parameter value needs to be checked too.

    If you have a layer and datatype you can simply create a RBA::LayerInfo object like this:

    from_layer = RBA::LayerInfo(layer, datatype)
    

    the name is ignored in that case because layer/datatype has higher priority.

    Regarding the top cells that pop up you can remove all PCell variants on top level afterwards. Because PCells may instantiate other PCells this step has to be repeated until there are no more cells to remove.

    The following is TESTED code:

    layout = RBA::CellView::active.layout
    
    from_layer = RBA::LayerInfo::new(2, 0)
    to_layer = RBA::LayerInfo::new(1, 0)
    
    # we don't want to create a race between original and new cells so we first collect the normal cells
    normal_cells = []
    layout.each_cell do |cell|
      cell.is_pcell_variant? || normal_cells << cell
    end
    
    # then we walk through these and treat the PCell instances there
    normal_cells.each do |cell|
      cell.each_inst do |inst|
        if inst.is_pcell?
          param = inst.pcell_parameters_by_name
          update_needed = false
          param.each do |name, value|
            # This should work because
            #  1.) Every layer parameter is a RBA::LayerInfo object
            #  2.) The RBA::LayerInfo class implements a == operator
            if value.class == RBA::LayerInfo && value == from_layer
              param[name] = to_layer
              update_needed = true
            end
          end
          if update_needed
            inst.change_pcell_parameters(param)
          end 
        end
      end
    end
    
    # remove top cells that popped up
    # This code emulates what KLayout does internally
    while !(cells_to_delete = layout.top_cells.select { |c| c.is_pcell_variant? }).empty?
      layout.delete_cells(cells_to_delete.collect { |c| c.cell_index })
    end
    

    Regards,

    Matthias

Sign In or Register to comment.