Merge pull request #2199 from KLayout/feature/issue-2195

Feature/issue 2195
This commit is contained in:
Matthias Köfferlein 2025-10-26 16:35:14 +01:00 committed by GitHub
commit ff49a81723
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
19 changed files with 376 additions and 36 deletions

View File

@ -149,6 +149,18 @@ created as well.
This method must be reimplemented in a PCell class to identify the PCell in human-readable form.
This text is shown in the cell tree for the PCell for example.
@method cell_name_impl
@brief Delivers the cell name to be used for the PCell variant
A PCell variant is represented in the cell tree by a placeholder cell. By
default, the name of this cell is the PCell name. Since multiple variants
may exist, usually a disambiguator is added to the name (e.g. "..$1").
This method allows encoding the PCell parameters into that cell name,
so the PCell variant is easier to identify in the cell tree - for example
in the GDS file - instead of the unspecific disambiguator.
@method produce_impl
@brief Produces the layout
@ -466,6 +478,19 @@ module RBA
text
end
# implementation of cell_name
def cell_name(parameters)
self._start
@param_values = parameters
text = ""
begin
text = cell_name_impl
ensure
self._finish
end
text
end
# get the parameters
def get_parameters
@param_decls
@ -568,6 +593,11 @@ module RBA
""
end
# default implementation
def cell_name_impl
self.name
end
# default implementation
def coerce_parameters_impl
end

View File

@ -158,6 +158,18 @@ created as well.
This method must be reimplemented in a PCell class to identify the PCell in human-readable form.
This text is shown in the cell tree for the PCell for example.
@method cell_name_impl
@brief Delivers the cell name to be used for the PCell variant
A PCell variant is represented in the cell tree by a placeholder cell. By
default, the name of this cell is the PCell name. Since multiple variants
may exist, usually a disambiguator is added to the name (e.g. "..$1").
This method allows encoding the PCell parameters into that cell name,
so the PCell variant is easier to identify in the cell tree - for example
in the GDS file - instead of the unspecific disambiguator.
@method produce_impl
@brief Produces the layout

View File

@ -862,6 +862,12 @@ Cell::get_basic_name () const
return layout ()->cell_name (cell_index ());
}
std::string
Cell::get_variant_name () const
{
return get_basic_name ();
}
std::string
Cell::get_qualified_name () const
{

View File

@ -890,7 +890,7 @@ public:
void set_name (const std::string &name);
/**
* @brief Get the basic name
* @brief Gets the basic name
*
* The basic name of the cell is either the cell name or the cell name in the
* target library (for library proxies) or the PCell name (for PCell proxies).
@ -898,6 +898,14 @@ public:
*/
virtual std::string get_basic_name () const;
/**
* @brief Gets the variant name
*
* The variant name is the PCell's "cell_name" - which may encode the PCell parameters
* into a formal name. Usually that is identical to the PCell name.
*/
virtual std::string get_variant_name () const;
/**
* @brief Gets the display name
*

View File

@ -89,7 +89,7 @@ ColdProxy::get_basic_name () const
}
}
std::string
std::string
ColdProxy::get_display_name () const
{
if (! mp_context_info->lib_name.empty ()) {

View File

@ -2462,7 +2462,7 @@ Layout::get_pcell_variant_dict (pcell_id_type pcell_id, const std::map<std::stri
pcell_variant_type *variant = header->get_variant (*this, parameters);
if (! variant) {
std::string b (header->get_name ());
std::string b (header->declaration ()->get_cell_name (parameters));
if (m_cell_map.find (b.c_str ()) != m_cell_map.end ()) {
b = uniquify_cell_name (b.c_str ());
}
@ -2501,7 +2501,7 @@ Layout::get_pcell_variant (pcell_id_type pcell_id, const std::vector<tl::Variant
pcell_variant_type *variant = header->get_variant (*this, parameters);
if (! variant) {
std::string b (header->get_name ());
std::string b (header->declaration ()->get_cell_name (parameters));
if (m_cell_map.find (b.c_str ()) != m_cell_map.end ()) {
b = uniquify_cell_name (b.c_str ());
}
@ -2627,9 +2627,18 @@ Layout::convert_cell_to_static (db::cell_index_type ci)
const cell_type &org_cell = cell (ci);
// Note: convert to static cell by explicitly cloning to the db::Cell class
ret_ci = add_cell (org_cell.get_basic_name ().c_str ());
std::string vn = org_cell.get_variant_name ();
if (vn == std::string (cell_name (ci), vn.size ())) {
// there is a cell name conflict: give priority to the static cell, so it
// will see the variant name or at least the original disambiguated name
std::string rename_org = uniquify_cell_name (vn.c_str ());
vn = cell_name (ci);
rename_cell (ci, rename_org.c_str ());
}
ret_ci = add_cell (vn.c_str ());
cell_type &new_cell = cell (ret_ci);
// Note: we convert to static cell by explicitly converting to the db::Cell class
new_cell = org_cell;
new_cell.set_cell_index (ret_ci);
@ -3126,6 +3135,12 @@ Layout::basic_name (cell_index_type cell_index) const
return cell (cell_index).get_basic_name ();
}
std::string
Layout::variant_name (cell_index_type cell_index) const
{
return cell (cell_index).get_variant_name ();
}
void
Layout::register_lib_proxy (db::LibraryProxy *lib_proxy)
{
@ -3161,7 +3176,7 @@ Layout::get_lib_proxy (Library *lib, cell_index_type cell_index)
} else {
// create a new unique name
std::string b (lib->layout ().basic_name (cell_index));
std::string b (lib->layout ().variant_name (cell_index));
if (m_cell_map.find (b.c_str ()) != m_cell_map.end ()) {
b = uniquify_cell_name (b.c_str ());
}

View File

@ -675,7 +675,7 @@ public:
std::string display_name (cell_index_type cell_index) const;
/**
* @brief Return the basic name for the given cell
* @brief Returns the basic name for the given cell
*
* This method is forwarded to the respective method of the cell.
* The basic name is the "original" cell name within the library or
@ -684,7 +684,16 @@ public:
*/
std::string basic_name (cell_index_type cell_index) const;
/**
/**
* @brief Returns the variant name for the given cell
*
* The variant name usually is the basic name. For PCells, this name
* can encode PCell parameters, depending on the definition of the
* PCell.
*/
std::string variant_name (cell_index_type cell_index) const;
/**
* @brief Add a cell object with the given ID and name
*
* This method is basically supposed to be used for "undo" and "redo".

View File

@ -257,7 +257,23 @@ LibraryProxy::get_basic_name () const
}
}
std::string
std::string
LibraryProxy::get_variant_name () const
{
Library *lib = LibraryManager::instance ().lib (lib_id ());
if (lib) {
if (! lib->layout ().is_valid_cell_index (library_cell_index ())) {
return "<defunct>";
} else {
const db::Cell &lib_cell = lib->layout ().cell (library_cell_index ());
return lib_cell.get_variant_name ();
}
} else {
return Cell::get_variant_name ();
}
}
std::string
LibraryProxy::get_display_name () const
{
Library *lib = LibraryManager::instance ().lib (lib_id ());

View File

@ -96,25 +96,28 @@ public:
/**
* @brief Gets the basic name
*
* The basic name of the cell is either the cell name or the cell name in the
* target library (for library proxies) or the PCell name (for PCell proxies).
* The actual name may be different by a extension to make it unique.
* This returns the basic name of the proxy target
*/
virtual std::string get_basic_name () const;
/**
* @brief Gets the variant name
*
* This returns the basic name of the proxy target
*/
virtual std::string get_variant_name () const;
/**
* @brief Gets the display name
*
* The display name is some "nice" descriptive name of the cell (variant)
* For normal cells this name is equivalent to the normal cell name.
* This returns the basic name of the proxy target
*/
virtual std::string get_display_name () const;
/**
* @brief Gets the qualified name
*
* The qualified name for a library proxy is made from the library name, a
* dot and the cell's name.
* Gets a combination of the library name and the target cell's qualified name
*/
virtual std::string get_qualified_name () const;

View File

@ -673,6 +673,18 @@ public:
return std::string ();
}
/**
* @brief Gets a cell name for the PCell, which can depend on the parameters
*
* The actual cell name in the layout may differ by disambiguation. This method
* delivers a proposal for a cell name.
* By default, the PCell name is returned.
*/
virtual std::string get_cell_name (const pcell_parameters_type &) const
{
return m_name;
}
/**
* @brief Returns the description text of the PCell
*

View File

@ -86,7 +86,18 @@ PCellVariant::get_basic_name () const
}
}
std::string
std::string
PCellVariant::get_variant_name () const
{
const PCellHeader *header = pcell_header ();
if (header) {
return m_variant_name;
} else {
return Cell::get_basic_name ();
}
}
std::string
PCellVariant::get_display_name () const
{
const PCellHeader *header = pcell_header ();
@ -172,6 +183,7 @@ PCellVariant::update (ImportLayerMapping *layer_mapping)
header->declaration ()->produce (*layout (), layer_ids, plist, *this);
m_display_name = header->declaration ()->get_display_name (plist);
m_variant_name = header->declaration ()->get_cell_name (plist);
} catch (tl::Exception &ex) {

View File

@ -94,42 +94,37 @@ public:
}
/**
* @brief Get the basic name
*
* The basic name of the cell is either the cell name or the cell name in the
* target library (for library proxies) or the PCell name (for PCell proxies).
* The actual name may be different by a extension to make it unique.
* @brief Gets the basic name
*/
virtual std::string get_basic_name () const;
/**
* @brief Get the display name
*
* The display name is some "nice" descriptive name of the cell (variant)
* For normal cells this name is equivalent to the normal cell name.
* @brief Gets the variant name
*/
virtual std::string get_variant_name () const;
/**
* @brief Gets the display name
*/
virtual std::string get_display_name () const;
/**
* @brief Unregister a cell from it's context.
* @brief Unregisters a cell from its context.
*/
virtual void unregister ();
/**
* @brief Reregister a cell inside it's context.
* @brief Re-registers a cell inside its context.
*/
virtual void reregister ();
/**
* @brief Update the layout
* @brief Updates the layout
*/
virtual void update (ImportLayerMapping *layer_mapping = 0);
/**
* @brief Tell, if this cell is a proxy cell
*
* Proxy cells are such whose layout represents a snapshot of another entity.
* Such cells can be PCell variants or library references for example.
* @brief Gets a value indicating if this cell is a proxy cell
*/
virtual bool is_proxy () const
{
@ -138,7 +133,7 @@ public:
protected:
/**
* @brief Get the PCell header for this variant
* @brief Gets the PCell header for this variant
*/
PCellHeader *pcell_header ()
{
@ -146,7 +141,7 @@ protected:
}
/**
* @brief Get the PCell header for this variant
* @brief Gets the PCell header for this variant
*/
const PCellHeader *pcell_header () const
{
@ -156,6 +151,7 @@ protected:
private:
pcell_parameters_type m_parameters;
mutable std::string m_display_name;
mutable std::string m_variant_name;
db::pcell_id_type m_pcell_id;
bool m_registered;
};

View File

@ -368,6 +368,7 @@ Class<db::PCellDeclaration> decl_PCellDeclaration_Native ("db", "PCellDeclaratio
gsi::method ("via_types", &db::PCellDeclaration::via_types) +
gsi::method ("description", &db::PCellDeclaration::get_description) +
gsi::method ("display_text", &db::PCellDeclaration::get_display_name, gsi::arg ("parameters")) +
gsi::method ("cell_name", &db::PCellDeclaration::get_cell_name, gsi::arg ("parameters")) +
gsi::method ("layout", &db::PCellDeclaration::layout,
"@brief Gets the Layout object the PCell is registered in or nil if it is not registered yet.\n"
"This attribute has been added in version 0.27.5."
@ -659,6 +660,20 @@ public:
}
}
std::string get_cell_name_fb (const db::pcell_parameters_type &parameters) const
{
return db::PCellDeclaration::get_cell_name (parameters);
}
virtual std::string get_cell_name (const db::pcell_parameters_type &parameters) const
{
if (cb_get_cell_name.can_issue ()) {
return cb_get_cell_name.issue<db::PCellDeclaration, std::string, const db::pcell_parameters_type &> (&db::PCellDeclaration::get_cell_name, parameters);
} else {
return db::PCellDeclaration::get_cell_name (parameters);
}
}
gsi::Callback cb_get_layer_declarations;
gsi::Callback cb_get_parameter_declarations;
gsi::Callback cb_produce;
@ -669,6 +684,7 @@ public:
gsi::Callback cb_coerce_parameters;
gsi::Callback cb_callback;
gsi::Callback cb_get_display_name;
gsi::Callback cb_get_cell_name;
gsi::Callback cb_get_description;
gsi::Callback cb_via_types;
};
@ -682,6 +698,7 @@ Class<PCellDeclarationImpl> decl_PCellDeclaration (decl_PCellDeclaration_Native,
gsi::method ("parameters_from_shape", &PCellDeclarationImpl::parameters_from_shape_fb, "@hide") +
gsi::method ("transformation_from_shape", &PCellDeclarationImpl::transformation_from_shape_fb, "@hide") +
gsi::method ("display_text", &PCellDeclarationImpl::get_display_name_fb, "@hide") +
gsi::method ("cell_name", &PCellDeclarationImpl::get_cell_name_fb, "@hide") +
gsi::method ("wants_lazy_evaluation", &PCellDeclarationImpl::wants_lazy_evaluation_fb, "@hide") +
gsi::method ("description", &PCellDeclarationImpl::get_description_fb, "@hide") +
gsi::method ("via_types", &PCellDeclarationImpl::via_types_fb, "@hide") +
@ -809,6 +826,13 @@ Class<PCellDeclarationImpl> decl_PCellDeclaration (decl_PCellDeclaration_Native,
"@brief Returns the display text for this PCell given a certain parameter set\n"
"Reimplement this method to create a distinct display text for a PCell variant with \n"
"the given parameter set. If this method is not implemented, a default text is created. \n"
) +
gsi::callback ("cell_name", &PCellDeclarationImpl::get_cell_name, &PCellDeclarationImpl::cb_get_cell_name, gsi::arg ("parameters"),
"@brief Returns a cell name used for the PCell variant\n"
"Reimplement this method to create a cell name the system uses for the PCell variant. By default that is the PCell name.\n"
"This feature allows encoding the PCell parameters into the cell name for easier identification of the PCell variant in a cell tree.\n"
"\n"
"This feature has been added in version 0.30.5.\n"
),
"@brief A PCell declaration providing the parameters and code to produce the PCell\n"
"\n"

View File

@ -88,6 +88,13 @@ class PD
cell.shapes (l_metal0).insert (db::Box (0, 0, width, height));
}
virtual std::string get_display_name (const db::pcell_parameters_type &parameters) const
{
db::Coord width = db::coord_traits<db::Coord>::rounded (parameters[0].to_double () * 1000.0);
db::Coord height = db::coord_traits<db::Coord>::rounded (parameters[1].to_double () * 1000.0);
return tl::sprintf ("PD(W=%d,H=%d)", width, height);
}
};
TEST(0)
@ -252,3 +259,114 @@ TEST(1)
}
}
// PCell names, convert PCell to static
class PD2
: public PD
{
public:
virtual std::string get_cell_name (const db::pcell_parameters_type &parameters) const
{
db::Coord width = db::coord_traits<db::Coord>::rounded (parameters[0].to_double () * 1000.0);
db::Coord height = db::coord_traits<db::Coord>::rounded (parameters[1].to_double () * 1000.0);
return tl::sprintf ("PD_W%d_H%d", width, height);
}
};
TEST(2)
{
db::Manager m (true);
db::Layout layout(&m);
layout.dbu (0.001);
db::LayerProperties p;
p.layer = 23;
p.datatype = 0;
unsigned int l_cont = layout.insert_layer (p);
p.layer = 16;
p.datatype = 0;
unsigned int l_gate = layout.insert_layer (p);
db::Cell &cell_a = layout.cell (layout.add_cell ("A"));
cell_a.shapes(l_cont).insert(db::Box (50, 50, 150, 150));
cell_a.shapes(l_gate).insert(db::Box (0, 0, 200, 1000));
db::Cell &top = layout.cell (layout.add_cell ("TOP"));
db::pcell_id_type pd = layout.register_pcell ("PD", new PD2 ());
std::vector<tl::Variant> parameters;
parameters.push_back (tl::Variant ());
parameters.push_back (tl::Variant ());
parameters.push_back (tl::Variant ());
tl::Variant &width = parameters[0];
tl::Variant &height = parameters[1];
tl::Variant &orientation = parameters[2];
width = 0.5;
height = 1.0;
orientation = long (0);
db::cell_index_type pd1 = layout.get_pcell_variant (pd, parameters);
top.insert (db::CellInstArray (db::CellInst (pd1), db::Trans (db::Vector (0, 0))));
EXPECT_EQ (layout.display_name (pd1), "PD(W=500,H=1000)");
EXPECT_EQ (layout.cell_name (pd1), "PD_W500_H1000");
EXPECT_EQ (layout.variant_name (pd1), "PD_W500_H1000");
width = 0.4;
height = 0.8;
db::cell_index_type pd2 = layout.get_pcell_variant (pd, parameters);
top.insert (db::CellInstArray (db::CellInst (pd2), db::Trans (db::Vector (0, 2000))));
EXPECT_EQ (layout.display_name (pd2), "PD(W=400,H=800)");
EXPECT_EQ (layout.cell_name (pd2), "PD_W400_H800");
EXPECT_EQ (layout.variant_name (pd2), "PD_W400_H800");
EXPECT_NE (pd1, pd2);
width = 0.4;
height = 0.8;
orientation = long (1);
db::cell_index_type pd3 = layout.get_pcell_variant (pd, parameters);
auto i3 = top.insert (db::CellInstArray (db::CellInst (pd3), db::Trans (db::Vector (2000, 0))));
EXPECT_EQ (layout.display_name (pd3), "PD(W=400,H=800)");
EXPECT_EQ (layout.cell_name (pd3), "PD_W400_H800$1");
EXPECT_EQ (layout.variant_name (pd3), "PD_W400_H800");
EXPECT_NE (pd2, pd3);
auto pd3_org = pd3;
pd3 = layout.convert_cell_to_static (pd3);
EXPECT_NE (pd3, pd3_org);
auto ci3 = i3.cell_inst ();
ci3.object ().cell_index (pd3);
top.replace (i3, ci3);
EXPECT_EQ (layout.cell (pd3_org).is_proxy (), true);
EXPECT_EQ (layout.cell (pd3).is_proxy (), false);
EXPECT_EQ (layout.display_name (pd3_org), "PD(W=400,H=800)");
EXPECT_EQ (layout.cell_name (pd3_org), "PD_W400_H800$2");
EXPECT_EQ (layout.variant_name (pd3_org), "PD_W400_H800");
layout.do_cleanup (true);
layout.cleanup ();
EXPECT_EQ (layout.is_valid_cell_index (pd3_org), false);
EXPECT_EQ (layout.display_name (pd3), "PD_W400_H800$1");
EXPECT_EQ (layout.cell_name (pd3), "PD_W400_H800$1");
EXPECT_EQ (layout.variant_name (pd3), "PD_W400_H800$1");
CHECKPOINT ();
db::compare_layouts (_this, layout, tl::testdata () + "/gds/pcell_test20.gds", db::NoNormalization);
}

View File

@ -138,6 +138,21 @@ class _PCellDeclarationHelperMixin:
self._finish()
return text
def cell_name(self, parameters):
"""
Reimplementation of PCellDeclaration.cell_name
This function delegates the implementation to self.cell_name_impl
after configuring the PCellDeclaration object.
"""
self._start()
self._param_values = parameters
try:
text = self.cell_name_impl()
finally:
self._finish()
return text
def get_parameters(self):
"""
Reimplementation of PCellDeclaration.get_parameters
@ -333,6 +348,12 @@ class _PCellDeclarationHelperMixin:
"""
return ""
def cell_name_impl(self):
"""
default implementation
"""
return self.name()
def coerce_parameters_impl(self):
"""
default implementation

Binary file not shown.

BIN
testdata/gds/pcell_test20.gds vendored Normal file

Binary file not shown.

View File

@ -27,6 +27,10 @@ class BoxPCell(pya.PCellDeclaration):
# provide a descriptive text for the cell
return "Box(L=" + str(parameters[0]) + ",W=" + ('%.3f' % parameters[1]) + ",H=" + ('%.3f' % parameters[2]) + ")"
def cell_name(self, parameters):
# provide a descriptive text for the cell
return "Box_L" + str(parameters[0]).replace("/", "d") + "_W" + ('%.3f' % parameters[1]).replace(".", "p") + "_H" + ('%.3f' % parameters[2]).replace(".", "p")
def get_parameters(self):
# prepare a set of parameter declarations
@ -100,6 +104,10 @@ if "PCellDeclarationHelper" in pya.__dict__:
# provide a descriptive text for the cell
return "Box2(L=" + str(self.layer) + ",W=" + ('%.3f' % self.width) + ",H=" + ('%.3f' % self.height) + ")"
def cell_name_impl(self):
# provide a descriptive text for the cell
return "Box2_L" + str(self.layer).replace("/", "d") + "_W" + ('%.3f' % self.width).replace(".", "p") + "_H" + ('%.3f' % self.height).replace(".", "p")
def wants_lazy_evaluation(self):
return True
@ -260,6 +268,8 @@ class DBPCellTests(unittest.TestCase):
self.assertEqual(pcell_var.is_pcell_variant(), True)
self.assertEqual(pcell_var.display_title(), "PCellTestLib.Box(L=1/0,W=1.000,H=1.000)")
self.assertEqual(pcell_var.basic_name(), "Box")
self.assertEqual(pcell_var.qname(), "PCellTestLib.Box")
self.assertEqual(pcell_var.name, "Box_L1d0_W1p000_H1p000")
self.assertEqual(pcell_var.pcell_declaration().wants_lazy_evaluation(), False)
self.assertEqual(c1.is_pcell_variant(), False)
self.assertEqual(c1.is_pcell_variant(pcell_inst), True)
@ -394,6 +404,8 @@ class DBPCellTests(unittest.TestCase):
pcell_var = ly.cell(pcell_var_id)
pcell_inst = c1.insert(pya.CellInstArray(pcell_var_id, pya.Trans()))
self.assertEqual(pcell_var.basic_name(), "Box2")
self.assertEqual(pcell_var.name, "Box2_L1d0_W1p000_H1p000")
self.assertEqual(pcell_var.qname(), "PCellTestLib2.Box2")
self.assertEqual(pcell_var.pcell_parameters().__repr__(), "[<1/0>, 1.0, 1.0]")
self.assertEqual(pcell_var.display_title(), "PCellTestLib2.Box2(L=1/0,W=1.000,H=1.000)")
self.assertEqual(nh(pcell_var.pcell_parameters_by_name()), "{'height': 1.0, 'layer': <1/0>, 'width': 1.0}")

View File

@ -39,6 +39,11 @@ class BoxPCell < RBA::PCellDeclaration
# provide a descriptive text for the cell
return "Box(L=#{parameters[0].to_s},W=#{'%.3f' % parameters[1].to_s},H=#{'%.3f' % parameters[2].to_s})"
end
def cell_name(parameters)
# provide a cell name for the PCell
return "Box_L#{parameters[0].to_s.gsub('/','d')}_W#{('%.3f' % parameters[1]).gsub('.','p')}_H#{('%.3f' % parameters[2]).gsub('.','p')}"
end
def get_parameters
@ -129,6 +134,11 @@ if RBA.constants.member?(:PCellDeclarationHelper)
return "Box2(L=" + layer.to_s + ",W=" + ('%.3f' % width) + ",H=" + ('%.3f' % height) + ")"
end
def cell_name_impl
# provide a cell name for the PCell
return "Box2_L" + layer.to_s.gsub('/', 'd') + "_W" + ('%.3f' % width).gsub('.', 'p') + "_H" + ('%.3f' % height).gsub('.', 'p')
end
def produce_impl
# fetch the parameters
@ -371,6 +381,9 @@ class DBPCell_TestClass < TestBase
param = [ RBA::LayerInfo::new(1, 0) ] # rest is filled with defaults
pcell_var_id = ly.add_pcell_variant(lib, pcell_decl_id, param)
pcell_var = ly.cell(pcell_var_id)
assert_equal(pcell_var.name, "Box_L1d0_W1p000_H1p000")
assert_equal(pcell_var.qname, "PCellTestLib.Box")
assert_equal(pcell_var.basic_name, "Box")
pcell_inst = c1.insert(RBA::CellInstArray::new(pcell_var_id, RBA::Trans::new))
assert_equal(pcell_var.layout.inspect, ly.inspect)
assert_equal(pcell_var.library.inspect, lib.inspect)
@ -512,6 +525,8 @@ class DBPCell_TestClass < TestBase
pcell_var = ly.cell(pcell_var_id)
pcell_inst = c1.insert(RBA::CellInstArray::new(pcell_var_id, RBA::Trans::new))
assert_equal(pcell_var.basic_name, "Box2")
assert_equal(pcell_var.name, "Box2_L1d0_W1p000_H1p000")
assert_equal(pcell_var.qname, "PCellTestLib2.Box2")
assert_equal(pcell_var.pcell_parameters().inspect, "[<1/0>, 1.0, 1.0, 0]")
assert_equal(pcell_var.display_title(), "PCellTestLib2.Box2(L=1/0,W=1.000,H=1.000)")
assert_equal(norm_hash(pcell_var.pcell_parameters_by_name()), "{\"height\"=>1.0, \"layer\"=><1/0>, \"secret\"=>0, \"width\"=>1.0}")
@ -908,6 +923,37 @@ class DBPCell_TestClass < TestBase
end
# convert to static cell
def test_13
if !RBA.constants.member?(:PCellDeclarationHelper)
return
end
# instantiate and register the library
tl = PCellTestLib2::new
ly = RBA::Layout::new(true)
ly.dbu = 0.01
ci1 = ly.add_cell("c1")
c1 = ly.cell(ci1)
lib = RBA::Library.library_by_name("PCellTestLib2")
assert_equal(lib != nil, true)
pcell_decl = lib.layout().pcell_declaration("Box2")
param = [ RBA::LayerInfo::new(1, 0) ] # rest is filled with defaults
pcell_var_id = ly.add_pcell_variant(lib, pcell_decl.id(), param)
static_id = ly.convert_cell_to_static(pcell_var_id)
static = ly.cell(static_id)
assert_equal(static.basic_name, "Box2_L1d0_W1p000_H1p000")
assert_equal(static.name, "Box2_L1d0_W1p000_H1p000")
assert_equal(static.qname, "Box2_L1d0_W1p000_H1p000")
assert_equal(static.is_proxy?, false)
end
end
class DBPCellParameterStates_TestClass < TestBase