From 1af5bcfd6b5f959944926a6d0865e76f4f4196a1 Mon Sep 17 00:00:00 2001 From: Eder Monteiro Date: Tue, 7 Apr 2026 11:39:25 -0300 Subject: [PATCH 1/9] odb: allow reload of ODB in a single session Signed-off-by: Eder Monteiro --- src/OpenRoad.cc | 4 +-- src/odb/include/odb/db.h | 1 + src/odb/include/odb/dbDatabaseObserver.h | 3 +++ src/odb/src/db/dbDatabase.cpp | 32 ++++++++++++++++++++++++ 4 files changed, 38 insertions(+), 2 deletions(-) diff --git a/src/OpenRoad.cc b/src/OpenRoad.cc index eef476375e0..3a2f924c32d 100644 --- a/src/OpenRoad.cc +++ b/src/OpenRoad.cc @@ -563,8 +563,8 @@ void OpenRoad::readDb(const char* filename, bool hierarchy) void OpenRoad::readDb(std::istream& stream) { if (db_->getChip() && db_->getChip()->getBlock()) { - logger_->error( - ORD, 47, "You can't load a new db file as the db is already populated"); + db_->triggerPreDbClear(); + db_->clear(); } stream.exceptions(std::ifstream::failbit | std::ifstream::badbit diff --git a/src/odb/include/odb/db.h b/src/odb/include/odb/db.h index 279f92828f1..d9b6cd5bbac 100644 --- a/src/odb/include/odb/db.h +++ b/src/odb/include/odb/db.h @@ -7713,6 +7713,7 @@ class dbDatabase : public dbObject void triggerPostReadDef(dbBlock* block, bool floorplan); void triggerPostReadDb(); void triggerPostRead3Dbx(dbChip* chip); + void triggerPreDbClear(); /// /// Create an instance of a database diff --git a/src/odb/include/odb/dbDatabaseObserver.h b/src/odb/include/odb/dbDatabaseObserver.h index 05ff66327ec..0b26bcf4ac2 100644 --- a/src/odb/include/odb/dbDatabaseObserver.h +++ b/src/odb/include/odb/dbDatabaseObserver.h @@ -31,6 +31,9 @@ class dbDatabaseObserver virtual void postReadDb(odb::dbDatabase* db) = 0; virtual void postRead3Dbx(odb::dbChip* chip) = 0; + // Called before the database is cleared for a reload + virtual void preDbClear(odb::dbDatabase* db) {} + void setUnregisterObserver(std::function unregister_observer) { unregister_observer_ = std::move(unregister_observer); diff --git a/src/odb/src/db/dbDatabase.cpp b/src/odb/src/db/dbDatabase.cpp index 83a5fec5d6e..12a06d65e6d 100644 --- a/src/odb/src/db/dbDatabase.cpp +++ b/src/odb/src/db/dbDatabase.cpp @@ -478,6 +478,24 @@ _dbDatabase::_dbDatabase(_dbDatabase* /* unused: db */, int id) chip_tbl_ = new dbTable<_dbChip, 2>( this, this, (GetObjTbl_t) &_dbDatabase::getObjectTable, dbChipObj); + chip_hash_.setTable(chip_tbl_); + + chip_inst_tbl_ = new dbTable<_dbChipInst>( + this, this, (GetObjTbl_t) &_dbDatabase::getObjectTable, dbChipInstObj); + chip_region_inst_tbl_ = new dbTable<_dbChipRegionInst>( + this, + this, + (GetObjTbl_t) &_dbDatabase::getObjectTable, + dbChipRegionInstObj); + chip_conn_tbl_ = new dbTable<_dbChipConn>( + this, this, (GetObjTbl_t) &_dbDatabase::getObjectTable, dbChipConnObj); + chip_bump_inst_tbl_ + = new dbTable<_dbChipBumpInst>(this, + this, + (GetObjTbl_t) &_dbDatabase::getObjectTable, + dbChipBumpInstObj); + chip_net_tbl_ = new dbTable<_dbChipNet>( + this, this, (GetObjTbl_t) &_dbDatabase::getObjectTable, dbChipNetObj); gds_lib_tbl_ = new dbTable<_dbGDSLib, 2>( this, this, (GetObjTbl_t) &_dbDatabase::getObjectTable, dbGdsLibObj); @@ -925,8 +943,14 @@ void dbDatabase::clear() { _dbDatabase* db = (_dbDatabase*) this; int id = db->unique_id_; + // Save session-level state that was set up during init and is not + // part of the database content being cleared. + auto observers = std::move(db->observers_); + utl::Logger* logger = db->logger_; db->~_dbDatabase(); new (db) _dbDatabase(db, id); + db->observers_ = std::move(observers); + db->logger_ = logger; } void dbDatabase::destroy(dbDatabase* db_) @@ -1029,6 +1053,14 @@ void dbDatabase::triggerPostReadDb() } } +void dbDatabase::triggerPreDbClear() +{ + _dbDatabase* db = (_dbDatabase*) this; + for (dbDatabaseObserver* observer : db->observers_) { + observer->preDbClear(this); + } +} + // User Code End dbDatabasePublicMethods } // namespace odb // Generator Code End Cpp From 8109fc7b524810b9cef9ad8ea6b7bca753f6d63b Mon Sep 17 00:00:00 2001 From: Eder Monteiro Date: Tue, 7 Apr 2026 11:43:41 -0300 Subject: [PATCH 2/9] dbSta: add preDbClear function to db observer Signed-off-by: Eder Monteiro --- src/dbSta/include/db_sta/dbSta.hh | 1 + src/dbSta/src/dbNetwork.cc | 2 ++ src/dbSta/src/dbSta.cc | 12 ++++++++++++ 3 files changed, 15 insertions(+) diff --git a/src/dbSta/include/db_sta/dbSta.hh b/src/dbSta/include/db_sta/dbSta.hh index 2c66a95a89c..43ef6b9502f 100644 --- a/src/dbSta/include/db_sta/dbSta.hh +++ b/src/dbSta/include/db_sta/dbSta.hh @@ -163,6 +163,7 @@ class dbSta : public Sta, public odb::dbDatabaseObserver void postReadDef(odb::dbBlock* block) override; void postReadDb(odb::dbDatabase* db) override; void postRead3Dbx(odb::dbChip* chip) override; + void preDbClear(odb::dbDatabase* db) override; // Find clock nets connected by combinational gates from the clock roots. std::set findClkNets(); diff --git a/src/dbSta/src/dbNetwork.cc b/src/dbSta/src/dbNetwork.cc index 763b4f1a956..b09b74189d0 100644 --- a/src/dbSta/src/dbNetwork.cc +++ b/src/dbSta/src/dbNetwork.cc @@ -704,6 +704,8 @@ void dbNetwork::clear() { ConcreteNetwork::clear(); db_ = nullptr; + block_ = nullptr; + top_cell_ = nullptr; } Instance* dbNetwork::topInstance() const diff --git a/src/dbSta/src/dbSta.cc b/src/dbSta/src/dbSta.cc index 6577b50111e..84bf99a2a1a 100644 --- a/src/dbSta/src/dbSta.cc +++ b/src/dbSta/src/dbSta.cc @@ -323,6 +323,18 @@ void dbSta::postReadDb(odb::dbDatabase* db) } } +void dbSta::preDbClear(odb::dbDatabase* db) +{ + db_cbk_->removeOwner(); + // Delete scenes before clearing the network, since scenes hold + // LibertyLibrary pointers that ConcreteNetwork::clear() will free. + deleteScenes(); + clear(); + db_network_->clear(); + // Restore db_ since dbNetwork::clear() nulls it, but we need it for reload + db_network_->init(db_, logger_); +} + float dbSta::slack(const odb::dbNet* db_net, const MinMax* min_max) { const Net* net = db_network_->dbToSta(db_net); From 0831058515cda7db52d6ecf920b8df27a5f73f45 Mon Sep 17 00:00:00 2001 From: Eder Monteiro Date: Tue, 7 Apr 2026 11:44:42 -0300 Subject: [PATCH 3/9] gui: add clear functions called when reloading an odb file Signed-off-by: Eder Monteiro --- src/gui/src/displayControls.cpp | 30 ++++++++++++++++++++++++++++++ src/gui/src/displayControls.h | 3 +++ src/gui/src/layoutTabs.cpp | 22 ++++++++++++++++++++++ src/gui/src/layoutTabs.h | 1 + src/gui/src/mainWindow.cpp | 11 +++++++++++ src/gui/src/mainWindow.h | 1 + 6 files changed, 68 insertions(+) diff --git a/src/gui/src/displayControls.cpp b/src/gui/src/displayControls.cpp index b6931490935..10b4ee1ecbf 100644 --- a/src/gui/src/displayControls.cpp +++ b/src/gui/src/displayControls.cpp @@ -2163,6 +2163,36 @@ void DisplayControls::techInit(odb::dbTech* tech) techs_.insert(tech); } +void DisplayControls::clearTechData() +{ + // Remove layer leaf rows but preserve sub-group items (implant, other) + // by clearing children of each sub-group first, then removing only + // direct layer rows from the layers group. + layers_.implant.name->removeRows(0, layers_.implant.name->rowCount()); + layers_.other.name->removeRows(0, layers_.other.name->rowCount()); + + // Remove direct children (routing/cut layers) from layers_group_, but + // keep the implant and other sub-group rows. Walk in reverse to avoid + // index shifting. + for (int i = layers_group_.name->rowCount() - 1; i >= 0; --i) { + QStandardItem* child = layers_group_.name->child(i); + if (child != layers_.implant.name && child != layers_.other.name) { + layers_group_.name->removeRow(i); + } + } + + site_group_.name->removeRows(0, site_group_.name->rowCount()); + + // Clear ODB-keyed maps + layer_controls_.clear(); + site_controls_.clear(); + layer_color_.clear(); + layer_pattern_.clear(); + site_color_.clear(); + techs_.clear(); + layers_menu_layer_ = nullptr; +} + void DisplayControls::blockLoaded(odb::dbBlock* block) { addTech(block->getTech()); diff --git a/src/gui/src/displayControls.h b/src/gui/src/displayControls.h index 6f6f0bf6667..fe12e21ebac 100644 --- a/src/gui/src/displayControls.h +++ b/src/gui/src/displayControls.h @@ -272,6 +272,9 @@ class DisplayControls : public QDockWidget, // options displayed need to match void blockLoaded(odb::dbBlock* block); + // Clears all ODB-derived display state (layers, sites) for DB reload + void clearTechData(); + void setCurrentChip(odb::dbChip* chip); // This is called by the check boxes to update the state diff --git a/src/gui/src/layoutTabs.cpp b/src/gui/src/layoutTabs.cpp index d7649ef05e2..5e1513f8e13 100644 --- a/src/gui/src/layoutTabs.cpp +++ b/src/gui/src/layoutTabs.cpp @@ -130,8 +130,30 @@ void LayoutTabs::chipLoaded(odb::dbChip* chip) emit newViewer(viewer); } +void LayoutTabs::clearViewers() +{ + // Stop render threads before destroying viewers to avoid + // deleting a running QThread. + for (LayoutViewer* viewer : viewers_) { + viewer->exit(); + } + // QTabWidget::clear() removes all tabs and deletes the page widgets + // (LayoutScroll), which are parents of the LayoutViewer widgets. + QTabWidget::clear(); + viewers_.clear(); + current_viewer_ = nullptr; + modules_.clear(); + focus_nets_.clear(); + route_guides_.clear(); + net_tracks_.clear(); +} + void LayoutTabs::tabChange(int index) { + if (index < 0 || index >= static_cast(viewers_.size())) { + current_viewer_ = nullptr; + return; + } current_viewer_ = viewers_[index]; emit setCurrentChip(current_viewer_->getChip()); diff --git a/src/gui/src/layoutTabs.h b/src/gui/src/layoutTabs.h index a0422f29227..4db63e8f78d 100644 --- a/src/gui/src/layoutTabs.h +++ b/src/gui/src/layoutTabs.h @@ -91,6 +91,7 @@ class LayoutTabs : public QTabWidget void tabChange(int index); void updateBackgroundColors(); void updateBackgroundColor(LayoutViewer* viewer); + void clearViewers(); // These are just forwarding to the current LayoutViewer void zoomIn(); diff --git a/src/gui/src/mainWindow.cpp b/src/gui/src/mainWindow.cpp index fd93eadb6fc..e7dec5caf28 100644 --- a/src/gui/src/mainWindow.cpp +++ b/src/gui/src/mainWindow.cpp @@ -1662,6 +1662,17 @@ void MainWindow::postRead3Dbx(odb::dbChip* chip) emit chipLoaded(chip); } +void MainWindow::preDbClear(odb::dbDatabase* db) +{ + selected_.clear(); + for (auto& highlighted_set : highlighted_) { + highlighted_set.clear(); + } + viewers_->clearViewers(); + controls_->clearTechData(); + setBlock(nullptr); +} + void MainWindow::postReadDb(odb::dbDatabase* db) { auto chip = db->getChip(); diff --git a/src/gui/src/mainWindow.h b/src/gui/src/mainWindow.h index 9df989b3dd3..ce122b09f54 100644 --- a/src/gui/src/mainWindow.h +++ b/src/gui/src/mainWindow.h @@ -79,6 +79,7 @@ class MainWindow : public QMainWindow, public odb::dbDatabaseObserver void postReadDef(odb::dbBlock* block) override; void postReadDb(odb::dbDatabase* db) override; void postRead3Dbx(odb::dbChip* chip) override; + void preDbClear(odb::dbDatabase* db) override; // Capture logger messages into the script widget output void setLogger(utl::Logger* logger); From 2f9c250741b974702e7a77bb3282825c75d444dd Mon Sep 17 00:00:00 2001 From: Eder Monteiro Date: Tue, 7 Apr 2026 12:49:53 -0300 Subject: [PATCH 4/9] web: small fix to support reload of odb file Signed-off-by: Eder Monteiro --- src/web/src/search.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/web/src/search.cpp b/src/web/src/search.cpp index e82ef1a82b8..4907937ef5b 100644 --- a/src/web/src/search.cpp +++ b/src/web/src/search.cpp @@ -203,10 +203,13 @@ void Search::setTopChip(odb::dbChip* chip) return; } odb::dbBlock* block = chip->getBlock(); - if (top_chip_ != chip) { + // Re-initialize when the chip changed or when the previous block was + // destroyed (e.g. after a database reload via read_db). The block + // destructor calls removeOwner() which clears hasOwner(). + if (top_chip_ != chip || !hasOwner()) { clear(); - if (top_chip_ != nullptr) { + if (hasOwner()) { removeOwner(); } From c36ece0f5179c202707e755695618fda9174adcc Mon Sep 17 00:00:00 2001 From: Eder Monteiro Date: Tue, 7 Apr 2026 14:29:42 -0300 Subject: [PATCH 5/9] odb: fix build error Signed-off-by: Eder Monteiro --- src/odb/include/odb/dbDatabaseObserver.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/odb/include/odb/dbDatabaseObserver.h b/src/odb/include/odb/dbDatabaseObserver.h index 0b26bcf4ac2..99a9f69a409 100644 --- a/src/odb/include/odb/dbDatabaseObserver.h +++ b/src/odb/include/odb/dbDatabaseObserver.h @@ -32,7 +32,7 @@ class dbDatabaseObserver virtual void postRead3Dbx(odb::dbChip* chip) = 0; // Called before the database is cleared for a reload - virtual void preDbClear(odb::dbDatabase* db) {} + virtual void preDbClear(odb::dbDatabase* /*db*/) {} void setUnregisterObserver(std::function unregister_observer) { From 886e1bcc3eb6c66d9f0cdd92a82c2bc12d13943b Mon Sep 17 00:00:00 2001 From: Eder Monteiro Date: Tue, 7 Apr 2026 14:43:58 -0300 Subject: [PATCH 6/9] odb: clang-tidy Signed-off-by: Eder Monteiro --- src/odb/src/db/dbDatabase.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/odb/src/db/dbDatabase.cpp b/src/odb/src/db/dbDatabase.cpp index 12a06d65e6d..f115f6ebca5 100644 --- a/src/odb/src/db/dbDatabase.cpp +++ b/src/odb/src/db/dbDatabase.cpp @@ -33,6 +33,7 @@ #include #include #include +#include #include #include "absl/synchronization/mutex.h" From f952e3558344d12279def1f4a578c0af02b71976 Mon Sep 17 00:00:00 2001 From: Eder Monteiro Date: Tue, 7 Apr 2026 21:07:15 -0300 Subject: [PATCH 7/9] dbSta: fix STA cleanup for database reload Clear staCell pointers on all masters before freeing the network to prevent the GUI render thread from accessing freed ConcreteCell objects. Recreate the default scene after deleteScenes() so cmd_scene_ remains valid for heatmap settings queries on exit. Co-Authored-By: Claude Opus 4.6 (1M context) Signed-off-by: Eder Monteiro --- src/dbSta/src/dbSta.cc | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/dbSta/src/dbSta.cc b/src/dbSta/src/dbSta.cc index 84bf99a2a1a..edfdbe0bf53 100644 --- a/src/dbSta/src/dbSta.cc +++ b/src/dbSta/src/dbSta.cc @@ -326,9 +326,18 @@ void dbSta::postReadDb(odb::dbDatabase* db) void dbSta::preDbClear(odb::dbDatabase* db) { db_cbk_->removeOwner(); + // Clear staCell pointers on all masters before freeing the network. + // The GUI render thread may still be accessing these concurrently. + for (odb::dbLib* lib : db->getLibs()) { + for (odb::dbMaster* master : lib->getMasters()) { + master->staSetCell(nullptr); + } + } // Delete scenes before clearing the network, since scenes hold // LibertyLibrary pointers that ConcreteNetwork::clear() will free. + // Recreate the default scene so cmd_scene_ remains valid. deleteScenes(); + makeDefaultScene(); clear(); db_network_->clear(); // Restore db_ since dbNetwork::clear() nulls it, but we need it for reload From 8ec475a0e5dda7e401998fc92b6ca0db8f1be31a Mon Sep 17 00:00:00 2001 From: Eder Monteiro Date: Tue, 7 Apr 2026 21:07:46 -0300 Subject: [PATCH 8/9] gui: fix heatmap and render thread issues on database reload Call destroyMap() in HeatMapDataSource::setChip when the chip changes to invalidate cached heatmap data. Fix the MapSettingMultiChoice getter type from const std::string to std::string to avoid std::function double-wrapping. Stop render threads in saveSettings before serializing renderer state to prevent races with the render thread on exit. Co-Authored-By: Claude Opus 4.6 (1M context) Signed-off-by: Eder Monteiro --- src/gui/include/gui/heatMap.h | 10 ++++++++-- src/gui/src/heatMapCore.cpp | 1 - src/gui/src/mainWindow.cpp | 4 ++++ 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/gui/include/gui/heatMap.h b/src/gui/include/gui/heatMap.h index df182b01570..07c342964ad 100644 --- a/src/gui/include/gui/heatMap.h +++ b/src/gui/include/gui/heatMap.h @@ -53,7 +53,7 @@ class HeatMapDataSource std::string name; std::string label; std::function()> choices; - std::function getter; + std::function getter; std::function setter; }; @@ -92,7 +92,13 @@ class HeatMapDataSource void registerHeatMap(); - virtual void setChip(odb::dbChip* chip) { chip_ = chip; } + virtual void setChip(odb::dbChip* chip) + { + if (chip_ != chip) { + destroyMap(); + } + chip_ = chip; + } void setUseDBU(bool use_dbu) { use_dbu_ = use_dbu; } bool getUseDBU() const { return use_dbu_; } diff --git a/src/gui/src/heatMapCore.cpp b/src/gui/src/heatMapCore.cpp index 4cebbc04c7d..8ed9eb150d3 100644 --- a/src/gui/src/heatMapCore.cpp +++ b/src/gui/src/heatMapCore.cpp @@ -397,7 +397,6 @@ Renderer::Settings HeatMapDataSource::getSettings() const settings[set.name] = set.getter(); } } - return settings; } diff --git a/src/gui/src/mainWindow.cpp b/src/gui/src/mainWindow.cpp index e7dec5caf28..8223fc9248a 100644 --- a/src/gui/src/mainWindow.cpp +++ b/src/gui/src/mainWindow.cpp @@ -1629,6 +1629,10 @@ void MainWindow::selectHighlightConnectedBufferTrees(bool select_flag, void MainWindow::saveSettings() { + // Stop render threads before saving settings to avoid races + // between the render thread and the main thread. + viewers_->exit(); + QSettings settings("OpenRoad Project", "openroad"); settings.beginGroup("main"); settings.setValue("geometry", saveGeometry()); From d43da9c1bf03c489664c6aaf0dc5fc107611dc52 Mon Sep 17 00:00:00 2001 From: Eder Monteiro Date: Tue, 7 Apr 2026 21:07:58 -0300 Subject: [PATCH 9/9] grt,psm: fix stale heatmap pointers on database reload Override setChip in RoutingCongestionDataSource to reset the cached layer pointer. Override setChip in RUDYDataSource to reset the cached rudy pointer, unregister from the old block, and re-register on the new block. Add GlobalRouter::clearRudy() to delete the cached Rudy so it is recreated for the new block. Reset layer_, net_, and corner_ in IRDropDataSource::setChip to prevent dangling pointer access. Co-Authored-By: Claude Opus 4.6 (1M context) Signed-off-by: Eder Monteiro --- src/grt/include/grt/GlobalRouter.h | 1 + src/grt/src/GlobalRouter.cpp | 6 ++++++ src/grt/src/heatMap.h | 6 ++++++ src/grt/src/heatMapRudy.cpp | 11 +++++++++++ src/grt/src/heatMapRudy.h | 1 + src/psm/src/heatMap.cpp | 3 +++ 6 files changed, 28 insertions(+) diff --git a/src/grt/include/grt/GlobalRouter.h b/src/grt/include/grt/GlobalRouter.h index 4a947c30fd1..3fa4140d669 100644 --- a/src/grt/include/grt/GlobalRouter.h +++ b/src/grt/include/grt/GlobalRouter.h @@ -332,6 +332,7 @@ class GlobalRouter odb::dbDatabase* db() const { return db_; } FastRouteCore* fastroute() const { return fastroute_; } Rudy* getRudy(); + void clearRudy(); void writePinLocations(const char* file_name); diff --git a/src/grt/src/GlobalRouter.cpp b/src/grt/src/GlobalRouter.cpp index 201b5e70142..de2ed3847c4 100644 --- a/src/grt/src/GlobalRouter.cpp +++ b/src/grt/src/GlobalRouter.cpp @@ -1138,6 +1138,12 @@ Rudy* GlobalRouter::getRudy() return rudy_; } +void GlobalRouter::clearRudy() +{ + delete rudy_; + rudy_ = nullptr; +} + bool GlobalRouter::findPinAccessPointPositions( const Pin& pin, std::map>& ap_positions, diff --git a/src/grt/src/heatMap.h b/src/grt/src/heatMap.h index 49bd81a7db2..3a0301e2f83 100644 --- a/src/grt/src/heatMap.h +++ b/src/grt/src/heatMap.h @@ -15,6 +15,12 @@ class RoutingCongestionDataSource : public gui::GlobalRoutingDataSource public: RoutingCongestionDataSource(utl::Logger* logger, odb::dbDatabase* db); + void setChip(odb::dbChip* chip) override + { + layer_ = nullptr; + HeatMapDataSource::setChip(chip); + } + protected: bool populateMap() override; void combineMapData(bool base_has_value, diff --git a/src/grt/src/heatMapRudy.cpp b/src/grt/src/heatMapRudy.cpp index 0902e272bdd..fac11300db7 100644 --- a/src/grt/src/heatMapRudy.cpp +++ b/src/grt/src/heatMapRudy.cpp @@ -156,6 +156,17 @@ bool RUDYDataSource::populateMap() return true; } +void RUDYDataSource::setChip(odb::dbChip* chip) +{ + grouter_->clearRudy(); + rudy_ = nullptr; + removeOwner(); + HeatMapDataSource::setChip(chip); + if (chip && chip->getBlock()) { + addOwner(chip->getBlock()); + } +} + void RUDYDataSource::onShow() { HeatMapDataSource::onShow(); diff --git a/src/grt/src/heatMapRudy.h b/src/grt/src/heatMapRudy.h index 3527d4a7aae..ca631a39fec 100644 --- a/src/grt/src/heatMapRudy.h +++ b/src/grt/src/heatMapRudy.h @@ -23,6 +23,7 @@ class RUDYDataSource : public gui::GlobalRoutingDataSource, grt::GlobalRouter* grouter, odb::dbDatabase* db); + void setChip(odb::dbChip* chip) override; void onShow() override; void onHide() override; diff --git a/src/psm/src/heatMap.cpp b/src/psm/src/heatMap.cpp index 347ceac0bb1..faed2592e03 100644 --- a/src/psm/src/heatMap.cpp +++ b/src/psm/src/heatMap.cpp @@ -96,6 +96,9 @@ IRDropDataSource::IRDropDataSource(PDNSim* psm, void IRDropDataSource::setChip(odb::dbChip* chip) { + layer_ = nullptr; + net_ = nullptr; + corner_ = nullptr; gui::HeatMapDataSource::setChip(chip); if (chip != nullptr) { odb::dbBlock* block = chip->getBlock();