diff --git a/src/db/db/built-in-macros/pcell_declaration_helper.lym b/src/db/db/built-in-macros/pcell_declaration_helper.lym index 6a9c21f9d..1db044b21 100644 --- a/src/db/db/built-in-macros/pcell_declaration_helper.lym +++ b/src/db/db/built-in-macros/pcell_declaration_helper.lym @@ -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 display_text + 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 diff --git a/src/db/db/built-in-pymacros/pcell_declaration_helper.lym b/src/db/db/built-in-pymacros/pcell_declaration_helper.lym index 39b4c4807..8b763e6e7 100644 --- a/src/db/db/built-in-pymacros/pcell_declaration_helper.lym +++ b/src/db/db/built-in-pymacros/pcell_declaration_helper.lym @@ -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 diff --git a/src/db/db/dbCell.cc b/src/db/db/dbCell.cc index 629ae4e92..cb56e7354 100644 --- a/src/db/db/dbCell.cc +++ b/src/db/db/dbCell.cc @@ -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 { diff --git a/src/db/db/dbCell.h b/src/db/db/dbCell.h index 2a64cdf23..7ba54fc71 100644 --- a/src/db/db/dbCell.h +++ b/src/db/db/dbCell.h @@ -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 * diff --git a/src/db/db/dbColdProxy.cc b/src/db/db/dbColdProxy.cc index 3ccb5806a..e83c712eb 100644 --- a/src/db/db/dbColdProxy.cc +++ b/src/db/db/dbColdProxy.cc @@ -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 ()) { diff --git a/src/db/db/dbLayout.cc b/src/db/db/dbLayout.cc index bf2a84e0e..e7c93b663 100644 --- a/src/db/db/dbLayout.cc +++ b/src/db/db/dbLayout.cc @@ -2462,7 +2462,7 @@ Layout::get_pcell_variant_dict (pcell_id_type pcell_id, const std::mapget_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::vectorget_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 == cell_name (ci)) { + // there is a cell name conflict: give priority to the static cell, so it + // will see the variant name + std::string rename_org = uniquify_cell_name (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 cloning 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 ()); } diff --git a/src/db/db/dbLayout.h b/src/db/db/dbLayout.h index 4c0d0078a..9104d758d 100644 --- a/src/db/db/dbLayout.h +++ b/src/db/db/dbLayout.h @@ -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". diff --git a/src/db/db/dbLibraryProxy.cc b/src/db/db/dbLibraryProxy.cc index 87db31672..c44a319c8 100644 --- a/src/db/db/dbLibraryProxy.cc +++ b/src/db/db/dbLibraryProxy.cc @@ -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 ""; + } 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 ()); diff --git a/src/db/db/dbLibraryProxy.h b/src/db/db/dbLibraryProxy.h index e1f026ed7..8c72787cc 100644 --- a/src/db/db/dbLibraryProxy.h +++ b/src/db/db/dbLibraryProxy.h @@ -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; diff --git a/src/db/db/dbPCellDeclaration.h b/src/db/db/dbPCellDeclaration.h index 7db690f4c..a75718d83 100644 --- a/src/db/db/dbPCellDeclaration.h +++ b/src/db/db/dbPCellDeclaration.h @@ -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 * diff --git a/src/db/db/dbPCellVariant.cc b/src/db/db/dbPCellVariant.cc index b401c8471..bebda8921 100644 --- a/src/db/db/dbPCellVariant.cc +++ b/src/db/db/dbPCellVariant.cc @@ -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) { diff --git a/src/db/db/dbPCellVariant.h b/src/db/db/dbPCellVariant.h index b4de1a1f5..c20aafeaf 100644 --- a/src/db/db/dbPCellVariant.h +++ b/src/db/db/dbPCellVariant.h @@ -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 it's context. */ virtual void unregister (); /** - * @brief Reregister a cell inside it's context. + * @brief Re-registers a cell inside it's 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; }; diff --git a/src/db/db/gsiDeclDbLibrary.cc b/src/db/db/gsiDeclDbLibrary.cc index d06caba5f..2693b0bb5 100644 --- a/src/db/db/gsiDeclDbLibrary.cc +++ b/src/db/db/gsiDeclDbLibrary.cc @@ -368,6 +368,7 @@ Class 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::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; }; @@ -809,6 +825,13 @@ Class 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" diff --git a/src/pymod/distutils_src/klayout/db/pcell_declaration_helper.py b/src/pymod/distutils_src/klayout/db/pcell_declaration_helper.py index 773ff03c7..6a89fc446 100644 --- a/src/pymod/distutils_src/klayout/db/pcell_declaration_helper.py +++ b/src/pymod/distutils_src/klayout/db/pcell_declaration_helper.py @@ -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