Comportment of Pcells in library

edited December 2016 in Layout
Dear all,

i am facing a little "issue" with a Pcell of my own used in a gds library.
Here is the description of the problem :
i have a library called test in which i use a Pcell (module name is called BiB (see code below) in a cell called test_cell
this give a tree like this:

test_cell
-BiB.BoxInBox(L1=3/0,L2=2/0)
-BiB.BoxInBox(L1=1/0,L2=2/0)


i then use this library test in a gds (say test2/cell_test2)
when doing so i expect to have, for example, a cell tree looking like

cell_test2
-test.test_cell
-test.BiB.BoxInBox(L1=3/0,L2=2/0)
-test.BiB.BoxInBox(L1=1/0,L2=2/0)

(which is the comportment i get using for example Basic Pcells)

however i get :

cell_test2
-test.test_cell
-testBoxInBox
-testBoxInBox$1

This is not a very important "issue", since the PCell in the library file is still kept as Pcell, however it is annoying because i lose(in this case) the information of layers used by each instance of the Pcell.

For what i know it is a recent "issue" i have since migrating to
- klayout 0.24.8 (was 0.23.8)
- a different way of managing library
i used to use the following code snippet

lib = RBA::Library.new
lib.layout.read(libpath)
lib.register(name)

to use a given library
while now i am using the integrated behaviour of Klayout (giving a library name in the gds save option)

but it may be also a pcell code not that clean !!

Is there something wrong in my code? or is it expected behaviour?

For information i tested the simple PCell sample example (drawing a circle) and the behaviour is the same as my Pcell.

Edit: i read that there is a bugfix in 0.24.9 concerning hierarchy tree containing Pcell in the 0.24.9. Does this adress the above issue?

Regards
Joël

----------------------------------
# PCell Pour motif alignement et contr�les
#
# This library contains
# BoxInBox
# sample PCell implements a library called "MyLib" with a single PCell that
# draws a circle. It demonstrates the basic implementation techniques for a PCell
# and how to use the "guiding shape" feature to implement a handle for the circle
# radius.
#
# NOTE: after changing the code, the macro needs to be rerun to install the new
# implementation. The macro is also set to "auto run" to install the PCell
# when KLayout is run.

module BiB

include RBA

# Remove any definition of our classes (this helps when
# reexecuting this code after a change has been applied)
BiB.constants.member?(:BoxinBox) && remove_const(:BoxinBox)
BiB.constants.member?(:BiB) && remove_const(:BiB)

# The PCell declaration for the circle
class BoxinBox < PCellDeclarationHelper

include RBA

def initialize

# Important: initialize the super class
super

# declare the parameters
param(:larg, TypeBoolean, "Large ?",:default=> false)
param(:bl, TypeLayer, "Layer Box", :default => LayerInfo::new(1, 0))
param(:bt, TypeString, "Number Override (<100)", :default => "")
param(:binv,TypeBoolean, "Box polarit� inverse?",:default => false)
param(:ibl, TypeLayer, "Layer InBox", :default => LayerInfo::new(1, 0))
param(:ibt, TypeString, "Number Override (<100)", :default => "")
param(:ibinv,TypeBoolean, "InBox polarit� inverse?",:default => false)

end

def display_text_impl
# Provide a descriptive text for the cell
"BoxInBox(L1=#{bl.to_s},L2=#{ibl.to_s})"
end

def coerce_parameters_impl

# We employ coerce_parameters_impl to decide whether the handle or the
# numeric parameter has changed (by comparing against the effective
# radius ru) and set ru to the effective radius. We also update the
# numerical value or the shape, depending on which on has not changed.
r =25
end

def can_create_from_shape_impl
# Implement the "Create PCell from shape" protocol: we can use any shape which
# has a finite bounding box
shape.is_box? || shape.is_polygon? || shape.is_path?
end

def parameters_from_shape_impl
# Implement the "Create PCell from shape" protocol: we set r and l from the shape's
# bounding box width and layer


set_r shape.bbox.width*layout.dbu / 2
set_ibl layout.get_info(layer)
set_bl layout.get_info(layer)
end

def transformation_from_shape_impl
# Implement the "Create PCell from shape" protocol: we use the center of the shape's
# bounding box to determine the transformation
Trans.new(shape.bbox.center)
end

def produce_impl


# This is the main part of the implementation: create the layout

# fetch the parameters


if larg
f_ib = 3.5
f_b = 3.0
else
f_b = 1.0
f_ib = 1.0
end


# find the lib
lib = RBA::Library.library_by_name("Basic")
lib || raise("Unknown lib 'Basic'")

# find the pcell
pcell_decl = lib.layout.pcell_declaration("TEXT")
pcell_decl || raise("Unknown PCell 'TEXT'")

layer = ibl.layer
datatype = ibl.datatype

if ibt == "" then
ibtexte=ibl.layer.to_s
else
ibtexte=ibt
end

if bt == "" then
btexte=bl.layer.to_s
else
btexte=bt
end

if !ibinv

param = {"text" => ibtexte, "layer" =>RBA::LayerInfo::new(layer, datatype), "mag"=>f_b*15, "inverse"=> false}
pv = pcell_decl.get_parameters.collect do |p|
param[p.name] || p.default
end


# InBox
pts3 = [ [ [-4.5*f_ib,6*f_ib],[-4.5*f_ib,8*f_ib],[4.5*f_ib,8*f_ib],[4.5*f_ib,6*f_ib] ],
[ [-4.5*f_ib,-6*f_ib],[-4.5*f_ib,-8*f_ib],[4.5*f_ib,-8*f_ib],[4.5*f_ib,-6*f_ib] ],
[ [-6*f_ib,4.5*f_ib],[-8*f_ib,4.5*f_ib],[-8*f_ib,-4.5*f_ib],[-6*f_ib,-4.5*f_ib] ],
[ [6*f_ib,4.5*f_ib],[8*f_ib,4.5*f_ib],[8*f_ib,-4.5*f_ib],[6*f_ib,-4.5*f_ib] ] ]

pts3.each { |pp|
pointlist = []
pp.each { |p| pointlist.push(Point.from_dpoint(DPoint.new( p[0]/layout.dbu, p[1]/layout.dbu ) )) }
cell.shapes(ibl_layer).insert(Polygon.new(pointlist))
}
else

param = {"text" => ibtexte, "layer" =>RBA::LayerInfo::new(layer, datatype), "mag"=>f_b*15, "inverse"=> true}
pv = pcell_decl.get_parameters.collect do |p|
param[p.name] || p.default
end

# InBox inverse
pts3 = [ [-15.00000*f_b,-15.00000*f_b],
[-15.00000*f_b,15.00000*f_b],
[15.00000*f_b,15.00000*f_b],
[15.00000*f_b,8.00000*f_ib],
[-4.50000*f_ib,8.00000*f_ib],
[-4.50000*f_ib,6.00000*f_ib],
[4.50000*f_ib,6.00000*f_ib],
[4.50000*f_ib,8.00000*f_ib],
[15.00000*f_b,8.00000*f_ib],
[15.00000*f_b,4.50000*f_ib],
[-8.00000*f_ib,4.50000*f_ib],
[-8.00000*f_ib,-4.50000*f_ib],
[-6.00000*f_ib,-4.50000*f_ib],
[-6.00000*f_ib,4.50000*f_ib],
[6.00000*f_ib,4.50000*f_ib],
[6.00000*f_ib,-4.50000*f_ib],
[8.00000*f_ib,-4.50000*f_ib],
[8.00000*f_ib,4.50000*f_ib],
[15.00000*f_b,4.50000*f_ib],
[15.00000*f_b,-6.00000*f_ib],
[-4.50000*f_ib,-6.00000*f_ib],
[-4.50000*f_ib,-8.00000*f_ib],
[4.50000*f_ib,-8.00000*f_ib],
[4.50000*f_ib,-6.00000*f_ib],
[15.00000*f_b,-6.00000*f_ib],
[15.00000*f_b,-15.00000*f_b] ]

# pts3.each { |pp|
pointlist = []
pts3.each { |p| pointlist.push(Point.from_dpoint(DPoint.new( p[0]/layout.dbu, p[1]/layout.dbu ) )) }
cell.shapes(ibl_layer).insert(Polygon.new(pointlist))
# }
end

# create a PCell variant cell
pcell_var = cell.layout.add_pcell_variant(lib, pcell_decl.id, pv)
x = f_b*16.5/layout.dbu
y = f_b*3/layout.dbu
t = RBA::Trans::new(0,false, x, y)
pcell_inst = cell.insert(RBA::CellInstArray::new(pcell_var, t))



layerb = bl.layer
datatypeb = bl.datatype

if !binv

param = {"text" => btexte, "layer" =>RBA::LayerInfo::new(layerb, datatypeb), "mag"=>f_b*15, "inverse"=> false}
pv = pcell_decl.get_parameters.collect do |p|
param[p.name] || p.default
end

#Box

pts2 = [ [ [-7.5,10],[-7.5,12],[7.5,12],[7.5,10] ],
[ [-7.5,-10],[-7.5,-12],[7.5,-12],[7.5,-10] ],
[ [-10,7.5],[-12,7.5],[-12,-7.5],[-10,-7.5] ],
[ [10,7.5],[12,7.5],[12,-7.5],[10,-7.5] ] ]

pts2.each { |pp|
pointlist = []
pp.each { |p| pointlist.push(Point.from_dpoint(DPoint.new( f_b*p[0]/layout.dbu, f_b*p[1]/layout.dbu ) )) }
cell.shapes(bl_layer).insert(Polygon.new(pointlist))
}

else

param = {"text" => btexte, "layer" =>RBA::LayerInfo::new(layerb, datatypeb), "mag"=>f_b*15, "inverse"=> true}
pv = pcell_decl.get_parameters.collect do |p|
param[p.name] || p.default
end

#Box inverse

pts2 = [ [-15.00000,-15.00000],
[-15.00000,15.00000],
[-10.00000,15.00000],
[-10.00000,7.500000],
[-12.00000,7.500000],
[-12.00000,-7.500000],
[-10.00000,-7.500000],
[-10.00000,15.00000],
[7.500000,15.00000],
[7.500000,12.00000],
[-7.500000,12.00000],
[-7.500000,10.00000],
[7.500000,10.00000],
[7.500000,-10.00000],
[-7.500000,-10.00000],
[-7.500000,-12.00000],
[7.500000,-12.00000],
[7.500000,15.00000],
[12.00000,15.00000],
[12.00000,7.500000],
[10.00000,7.500000],
[10.00000,-7.500000],
[12.00000,-7.500000],
[12.00000,15.00000],
[15.00000,15.00000],
[15.00000,-15.00000]
]

# pts3.each { |pp|
pointlist = []
pts2.each { |p| pointlist.push(Point.from_dpoint(DPoint.new( f_b*p[0]/layout.dbu,f_b*p[1]/layout.dbu ) )) }
cell.shapes(bl_layer).insert(Polygon.new(pointlist))
# }

end
pcell_var = cell.layout.add_pcell_variant(lib, pcell_decl.id, pv)
x = 16.5*f_b/layout.dbu
y = -13.5*f_b/layout.dbu
t = RBA::Trans::new(0,false, x, y)
pcell_inst = cell.insert(RBA::CellInstArray::new(pcell_var, t))
end


end



class BiB < Library

def initialize

# Set the description
self.description = "Librairie alignement et controles"

# Create the PCell declarations
layout.register_pcell("BoxinBox", BoxinBox::new)


# That would be the place to put in more PCells ...

# Register us with the name "MyLib".
# If a library with that name already existed, it will be replaced then.
register("BiB")

end

end

# Instantiate and register the library
BiB::new

end

Comments

  • edited November -1
    Tested the last version. do not fix the problem.


    Regards
    Joël
  • edited November -1

    Hi Joel,

    the bugfix you mention is not related to this issue but only to manual copy/paste in the editor.

    If I understand your description correctly you changed the way the "test" library is built. So now, you're loading the library from a file and this file contains PCell's, right?

    If that is the case I assume the problem is related to the build order. If for some reason, the BiB PCell is built after the library is loaded, the PCell's inside the library will not be connected to your PCell code.

    So the important question is: when do you load the library and when do you load the PCell? If you do both in a .lym file you can try loading the PCell "early on startup" (see macro options) to force it to be loaded before the library.

    Regards,

    Matthias

  • edited November -1
    Hello Matthias

    Concerning the order of loading when all is done through the macro way, i dunno, i suppose that its follow alphebetic order. In this case, my "old" way of doing should have loaded the Pcell before the library (since my Pcell start with B and my lybrary macro is starting with L) => hence worked the way it should.
    Now that i have switch to the "integrated" library feature of klayout (put the gds library in the folder library and give it a name) i believe that klayout is loading first the lib, then the PCell macro. Is it the case?

    By the way if i use your simple Pcell macro example (draw a circle, and use the "integrated" library fetaure, i have the same "wrong behaviour"


    I will try your suggestion and will come back to you

    Joël
  • edited November -1
    Hi Matthias,

    have tried your suggestion. works like a charm !! Thanks for your help and for your great work !!
    Maybe can i suggest you to put the early startup flag to true by default in your Pcell template?


    Regards
    Joël
  • edited November -1
    Hello again Matthias

    Think i got the real issue here.
    Actually i have tried your suggestion with my Pcell being in the local macro folder (identifeid as local in the macro window) and it works ok (even if i put only run on startup )
    Now i also have several directories setted in the KLAYOUT_PATH env variable.
    these directories appears as global directories in the macro window (the macro in theses directories being not anymore editable or modifyable)
    if i move my Pcell macro into the macro directory of one of these global directories, then the macro is not automatically started at klayout launch, whatever the flog startup or early startup is setted. I dunno if it is a behaviour of my klayout installation, but a collegue of mine see the same behaviour on his own computer.
    This also occur with the very simple pcell sample you provided...

    Regards
    JoËl
  • edited November -1
    Hi all

    issue is closed. Everything is working ok. Don't know what happened here, but it may be related to a synchronisation issue with the disk we were working on (network disk)

    Joël
  • edited November -1

    Hi Joel,

    thanks for this feedback. Let me know if you observe issues that are not network related.

    Regards,

    Matthias

Sign In or Register to comment.