mirror of https://github.com/KLayout/klayout.git
Merge pull request #1803 from KLayout/feature/issue-1790
Implemented a solution for issue #1790 (Support for recursive PCell i…
This commit is contained in:
commit
f4e4ce99b8
|
|
@ -272,6 +272,11 @@ module RBA
|
||||||
# of a PCell
|
# of a PCell
|
||||||
class PCellDeclarationHelper < PCellDeclaration
|
class PCellDeclarationHelper < PCellDeclaration
|
||||||
|
|
||||||
|
# makes PCellDeclaration's "layout" method available
|
||||||
|
if ! self.method_defined?(:_layout_base)
|
||||||
|
alias_method :_layout_base, :layout
|
||||||
|
end
|
||||||
|
|
||||||
# import the Type... constants from PCellParameterDeclaration
|
# import the Type... constants from PCellParameterDeclaration
|
||||||
PCellParameterDeclaration.constants.each do |c|
|
PCellParameterDeclaration.constants.each do |c|
|
||||||
if !const_defined?(c)
|
if !const_defined?(c)
|
||||||
|
|
@ -290,18 +295,58 @@ module RBA
|
||||||
@cell = nil
|
@cell = nil
|
||||||
@layer_param_index = []
|
@layer_param_index = []
|
||||||
@layers = nil
|
@layers = nil
|
||||||
|
@state_stack = []
|
||||||
end
|
end
|
||||||
|
|
||||||
# provide accessors for the current layout and cell (for prod)
|
# provide accessors for the current layout and cell (for prod)
|
||||||
attr_reader :layout, :cell, :shape, :layer
|
attr_reader :cell, :shape, :layer
|
||||||
|
|
||||||
|
def layout
|
||||||
|
@layout || _layout_base()
|
||||||
|
end
|
||||||
|
|
||||||
# provide fallback accessors in case of a name clash with a
|
# provide fallback accessors in case of a name clash with a
|
||||||
# parameter
|
# parameter
|
||||||
def _layer; @layer; end
|
def _layer; @layer; end
|
||||||
def _layout; @layout; end
|
def _layout; @layout || _layout_base(); end
|
||||||
def _cell; @cell; end
|
def _cell; @cell; end
|
||||||
def _shape; @shape; end
|
def _shape; @shape; end
|
||||||
|
|
||||||
|
# Starts an operation - pushes the state on the state stack
|
||||||
|
|
||||||
|
def start
|
||||||
|
@state_stack << [ @param_values, @param_states, @layers, @cell, @layout, @layer, @shape ]
|
||||||
|
self._reset_state
|
||||||
|
end
|
||||||
|
|
||||||
|
# Finishes an operation - pops the state from the state stack
|
||||||
|
|
||||||
|
def finish
|
||||||
|
if ! @state_stack.empty?
|
||||||
|
@param_values, @param_states, @layers, @cell, @layout, @layer, @shape = @state_stack.pop
|
||||||
|
else
|
||||||
|
self._reset_state
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Resets the state to default values
|
||||||
|
|
||||||
|
def _reset_state
|
||||||
|
|
||||||
|
@param_values = nil
|
||||||
|
@param_states = nil
|
||||||
|
@layers = nil
|
||||||
|
@layout = nil
|
||||||
|
|
||||||
|
# This should be here:
|
||||||
|
# @cell = nil
|
||||||
|
# @layer = nil
|
||||||
|
# @shape = nil
|
||||||
|
# but this would break backward compatibility of "display_text" (actually
|
||||||
|
# exploiting this bug) - fix this in the next major release.
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
# A helper method to access the nth parameter
|
# A helper method to access the nth parameter
|
||||||
|
|
||||||
def _get_param(nth, name)
|
def _get_param(nth, name)
|
||||||
|
|
@ -410,11 +455,13 @@ module RBA
|
||||||
|
|
||||||
# implementation of display_text
|
# implementation of display_text
|
||||||
def display_text(parameters)
|
def display_text(parameters)
|
||||||
|
self.start
|
||||||
@param_values = parameters
|
@param_values = parameters
|
||||||
|
text = ""
|
||||||
begin
|
begin
|
||||||
text = display_text_impl
|
text = display_text_impl
|
||||||
ensure
|
ensure
|
||||||
@param_values = nil
|
self.finish
|
||||||
end
|
end
|
||||||
text
|
text
|
||||||
end
|
end
|
||||||
|
|
@ -431,34 +478,33 @@ module RBA
|
||||||
|
|
||||||
# coerce parameters (make consistent)
|
# coerce parameters (make consistent)
|
||||||
def coerce_parameters(layout, parameters)
|
def coerce_parameters(layout, parameters)
|
||||||
|
self.start
|
||||||
@param_values = parameters
|
@param_values = parameters
|
||||||
@layout = layout
|
@layout = layout
|
||||||
ret = parameters
|
|
||||||
begin
|
begin
|
||||||
coerce_parameters_impl
|
coerce_parameters_impl
|
||||||
ensure
|
ensure
|
||||||
@layout = nil
|
|
||||||
ret = @param_values
|
ret = @param_values
|
||||||
@param_values = nil
|
self.finish
|
||||||
end
|
end
|
||||||
ret
|
ret
|
||||||
end
|
end
|
||||||
|
|
||||||
# parameter change callback
|
# parameter change callback
|
||||||
def callback(layout, name, states)
|
def callback(layout, name, states)
|
||||||
@param_values = nil
|
self.start
|
||||||
@param_states = states
|
@param_states = states
|
||||||
@layout = layout
|
@layout = layout
|
||||||
begin
|
begin
|
||||||
callback_impl(name)
|
callback_impl(name)
|
||||||
ensure
|
ensure
|
||||||
@param_states = nil
|
self.finish
|
||||||
@layout = nil
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# produce the layout
|
# produce the layout
|
||||||
def produce(layout, layers, parameters, cell)
|
def produce(layout, layers, parameters, cell)
|
||||||
|
self.start
|
||||||
@layers = layers
|
@layers = layers
|
||||||
@cell = cell
|
@cell = cell
|
||||||
@param_values = parameters
|
@param_values = parameters
|
||||||
|
|
@ -466,15 +512,13 @@ module RBA
|
||||||
begin
|
begin
|
||||||
produce_impl
|
produce_impl
|
||||||
ensure
|
ensure
|
||||||
@layers = nil
|
self.finish
|
||||||
@cell = nil
|
|
||||||
@param_values = nil
|
|
||||||
@layout = nil
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# produce a helper for can_create_from_shape
|
# produce a helper for can_create_from_shape
|
||||||
def can_create_from_shape(layout, shape, layer)
|
def can_create_from_shape(layout, shape, layer)
|
||||||
|
self.start
|
||||||
ret = false
|
ret = false
|
||||||
@layout = layout
|
@layout = layout
|
||||||
@shape = shape
|
@shape = shape
|
||||||
|
|
@ -482,24 +526,22 @@ module RBA
|
||||||
begin
|
begin
|
||||||
ret = can_create_from_shape_impl
|
ret = can_create_from_shape_impl
|
||||||
ensure
|
ensure
|
||||||
@layout = nil
|
self.finish
|
||||||
@shape = nil
|
|
||||||
@layer = nil
|
|
||||||
end
|
end
|
||||||
ret
|
ret
|
||||||
end
|
end
|
||||||
|
|
||||||
# produce a helper for parameters_from_shape
|
# produce a helper for transformation_from_shape
|
||||||
def transformation_from_shape(layout, shape, layer)
|
def transformation_from_shape(layout, shape, layer)
|
||||||
|
self.start
|
||||||
@layout = layout
|
@layout = layout
|
||||||
@shape = shape
|
@shape = shape
|
||||||
@layer = layer
|
@layer = layer
|
||||||
|
t = nil
|
||||||
begin
|
begin
|
||||||
t = transformation_from_shape_impl
|
t = transformation_from_shape_impl
|
||||||
ensure
|
ensure
|
||||||
@layout = nil
|
self.finish
|
||||||
@shape = nil
|
|
||||||
@layer = nil
|
|
||||||
end
|
end
|
||||||
t
|
t
|
||||||
end
|
end
|
||||||
|
|
@ -507,6 +549,7 @@ module RBA
|
||||||
# produce a helper for parameters_from_shape
|
# produce a helper for parameters_from_shape
|
||||||
# with this helper, the implementation can use the parameter setters
|
# with this helper, the implementation can use the parameter setters
|
||||||
def parameters_from_shape(layout, shape, layer)
|
def parameters_from_shape(layout, shape, layer)
|
||||||
|
self.start
|
||||||
@param_values = @param_decls.map { |pd| pd.default }
|
@param_values = @param_decls.map { |pd| pd.default }
|
||||||
@layout = layout
|
@layout = layout
|
||||||
@shape = shape
|
@shape = shape
|
||||||
|
|
@ -514,11 +557,10 @@ module RBA
|
||||||
begin
|
begin
|
||||||
parameters_from_shape_impl
|
parameters_from_shape_impl
|
||||||
ensure
|
ensure
|
||||||
@layout = nil
|
ret = @param_values
|
||||||
@shape = nil
|
self.finish
|
||||||
@layer = nil
|
|
||||||
end
|
end
|
||||||
@param_values
|
ret
|
||||||
end
|
end
|
||||||
|
|
||||||
# default implementation
|
# default implementation
|
||||||
|
|
|
||||||
|
|
@ -60,6 +60,7 @@ class _PCellDeclarationHelperMixin:
|
||||||
self._param_states = None
|
self._param_states = None
|
||||||
self._layer_param_index = []
|
self._layer_param_index = []
|
||||||
self._layers = []
|
self._layers = []
|
||||||
|
self._state_stack = []
|
||||||
# public attributes
|
# public attributes
|
||||||
self.layout = None
|
self.layout = None
|
||||||
self.shape = None
|
self.shape = None
|
||||||
|
|
@ -129,6 +130,7 @@ class _PCellDeclarationHelperMixin:
|
||||||
This function delegates the implementation to self.display_text_impl
|
This function delegates the implementation to self.display_text_impl
|
||||||
after configuring the PCellDeclaration object.
|
after configuring the PCellDeclaration object.
|
||||||
"""
|
"""
|
||||||
|
self.start()
|
||||||
self._param_values = parameters
|
self._param_values = parameters
|
||||||
try:
|
try:
|
||||||
text = self.display_text_impl()
|
text = self.display_text_impl()
|
||||||
|
|
@ -165,6 +167,7 @@ class _PCellDeclarationHelperMixin:
|
||||||
"layers" are the layer indexes corresponding to the layer
|
"layers" are the layer indexes corresponding to the layer
|
||||||
parameters.
|
parameters.
|
||||||
"""
|
"""
|
||||||
|
self.start()
|
||||||
self._param_values = None
|
self._param_values = None
|
||||||
self._param_states = None
|
self._param_states = None
|
||||||
if states:
|
if states:
|
||||||
|
|
@ -177,17 +180,39 @@ class _PCellDeclarationHelperMixin:
|
||||||
self._param_values = values
|
self._param_values = values
|
||||||
self._layers = layers
|
self._layers = layers
|
||||||
|
|
||||||
|
def start(self):
|
||||||
|
"""
|
||||||
|
Is called to prepare the environment for an operation
|
||||||
|
After the operation, "finish" must be called.
|
||||||
|
This method will push the state onto a stack, hence implementing
|
||||||
|
reentrant implementation methods.
|
||||||
|
"""
|
||||||
|
self._state_stack.append( (self._param_values, self._param_states, self._layers, self.cell, self.layout, self.layer, self.shape) )
|
||||||
|
self._reset_state()
|
||||||
|
|
||||||
def finish(self):
|
def finish(self):
|
||||||
"""
|
"""
|
||||||
Is called at the end of an implementation of a PCellDeclaration method
|
Is called at the end of an implementation of a PCellDeclaration method
|
||||||
"""
|
"""
|
||||||
|
if len(self._state_stack) > 0:
|
||||||
|
self._param_values, self._param_states, self._layers, self.cell, self.layout, self.layer, self.shape = self._state_stack.pop()
|
||||||
|
else:
|
||||||
|
self._reset_state()
|
||||||
|
|
||||||
|
def _reset_state(self):
|
||||||
|
"""
|
||||||
|
Resets the internal state
|
||||||
|
"""
|
||||||
self._param_values = None
|
self._param_values = None
|
||||||
self._param_states = None
|
self._param_states = None
|
||||||
self._layers = None
|
self._layers = None
|
||||||
self._cell = None
|
self.layout = super(_PCellDeclarationHelperMixin, self).layout()
|
||||||
self._layout = None
|
# This should be here:
|
||||||
self._layer = None
|
# self.cell = None
|
||||||
self._shape = None
|
# self.layer = None
|
||||||
|
# self.shape = None
|
||||||
|
# but this would break backward compatibility of "display_text" (actually
|
||||||
|
# exploiting this bug) - fix this in the next major release.
|
||||||
|
|
||||||
def get_layers(self, parameters):
|
def get_layers(self, parameters):
|
||||||
"""
|
"""
|
||||||
|
|
@ -255,6 +280,7 @@ class _PCellDeclarationHelperMixin:
|
||||||
The function delegates the implementation to can_create_from_shape_impl
|
The function delegates the implementation to can_create_from_shape_impl
|
||||||
after updating the state of this object with the current parameters.
|
after updating the state of this object with the current parameters.
|
||||||
"""
|
"""
|
||||||
|
self.start()
|
||||||
self.layout = layout
|
self.layout = layout
|
||||||
self.shape = shape
|
self.shape = shape
|
||||||
self.layer = layer
|
self.layer = layer
|
||||||
|
|
@ -271,6 +297,7 @@ class _PCellDeclarationHelperMixin:
|
||||||
The function delegates the implementation to transformation_from_shape_impl
|
The function delegates the implementation to transformation_from_shape_impl
|
||||||
after updating the state of this object with the current parameters.
|
after updating the state of this object with the current parameters.
|
||||||
"""
|
"""
|
||||||
|
self.start()
|
||||||
self.layout = layout
|
self.layout = layout
|
||||||
self.shape = shape
|
self.shape = shape
|
||||||
self.layer = layer
|
self.layer = layer
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@
|
||||||
|
|
||||||
import pya
|
import pya
|
||||||
import unittest
|
import unittest
|
||||||
|
import math
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
class BoxPCell(pya.PCellDeclaration):
|
class BoxPCell(pya.PCellDeclaration):
|
||||||
|
|
@ -77,7 +78,7 @@ class PCellTestLib(pya.Library):
|
||||||
sb_cell = self.layout().cell(sb_index)
|
sb_cell = self.layout().cell(sb_index)
|
||||||
sb_cell.shapes(l10).insert(pya.Box(0, 0, 100, 200))
|
sb_cell.shapes(l10).insert(pya.Box(0, 0, 100, 200))
|
||||||
|
|
||||||
# register us with the name "MyLib"
|
# register us with the name "PCellTestLib"
|
||||||
self.register("PCellTestLib")
|
self.register("PCellTestLib")
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -135,9 +136,62 @@ if "PCellDeclarationHelper" in pya.__dict__:
|
||||||
# create the PCell declarations
|
# create the PCell declarations
|
||||||
self.layout().register_pcell("Box2", BoxPCell2())
|
self.layout().register_pcell("Box2", BoxPCell2())
|
||||||
|
|
||||||
# register us with the name "MyLib"
|
# register us with the name "PCellTestLib2"
|
||||||
self.register("PCellTestLib2")
|
self.register("PCellTestLib2")
|
||||||
|
|
||||||
|
# A recursive PCell
|
||||||
|
|
||||||
|
class RecursivePCell(pya.PCellDeclarationHelper):
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
|
||||||
|
super(RecursivePCell, self).__init__()
|
||||||
|
|
||||||
|
self.param("layer", self.TypeLayer, "Layer", default = pya.LayerInfo(0, 0))
|
||||||
|
self.param("line", self.TypeShape, "Line", default = pya.Edge(0, 0, 10000, 0))
|
||||||
|
self.param("level", self.TypeInt, "Level", default = 1)
|
||||||
|
|
||||||
|
def display_text_impl(self):
|
||||||
|
# provide a descriptive text for the cell
|
||||||
|
return "RecursivePCell(L=" + str(self.layer) + ",E=" + str(pya.CplxTrans(self.layout.dbu) * self.line) + ",LVL=" + str(self.level)
|
||||||
|
|
||||||
|
def produce_impl(self):
|
||||||
|
|
||||||
|
# fetch the parameters
|
||||||
|
l = self.layer_layer
|
||||||
|
e = self.line
|
||||||
|
|
||||||
|
if self.level <= 0:
|
||||||
|
self.cell.shapes(l).insert(e)
|
||||||
|
return
|
||||||
|
|
||||||
|
d3 = e.d() * (1.0 / 3.0)
|
||||||
|
d3n = pya.Vector(-d3.y, d3.x)
|
||||||
|
|
||||||
|
e1 = pya.Edge(e.p1, e.p1 + d3)
|
||||||
|
e2 = pya.Edge(e1.p2, e1.p2 + d3 * 0.5 + d3n * math.cos(math.pi / 6))
|
||||||
|
e3 = pya.Edge(e2.p2, e.p1 + d3 * 2.0)
|
||||||
|
e4 = pya.Edge(e3.p2, e.p2)
|
||||||
|
|
||||||
|
for e in [ e1, e2, e3, e4 ]:
|
||||||
|
t = pya.Trans(e.p1 - pya.Point())
|
||||||
|
cc = self.layout.create_cell("RecursivePCell", { "layer": self.layer, "line": t.inverted() * e, "level": self.level - 1 })
|
||||||
|
self.cell.insert(pya.CellInstArray(cc, t))
|
||||||
|
|
||||||
|
class PCellTestLib3(pya.Library):
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
|
||||||
|
# set the description
|
||||||
|
self.description = "PCell test lib3"
|
||||||
|
|
||||||
|
# create the PCell declarations
|
||||||
|
self.layout().register_pcell("RecursivePCell", RecursivePCell())
|
||||||
|
|
||||||
|
# register us with the name "PCellTestLib3"
|
||||||
|
self.register("PCellTestLib3")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def inspect_LayerInfo(self):
|
def inspect_LayerInfo(self):
|
||||||
return "<" + str(self) + ">"
|
return "<" + str(self) + ">"
|
||||||
|
|
@ -501,6 +555,27 @@ class DBPCellTests(unittest.TestCase):
|
||||||
|
|
||||||
self.assertEqual(cell.begin_shapes_rec(ly.layer(5, 0)).shape().__str__(), "box (-100,-300;100,300)")
|
self.assertEqual(cell.begin_shapes_rec(ly.layer(5, 0)).shape().__str__(), "box (-100,-300;100,300)")
|
||||||
|
|
||||||
|
def test_9(self):
|
||||||
|
|
||||||
|
if not "PCellDeclarationHelper" in pya.__dict__:
|
||||||
|
return
|
||||||
|
|
||||||
|
# instantiate and register the library
|
||||||
|
tl = PCellTestLib3()
|
||||||
|
|
||||||
|
ly = pya.Layout(True)
|
||||||
|
|
||||||
|
li1 = find_layer(ly, "1/0")
|
||||||
|
self.assertEqual(li1 == None, True)
|
||||||
|
|
||||||
|
c1 = ly.create_cell("c1")
|
||||||
|
|
||||||
|
c2 = ly.create_cell("RecursivePCell", "PCellTestLib3", { "layer": pya.LayerInfo(1, 0), "level": 4, "line": pya.Edge(0, 0, 20000, 0) })
|
||||||
|
c1.insert(pya.CellInstArray(c2.cell_index(), pya.Trans()))
|
||||||
|
|
||||||
|
self.assertEqual(c2.display_title(), "PCellTestLib3.RecursivePCell(L=1/0,E=(0,0;20,0),LVL=4")
|
||||||
|
self.assertEqual(str(c1.dbbox()), "(0,0;20,5.774)")
|
||||||
|
|
||||||
# run unit tests
|
# run unit tests
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
suite = unittest.TestLoader().loadTestsFromTestCase(DBPCellTests)
|
suite = unittest.TestLoader().loadTestsFromTestCase(DBPCellTests)
|
||||||
|
|
|
||||||
|
|
@ -170,6 +170,71 @@ if RBA.constants.member?(:PCellDeclarationHelper)
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# A recursive PCell
|
||||||
|
|
||||||
|
class RecursivePCell < RBA::PCellDeclarationHelper
|
||||||
|
|
||||||
|
def initialize
|
||||||
|
|
||||||
|
super()
|
||||||
|
|
||||||
|
param("layer", RecursivePCell::TypeLayer, "Layer", :default => RBA::LayerInfo::new(0, 0))
|
||||||
|
param("line", RecursivePCell::TypeShape, "Line", :default => RBA::Edge::new(0, 0, 10000, 0))
|
||||||
|
param("level", RecursivePCell::TypeInt, "Level", :default => 1)
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
def display_text_impl
|
||||||
|
# provide a descriptive text for the cell
|
||||||
|
return "RecursivePCell(L=" + self.layer.to_s + ",E=" + (RBA::CplxTrans::new(self.layout.dbu) * self.line).to_s + ",LVL=" + self.level.to_s
|
||||||
|
end
|
||||||
|
|
||||||
|
def produce_impl
|
||||||
|
|
||||||
|
# fetch the parameters
|
||||||
|
l = self.layer_layer
|
||||||
|
e = self.line
|
||||||
|
|
||||||
|
if self.level <= 0
|
||||||
|
self.cell.shapes(l).insert(e)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
d3 = e.d * (1.0 / 3.0)
|
||||||
|
d3n = RBA::Vector::new(-d3.y, d3.x)
|
||||||
|
|
||||||
|
e1 = RBA::Edge::new(e.p1, e.p1 + d3)
|
||||||
|
e2 = RBA::Edge::new(e1.p2, e1.p2 + d3 * 0.5 + d3n * Math::cos(Math::PI / 6))
|
||||||
|
e3 = RBA::Edge::new(e2.p2, e.p1 + d3 * 2.0)
|
||||||
|
e4 = RBA::Edge::new(e3.p2, e.p2)
|
||||||
|
|
||||||
|
[ e1, e2, e3, e4 ].each do |e|
|
||||||
|
t = RBA::Trans::new(e.p1 - RBA::Point::new)
|
||||||
|
cc = self.layout.create_cell("RecursivePCell", { "layer" => self.layer, "line" => t.inverted * e, "level" => self.level - 1 })
|
||||||
|
self.cell.insert(RBA::CellInstArray::new(cc, t))
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
class PCellTestLib3 < RBA::Library
|
||||||
|
|
||||||
|
def initialize
|
||||||
|
|
||||||
|
# set the description
|
||||||
|
self.description = "PCell test lib3"
|
||||||
|
|
||||||
|
# create the PCell declarations
|
||||||
|
self.layout().register_pcell("RecursivePCell", RecursivePCell::new)
|
||||||
|
|
||||||
|
# register us with the name "PCellTestLib3"
|
||||||
|
self.register("PCellTestLib3")
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# A helper for testing: provide an inspect method
|
# A helper for testing: provide an inspect method
|
||||||
|
|
@ -809,6 +874,30 @@ class DBPCell_TestClass < TestBase
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_12
|
||||||
|
|
||||||
|
if !RBA.constants.member?(:PCellDeclarationHelper)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
# instantiate and register the library
|
||||||
|
tl = PCellTestLib3::new
|
||||||
|
|
||||||
|
ly = RBA::Layout::new
|
||||||
|
|
||||||
|
li1 = ly.find_layer("1/0")
|
||||||
|
assert_equal(li1 == nil, true)
|
||||||
|
|
||||||
|
c1 = ly.create_cell("c1")
|
||||||
|
|
||||||
|
c2 = ly.create_cell("RecursivePCell", "PCellTestLib3", { "layer" => RBA::LayerInfo::new(1, 0), "level" => 4, "line" => RBA::Edge::new(0, 0, 20000, 0) })
|
||||||
|
c1.insert(RBA::CellInstArray::new(c2.cell_index(), RBA::Trans::new))
|
||||||
|
|
||||||
|
assert_equal(c2.display_title, "PCellTestLib3.RecursivePCell(L=1/0,E=(0,0;20,0),LVL=4")
|
||||||
|
assert_equal(c1.dbbox.to_s, "(0,0;20,5.774)")
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
load("test_epilogue.rb")
|
load("test_epilogue.rb")
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue