Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions src/db/db/dbLibrary.cc
Original file line number Diff line number Diff line change
Expand Up @@ -145,9 +145,20 @@ Library::is_retired (const db::cell_index_type library_cell_index) const
return (i != m_refcount.end () && j != m_retired_count.end () && i->second == j->second);
}

void
Library::rename (const std::string &name)
{
if (name != get_name () && db::LibraryManager::initialized ()) {
db::LibraryManager::instance ().rename (get_id (), name);
}
}

void
Library::refresh ()
{
std::string name = reload ();
rename (name);

layout ().refresh ();
remap_to (this);
}
Expand Down Expand Up @@ -271,6 +282,9 @@ Library::remap_to (db::Library *other)
// Do a cleanup later since the referrers now might have invalid proxy instances
for (std::set<db::Layout *>::const_iterator c = needs_cleanup.begin (); c != needs_cleanup.end (); ++c) {
(*c)->cleanup ();
// forces an update of the cell tree in the application - this will reflect the changed name
// of the library reference
(*c)->invalidate_hier ();
}
}

Expand Down
22 changes: 22 additions & 0 deletions src/db/db/dbLibrary.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,20 @@ class DB_PUBLIC Library
*/
virtual ~Library ();

/**
* @brief Called to reload the library
*
* If the library is a file-based one, this method can be reimplemented to reload
* the file. This method must not change the name of the library, but return a new
* name in case it has changed.
*
* @return The new name of the library
*/
virtual std::string reload ()
{
return get_name ();
}

/**
* @brief The layout object
*
Expand Down Expand Up @@ -211,6 +225,14 @@ class DB_PUBLIC Library
*/
void refresh ();

/**
* @brief Renames the library
*
* Unlike "set_name", this method will take care of properly re-registering the library
* under the new name.
*/
void rename (const std::string &name);

/**
* @brief Remap the library proxies to a different library
*
Expand Down
49 changes: 48 additions & 1 deletion src/db/db/dbLibraryManager.cc
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,39 @@ LibraryManager::~LibraryManager ()
clear ();
}

void
LibraryManager::rename (lib_id_type lib_id, const std::string &name)
{
db::Library *lib = 0;

{
tl::MutexLocker locker (&m_lock);

lib = lib_internal (lib_id);
if (! lib) {
return;
}

std::string org_name = lib->get_name ();

for (auto it = m_lib_by_name.find (org_name);it != m_lib_by_name.end () && it->first == org_name; ++it) {
if (it->second == lib_id) {
m_lib_by_name.erase (it);
break;
}
}

m_lib_by_name.insert (std::make_pair (name, lib_id));
lib->set_name (name);
}

// triggers a layout update
lib->remap_to (lib);

// issue the change notification
changed_event ();
}

std::pair<bool, lib_id_type>
LibraryManager::lib_by_name (const std::string &name, const std::set<std::string> &for_technologies) const
{
Expand Down Expand Up @@ -112,6 +145,8 @@ LibraryManager::unregister_lib (Library *library)
return;
}

library->remap_to (0);

{
tl::MutexLocker locker (&m_lock);

Expand All @@ -124,8 +159,10 @@ LibraryManager::unregister_lib (Library *library)
}
}

library->remap_to (0);
library->set_id (std::numeric_limits<lib_id_type>::max ());

// issue the change notification
changed_event ();
}

void
Expand Down Expand Up @@ -244,6 +281,16 @@ LibraryManager::lib_internal (lib_id_type id) const
}
}

void
LibraryManager::refresh_all ()
{
for (std::vector<Library *>::iterator l = m_libs.begin (); l != m_libs.end (); ++l) {
if (*l) {
(*l)->refresh ();
}
}
}

void
LibraryManager::clear ()
{
Expand Down
10 changes: 10 additions & 0 deletions src/db/db/dbLibraryManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,11 @@ class DB_PUBLIC LibraryManager
return m_lib_by_name.end ();
}

/**
* @brief Renames a library
*/
void rename (lib_id_type lib_id, const std::string &name);

/**
* @brief Get the library by name which is valid for all given technologies
*
Expand Down Expand Up @@ -212,6 +217,11 @@ class DB_PUBLIC LibraryManager
*/
void clear ();

/**
* @brief Refreshes all libraries
*/
void refresh_all ();

private:
std::vector<Library *> m_libs;
lib_name_map m_lib_by_name;
Expand Down
57 changes: 56 additions & 1 deletion src/db/db/gsiDeclDbCell.cc
Original file line number Diff line number Diff line change
Expand Up @@ -974,6 +974,45 @@ static db::Library *library (const db::Cell *cell)
}
}

static void change_library_ref (db::Cell *cell, db::lib_id_type lib_id, db::cell_index_type cell_index)
{
db::LibraryProxy *l = dynamic_cast<db::LibraryProxy *> (cell);
if (! l) {
throw tl::Exception (tl::to_string (tr ("Cell is not a library reference - cannot change that reference")));
}

const db::Library *lib = db::LibraryManager::instance ().lib (lib_id);
if (! lib) {
throw tl::Exception (tl::to_string (tr ("'lib_id' is not a valid library ID")));
}

if (! lib->layout ().is_valid_cell_index (cell_index)) {
throw tl::Exception (tl::to_string (tr ("'cell_index' is not a valid cell index in the context of the library")));
}

l->remap (lib_id, cell_index);
}

static void change_library_ref2 (db::Cell *cell, const std::string &lib_name, const std::string &cell_name)
{
db::LibraryProxy *l = dynamic_cast<db::LibraryProxy *> (cell);
if (! l) {
throw tl::Exception (tl::to_string (tr ("Cell is not a library reference - cannot change that reference")));
}

db::Library *lib = db::LibraryManager::instance ().lib_ptr_by_name (lib_name);
if (! lib) {
throw tl::Exception (tl::to_string (tr ("Not a valid library name: ")) + lib_name);
}

auto cbn = lib->layout ().cell_by_name (cell_name.c_str ());
if (! cbn.first) {
throw tl::Exception (tl::to_string (tr ("Not a valid cell name: ")) + cell_name);
}

l->remap (lib->get_id (), cbn.second);
}

static const db::Layout *layout_const (const db::Cell *cell)
{
return cell->layout ();
Expand Down Expand Up @@ -3194,8 +3233,24 @@ Class<db::Cell> decl_Cell ("db", "Cell",
"@brief Returns a reference to the library from which the cell is imported\n"
"if the cell is not imported from a library, this reference is nil.\n"
"\n"
"this method has been introduced in version 0.22.\n"
"This method has been introduced in version 0.22.\n"
) +
gsi::method_ext ("change_ref", &change_library_ref, gsi::arg ("lib_id"), gsi::arg ("lib_cell_index"),
"@brief Changes the reference to a different library cell\n"
"This method requires a cell that is a library reference (i.e. \\is_library_cell? is true). It will "
"change that reference to a new cell, potentially from a different library.\n"
"The library is given by library ID, the cell by cell inside inside that library.\n"
"\n"
"This method has been introduced in version 0.30.5.\n"
) +
gsi::method_ext ("change_ref", &change_library_ref2, gsi::arg ("lib_name"), gsi::arg ("cell_name"),
"@brief Changes the reference to a different library cell\n"
"This method requires a cell that is a library reference (i.e. \\is_library_cell? is true). It will "
"change that reference to a new cell, potentially from a different library.\n"
"This version takes a library name and cell name (from that library).\n"
"\n"
"This method has been introduced in version 0.30.5.\n"
) +
gsi::method_ext ("layout", &layout,
"@brief Returns a reference to the layout where the cell resides\n"
"\n"
Expand Down
Loading
Loading