Repeat sub-cell layer boolean

edited January 2014 in General

Hi Matthias,

Is there a way to repeat sub-cell layer boolean? Currently the "Layer => Boolean Operations" process layer on database level, and the result would be generated on Topcell.

For example(Currently):

Topcell => Cell1 (with layer 1/0 and layer 2/0)
        => Cell2 (with layer 1/0 and layer 2/0)

If boolean (1/0 not 2/0) to 3/0 , the 3/0 would on Topcell and usually becomes a large polygon.

We hope the 3/0 could be down to Cell1 => 1/0 not 2/0 => output 3/0 in Cell1 and then Cell2, CellN...

I tried to do it with DRC Macro, however I don't know how to specify the output cell from Topcell to Cell1...

layout_with_selection = layout.select("-*", "+Cell1")

a = layout_with_selection.input("1/0")
b = layout_with_selection.input("2/0")
c = a.not(b)
c.output("c (3/0)")

Best Regards,

chhung

Comments

  • edited November -1

    Hi Chhung,

    basically, KLayout's DRC implementation is flat, not hierarchical. So it will pull all shapes to top level and process them there.

    Your approach however is correct - if you happen to know that you can process these cells separately. "cell" is the method which allows you to focus on one cell and perform the operations in the context of that cell (again flat with respect to this cell) and "select" is the operation which allow to unselect cells plus their children.

    "select" and "cell" act on subsequent "input" statements, so they have to appear before "input".

    Here's your example with a simple hierarchy of "TOP" and two child cells "A" and "B" which are considered to be isolated with respect to each other and to the top cell. The following code will perform the operation locally on "A" and "B" and then on "TOP", this time without "A" and "B":

    cell("A")
    
    l1 = input(1)
    l2 = input(2)
    l1.not(l2).output(10)
    
    cell("B")
    
    l1 = input(1)
    l2 = input(2)
    l1.not(l2).output(10)
    
    cell("TOP")
    select("-A", "-B")
    
    l1 = input(1)
    l2 = input(2)
    l1.not(l2).output(10)
    

    Since the actual processing appears three times you can put it into a function (actually a method):

    def doit
      l1 = input(1)
      l2 = input(2)
      l1.not(l2).output(10)
    end
    
    cell("A")
    doit    
    
    cell("B")
    doit
    
    cell("TOP")
    select("-A", "-B")
    doit
    

    Hope that helps.
    Best regards,

    Matthias

  • edited November -1

    Hi Matthias,

    The cell() function call solved our problem, thank you so much~

    One tier sub-cell boolean operation could be apporached like the code:

    ly = RBA::CellView::active.layout
    
    topcell=ly.top_cell
    topcell.each_child_cell do |cell|
      cell(ly.cell_name(cell))       
    
      a = input("1/0")    
      b = input("2/0")
      a.not(b).output("3/0")
    end
    

    Best Regards,

    chhung

  • edited January 2014

    Hi chhung,

    thank you for the code. It's correct, but let put a note here for other readers: in the general case this approach is likely to produce incorrect results because it does not take into account inter-cell interactions. If the cells are non-overlapping however it's a valid and usually faster solution.

    Best regards,

    Matthias

  • Dear Matthias,
    I want to do the same because if you merge the layers in the top cell, the hierarchy in the layout is avoided due to the layers in the subcells is copied to the top cell.
    I have developed some code to fix this, however at the end the layout showed only is the first subcell iterated. Could you help me?

    app = RBA::Application.instance
    mw = app.main_window
    view = mw.current_view
    cv = view.cellview(view.active_cellview_index)
    cv.layout.each_cell_bottom_up do |cellss|
    print cellss.to_s
    cell(cv.layout.cell_name(cellss))
    if !cv.is_valid?
    return
    end

      cell = cv.cell
      dbu = cv.layout.dbu
    
      text = "Cell : #{cv.layout.cell_name(cellss)}\n"
      text += "Layers List :\n\n"
    
      cv.layout.layer_indices.each do |layer_id|
          layer_info = cv.layout.get_info(layer_id)
          print "\n"
          input(layer_info).merged.output(layer_info)
          lp_found = nil
          iter = view.begin_layers
          while !iter.at_end?
              lp = iter.current
              if lp.layer_index == layer_id
                  lp_found = lp 
              end
              iter.next
          end
    
          if lp_found.nil?
              text += "#{layer_info.to_s}\n"
          else
              text += "#{layer_info.to_s}  :  #{lp_found.name}\n"
          end
      end
      RBA::MessageBox::info("Cell Layers merged", text, RBA::MessageBox::b_ok)
    end
    
Sign In or Register to comment.