diff --git a/src/db/db/dbCell.cc b/src/db/db/dbCell.cc index 1a465f47c..629ae4e92 100644 --- a/src/db/db/dbCell.cc +++ b/src/db/db/dbCell.cc @@ -777,6 +777,7 @@ Cell::get_pcell_parameters (const instance_type &ref) const Cell::instance_type Cell::change_pcell_parameters (const instance_type &ref, const std::vector &new_parameters) { + tl_assert (mp_layout != 0); cell_index_type new_cell_index = mp_layout->get_pcell_variant_cell (ref.cell_index (), new_parameters); if (new_cell_index != ref.cell_index ()) { @@ -790,6 +791,61 @@ Cell::change_pcell_parameters (const instance_type &ref, const std::vector &map) +{ + tl_assert (mp_layout != 0); + + const db::PCellDeclaration *pcd = pcell_declaration_of_inst (ref); + if (! pcd) { + return Cell::instance_type (); + } + + const std::vector &pcp = pcd->parameter_declarations (); + + std::vector p = get_pcell_parameters (ref); + bool needs_update = false; + + for (size_t i = 0; i < pcp.size () && i < p.size (); ++i) { + std::map::const_iterator pm = map.find (pcp [i].get_name ()); + if (pm != map.end () && p [i] != pm->second) { + p [i] = pm->second; + needs_update = true; + } + } + + if (needs_update) { + return change_pcell_parameters (ref, p); + } else { + return ref; + } + +} + +const db::PCellDeclaration * +Cell::pcell_declaration_of_inst (const db::Cell::instance_type &ref) const +{ + tl_assert (mp_layout != 0); + return mp_layout->cell (ref.cell_index ()).pcell_declaration (); +} + +const db::PCellDeclaration * +Cell::pcell_declaration () const +{ + tl_assert (mp_layout != 0); + std::pair pc = mp_layout->is_pcell_instance (cell_index ()); + if (pc.first) { + db::Library *lib = mp_layout->defining_library (cell_index ()).first; + if (lib) { + return lib->layout ().pcell_declaration (pc.second); + } else { + return mp_layout->pcell_declaration (pc.second); + } + } else { + return 0; + } +} + void Cell::sort_inst_tree (bool force) { diff --git a/src/db/db/dbCell.h b/src/db/db/dbCell.h index 044f917f3..2a64cdf23 100644 --- a/src/db/db/dbCell.h +++ b/src/db/db/dbCell.h @@ -57,6 +57,7 @@ class Library; class ImportLayerMapping; class CellMapping; class LayerMapping; +class PCellDeclaration; /** * @brief The cell object @@ -473,6 +474,27 @@ public: */ instance_type change_pcell_parameters (const instance_type &ref, const std::vector &new_parameters); + /** + * @brief Changes the PCell parameters of a PCell instance using a dict + * + * @return A reference to the new instance. The original reference may be invalid. + */ + instance_type change_pcell_parameters (const instance_type &ref, const std::map &new_parameters); + + /** + * @brief Gets the PCellDeclaration object of the instance if the instance is a PCell instance + * + * If the instance is not a PCell instance, 0 is returned. + */ + const db::PCellDeclaration *pcell_declaration_of_inst (const db::Cell::instance_type &ref) const; + + /** + * @brief Gets the PCellDeclaration object of the cell is the cell is a PCell variant + * + * If the cell is not a PCell variant, 0 is returned. + */ + const db::PCellDeclaration *pcell_declaration () const; + /** * @brief The cell index accessor method * diff --git a/src/db/db/gsiDeclDbCell.cc b/src/db/db/gsiDeclDbCell.cc index 31b693cd8..6bcb72581 100644 --- a/src/db/db/gsiDeclDbCell.cc +++ b/src/db/db/gsiDeclDbCell.cc @@ -3321,7 +3321,8 @@ Class decl_Cell ("db", "Cell", "\n" "This method has been introduced in version 0.24.\n" ) + - gsi::method ("change_pcell_parameters", &db::Cell::change_pcell_parameters, gsi::arg ("instance"), gsi::arg ("parameters"), + gsi::method ("change_pcell_parameters", static_cast &new_parameters)> (&db::Cell::change_pcell_parameters), + gsi::arg ("instance"), gsi::arg ("parameters"), "@brief Changes the parameters for an individual PCell instance\n" "@return The new instance (the old may be invalid)\n" "If necessary, this method creates a new variant and replaces the given instance\n"