It looks like you're new here. If you want to get involved, click one of these buttons!
Hi Matthias,
To test the concept of using PCells inside PCells, I made a PCell test library "TestLib2" with two PCells: "Rectangle" and "RectangleArray", where PCell "Rectangle" is used inside PCell "RectangleArray". The code is attached below. It works well. The only thing I notice is that the PCell "Rectangle" is named TestLib2.Testlib2.Rectangle(...) where I would expect Testlib2.Rectangle(...). Is the code ok? I based it on the circle example found in the documentation.
Thank you in advance!
Kind regards,
Tomas
# Test Library 2
module TestLib2
include RBA
# Remove any definition of our classes (this helps when
# reexecuting this code after a change has been applied)
TestLib2.constants.member?(:Rectangle) && remove_const(:Rectangle)
TestLib2.constants.member?(:RectangleArray) && remove_const(:RectangleArray)
TestLib2.constants.member?(:TestLib2) && remove_const(:TestLib2)
# -------------------------------------------------------------------------------
# The PCell declaration for the rectangle
class Rectangle < PCellDeclarationHelper
include RBA
def initialize
# Important: initialize the super class
super
# declare the parameters
param(:l, TypeLayer, "Layer", :default => LayerInfo::new(1, 0))
param(:w, TypeDouble, "Width", :default => 1.0)
param(:h, TypeDouble, "Height", :default => 1.0)
end
def display_text_impl
# Provide a descriptive text for the cell
"Rectangle(L=#{l.to_s},W=#{'%.3f' % w.to_f},H=#{'%.3f' % h.to_f})"
end
def produce_impl
# This is the main part of the implementation: create the layout
# create the rectangle
p1=DPoint.new(-w / 2,-h / 2)
p2=DPoint.new(-w / 2,h / 2)
p3=DPoint.new(w / 2,h / 2)
p4=DPoint.new(w / 2,-h / 2)
pts=[p1,p2,p3,p4]
# create the shape
cell.shapes(l_layer).insert(DPolygon.new(pts))
end
end
# -------------------------------------------------------------------------------
# The PCell declaration for the rectangle array
class RectangleArray < PCellDeclarationHelper
include RBA
def initialize
# Important: initialize the super class
super
# declare the parameters
param(:l, TypeLayer, "Layer", :default => LayerInfo::new(1, 0))
param(:w, TypeDouble, "Width", :default => 20.0)
param(:h, TypeDouble, "Height", :default => 20.0)
param(:n, TypeInt, "Number of rectangles", :default => 10)
param(:p, TypeDouble, "Pitch", :default => 200.0)
end
def display_text_impl
# Provide a descriptive text for the cell
"RectangleArray(L=#{l.to_s},W=#{'%.3f' % w.to_f},H=#{'%.3f' % h.to_f},N=#{n.to_i},P=#{'%.3f' % p.to_f})"
end
def produce_impl
# This is the main part of the implementation: create the layout
# find the lib
lib = RBA::Library.library_by_name("TestLib2")
lib || raise("Unknown lib 'TestLib2'")
# find the pcell
pcell_decl = lib.layout.pcell_declaration("Rectangle")
pcell_decl || raise("Unknown PCell 'Rectangle'")
for i in 1..n do
# set the parameters
param = { "l" => l, "w" => w*i, "h" => h*i}
# build a param array using the param hash as a source
pv = pcell_decl.get_parameters.collect do |p|
param[p.name] || p.default
end
# create a PCell variant cell
pcell_var = layout.add_pcell_variant(lib, pcell_decl.id, pv)
# instantiate that cell
xcoord = p*(i-1)
ycoord = 0.0
t = RBA::DTrans::new(DPoint.new(xcoord, ycoord))
cell.insert(RBA::DCellInstArray::new(pcell_var, t))
end
end
end
# -------------------------------------------------------------------------------
# The library where we will put the PCell into
class TestLib2 < Library
def initialize
# Set the description
self.description = "Test Library 2"
# initialize the database unit (line added ~ default is 0.001):
layout.dbu = 0.0001
# Create the PCell declarations
layout.register_pcell("Rectangle", Rectangle::new)
layout.register_pcell("RectangleArray", RectangleArray::new)
# Register us with the name "TestLib2".
# If a library with that name already existed, it will be replaced then.
register("TestLib2")
end
end
# Instantiate and register the library
TestLib2::new
end
Comments
Hi Thomas,
Thanks for sharing this code. About the name, I'd not worry ... this is a generated "speaking" description and that does not have impact on the functionality.
If you want to avoid this you can take the PCell directly from the current layout:
This works because the "layout" object isn't the target layout but the layout object of the library. It's finally mirror into the drawn layout.
I observed a crash while playing with your original code once after re-executing the script ... so I need to say that embedding PCells in other PCells leads to tricky interactions and debugging is kind of difficult. If you do this, I'd advise not to use the built-in debugger.
Kind regards,
Matthias