mirror of https://github.com/KLayout/klayout.git
Merge pull request #2199 from KLayout/feature/issue-2195
Feature/issue 2195
This commit is contained in:
commit
ff49a81723
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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 ()) {
|
||||
|
|
|
|||
|
|
@ -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 ());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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".
|
||||
|
|
|
|||
|
|
@ -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 ());
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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 ¶meters) const
|
||||
{
|
||||
return db::PCellDeclaration::get_cell_name (parameters);
|
||||
}
|
||||
|
||||
virtual std::string get_cell_name (const db::pcell_parameters_type ¶meters) 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"
|
||||
|
|
|
|||
|
|
@ -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 ¶meters) 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 ¶meters) 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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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.
Binary file not shown.
|
|
@ -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}")
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in New Issue