From 0b417159a313e84896da107e54b00c29db5c8727 Mon Sep 17 00:00:00 2001 From: Cho Moon Date: Thu, 27 Feb 2025 07:21:23 +0000 Subject: [PATCH 1/5] consider state-dependent leakage during sizing Signed-off-by: Cho Moon --- src/rsz/include/rsz/Resizer.hh | 3 ++- src/rsz/src/Resizer.cc | 39 ++++++++++++++++++++++++++++------ 2 files changed, 34 insertions(+), 8 deletions(-) diff --git a/src/rsz/include/rsz/Resizer.hh b/src/rsz/include/rsz/Resizer.hh index 04f544a2ff2..00936d1c78c 100644 --- a/src/rsz/include/rsz/Resizer.hh +++ b/src/rsz/include/rsz/Resizer.hh @@ -442,7 +442,7 @@ class Resizer : public dbStaState, public dbNetworkObserver void invalidateParasitics(const Pin* pin, const Net* net); void eraseParasitics(const Net* net); void eliminateDeadLogic(bool clean_nets); - std::optional cellLeakage(const LibertyCell* cell); + std::optional cellLeakage(LibertyCell* cell); // For debugging - calls getSwappableCells void reportEquivalentCells(LibertyCell* base_cell, bool match_cell_footprint); @@ -793,6 +793,7 @@ class Resizer : public dbStaState, public dbNetworkObserver std::stack cloned_gates_; std::unordered_set cloned_inst_set_; std::unordered_map removed_buffer_map_; + std::unordered_map> cell_leakage_cache_; // Need to track all changes for buffer removal InstanceSet all_sized_inst_set_; diff --git a/src/rsz/src/Resizer.cc b/src/rsz/src/Resizer.cc index 3f5e6d78fd1..ff9e368e5ac 100644 --- a/src/rsz/src/Resizer.cc +++ b/src/rsz/src/Resizer.cc @@ -57,6 +57,7 @@ #include "sta/Graph.hh" #include "sta/GraphDelayCalc.hh" #include "sta/InputDrive.hh" +#include "sta/LeakagePower.hh" #include "sta/Liberty.hh" #include "sta/Network.hh" #include "sta/Parasitics.hh" @@ -132,6 +133,8 @@ using sta::VertexOutEdgeIterator; using sta::BufferUse; using sta::CLOCK; +using sta::LeakagePower; +using sta::LeakagePowerSeq; Resizer::Resizer() : recover_power_(new RecoverPower(this)), @@ -1243,17 +1246,39 @@ void Resizer::resizePreamble() findTargetLoads(); } -// Convert sta results to std::optional -std::optional Resizer::cellLeakage(const LibertyCell* cell) +// Convert static cell leakage to std::optional. +// For state-dependent leakage, compute the average +// across all the power states. Cache the leakage for +// runtime. +std::optional Resizer::cellLeakage(LibertyCell* cell) { - float leakage; + auto it = cell_leakage_cache_.find(cell); + if (it != cell_leakage_cache_.end()) { + return it->second; + } + + float leakage = 0.0; bool exists; cell->leakagePower(leakage, exists); - std::optional value; if (exists) { - value = leakage; + cell_leakage_cache_[cell] = leakage; + return leakage; + } + + // Compute average leakage across power conds for state-dependent leakage + LeakagePowerSeq* leakages = cell->leakagePowers(); + if (!leakages || leakages->empty()) { + cell_leakage_cache_[cell] = std::nullopt; + return std::nullopt; + } + + float total_leakage = 0.0; + for (LeakagePower* leak : *leakages) { + total_leakage += leak->power(); } - return value; + leakage = total_leakage / leakages->size(); + cell_leakage_cache_[cell] = leakage; + return leakage; } // For debugging @@ -1269,7 +1294,7 @@ void Resizer::reportEquivalentCells(LibertyCell* base_cell, // STA sorts them by drive resistance std::sort(equiv_cells.begin(), equiv_cells.end(), - [this](const LibertyCell* a, const LibertyCell* b) { + [this](LibertyCell* a, LibertyCell* b) { if (!sta::fuzzyEqual(a->area(), b->area())) { return a->area() < b->area(); } From 31a5b9252140af143b8dcb69c6f5ab548165bb32 Mon Sep 17 00:00:00 2001 From: Cho Moon Date: Thu, 27 Feb 2025 18:22:23 +0000 Subject: [PATCH 2/5] Coverity and clang-format fix Signed-off-by: Cho Moon --- src/rsz/src/Resizer.cc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/rsz/src/Resizer.cc b/src/rsz/src/Resizer.cc index 9df31c09694..d7e99adf0da 100644 --- a/src/rsz/src/Resizer.cc +++ b/src/rsz/src/Resizer.cc @@ -1428,7 +1428,7 @@ LibertyCellSeq Resizer::getSwappableCells(LibertyCell* source_cell) } dbMaster* master = db_network_->staToDb(source_cell); - if (master && !master->isCore()) { + if (master == nullptr || !master->isCore()) { swappable_cells_cache_[source_cell] = {}; return {}; } @@ -1698,7 +1698,6 @@ int Resizer::resizeToTargetSlew(const Pin* drvr_pin) if (target_cell != cell) { debugPrint(logger_, RSZ, - "resize", 2, "{} {} -> {}", From 9f0117582a134d1db8ffdaf6e578e469966dd4ab Mon Sep 17 00:00:00 2001 From: Cho Moon Date: Thu, 27 Feb 2025 18:36:23 +0000 Subject: [PATCH 3/5] made report_equiv_cells sorting more deterministic Signed-off-by: Cho Moon --- src/rsz/src/Resizer.cc | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/rsz/src/Resizer.cc b/src/rsz/src/Resizer.cc index d7e99adf0da..64fcfd0f9e8 100644 --- a/src/rsz/src/Resizer.cc +++ b/src/rsz/src/Resizer.cc @@ -1330,19 +1330,19 @@ void Resizer::reportEquivalentCells(LibertyCell* base_cell, // Sort equiv cells by ascending area and leakage // STA sorts them by drive resistance - std::sort(equiv_cells.begin(), - equiv_cells.end(), - [this](LibertyCell* a, LibertyCell* b) { - if (!sta::fuzzyEqual(a->area(), b->area())) { - return a->area() < b->area(); - } - std::optional leakage_a = this->cellLeakage(a); - std::optional leakage_b = this->cellLeakage(b); - if (leakage_a && leakage_b) { - return *leakage_a < *leakage_b; - } - return leakage_a.has_value(); - }); + std::stable_sort(equiv_cells.begin(), + equiv_cells.end(), + [this](LibertyCell* a, LibertyCell* b) { + if (!sta::fuzzyEqual(a->area(), b->area())) { + return a->area() < b->area(); + } + std::optional leakage_a = this->cellLeakage(a); + std::optional leakage_b = this->cellLeakage(b); + if (leakage_a && leakage_b) { + return *leakage_a < *leakage_b; + } + return leakage_a.has_value() && !leakage_b.has_value(); + }); logger_->report( "The following {} cells are equivalent to {}{}", From 3577b099d8888fa46f39730909a883b995540da6 Mon Sep 17 00:00:00 2001 From: Cho Moon Date: Thu, 27 Feb 2025 19:44:26 +0000 Subject: [PATCH 4/5] removed fuzzyEqual from std::sort Signed-off-by: Cho Moon --- src/rsz/src/Resizer.cc | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/rsz/src/Resizer.cc b/src/rsz/src/Resizer.cc index 64fcfd0f9e8..b81d75df75d 100644 --- a/src/rsz/src/Resizer.cc +++ b/src/rsz/src/Resizer.cc @@ -1333,8 +1333,12 @@ void Resizer::reportEquivalentCells(LibertyCell* base_cell, std::stable_sort(equiv_cells.begin(), equiv_cells.end(), [this](LibertyCell* a, LibertyCell* b) { - if (!sta::fuzzyEqual(a->area(), b->area())) { - return a->area() < b->area(); + dbMaster* master_a = this->getDbNetwork()->staToDb(a); + dbMaster* master_b = this->getDbNetwork()->staToDb(b); + if (master_a && master_b) { + if (master_a->getArea() != master_b->getArea()) { + return master_a->getArea() < master_b->getArea(); + } } std::optional leakage_a = this->cellLeakage(a); std::optional leakage_b = this->cellLeakage(b); From 82ed546b20fdf162458c5b3180cc528f9478f83b Mon Sep 17 00:00:00 2001 From: Cho Moon Date: Thu, 27 Feb 2025 20:55:01 +0000 Subject: [PATCH 5/5] incorporated code review feedback from Ethan Signed-off-by: Cho Moon --- src/rsz/src/Resizer.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/rsz/src/Resizer.cc b/src/rsz/src/Resizer.cc index b81d75df75d..ba3f5f01df4 100644 --- a/src/rsz/src/Resizer.cc +++ b/src/rsz/src/Resizer.cc @@ -1342,9 +1342,12 @@ void Resizer::reportEquivalentCells(LibertyCell* base_cell, } std::optional leakage_a = this->cellLeakage(a); std::optional leakage_b = this->cellLeakage(b); + // Compare leakages only if they are defined if (leakage_a && leakage_b) { return *leakage_a < *leakage_b; } + // Cell 'a' has a priority as it has lower + // drive resistance than 'b' after STA sort return leakage_a.has_value() && !leakage_b.has_value(); });