From 67b57e1f0816c065849012fd90d02d5ad14895a9 Mon Sep 17 00:00:00 2001 From: Arthur Koucher Date: Mon, 22 Apr 2024 13:38:35 -0300 Subject: [PATCH 01/23] mpl2: implement first version of the boundary push Signed-off-by: Arthur Koucher --- src/mpl2/src/hier_rtlmp.cpp | 145 +++++++++++++++++++++++++++++++++++- src/mpl2/src/hier_rtlmp.h | 27 +++++++ 2 files changed, 168 insertions(+), 4 deletions(-) diff --git a/src/mpl2/src/hier_rtlmp.cpp b/src/mpl2/src/hier_rtlmp.cpp index f140f9a9f32..b5894a29ad8 100644 --- a/src/mpl2/src/hier_rtlmp.cpp +++ b/src/mpl2/src/hier_rtlmp.cpp @@ -377,6 +377,9 @@ void HierRTLMP::run() runHierarchicalMacroPlacementWithoutBusPlanning(root_cluster_); } + BoundaryPusher boundary_pusher(root_cluster_, block_); + boundary_pusher.pushMacrosToCoreBoundaries(); + generateTemporaryStdCellsPlacement(root_cluster_); for (auto& [inst, hard_macro] : hard_macro_map_) { @@ -4207,8 +4210,6 @@ void HierRTLMP::runHierarchicalMacroPlacement(Cluster* parent) } } - alignHardMacroGlobal(parent); - sa_containers.clear(); updateInstancesAssociation(parent); @@ -4738,8 +4739,6 @@ void HierRTLMP::runHierarchicalMacroPlacementWithoutBusPlanning(Cluster* parent) } } - alignHardMacroGlobal(parent); - sa_containers.clear(); updateInstancesAssociation(parent); @@ -6638,4 +6637,142 @@ void HierRTLMP::setDebugShowBundledNets(bool show_bundled_nets) graphics_->setShowBundledNets(show_bundled_nets); } +BoundaryPusher::BoundaryPusher(Cluster* root, odb::dbBlock* block) + : root_(root), block_(block) +{ + core_ = block_->getCoreArea(); + dbu_ = block->getTech()->getDbUnitsPerMicron(); +} + +void BoundaryPusher::fetchMacroClusters(Cluster* parent, + std::vector& macro_clusters) +{ + for (Cluster* child : parent->getChildren()) { + if (child->getClusterType() == HardMacroCluster) { + macro_clusters.push_back(child); + } else if (child->getClusterType() == MixedCluster) { + fetchMacroClusters(child, macro_clusters); + } + } +} + +void BoundaryPusher::pushMacrosToCoreBoundaries() +{ + std::vector macro_clusters; + fetchMacroClusters(root_, macro_clusters); + + for (Cluster* macro_cluster : macro_clusters) { + std::vector hard_macros = macro_cluster->getHardMacros(); + + bool horizontal_move_allowed = true; + bool vertical_move_allowed = true; + + const int width = micronToDbu(macro_cluster->getWidth(), dbu_); + if (width > (core_.dx() / 2)) { + horizontal_move_allowed = false; + } + + const int height = micronToDbu(macro_cluster->getHeight(), dbu_); + if (height > (core_.dy() / 2)) { + vertical_move_allowed = false; + } + + if (!horizontal_move_allowed && !vertical_move_allowed) { + continue; + } + + // A partir daqui ja pode ser uma nova função eu acho + int min_dx_to_push = std::numeric_limits::max(); + int min_dy_to_push = std::numeric_limits::max(); + + for (auto& hard_macro : hard_macros) { + hard_macros_.push_back(hard_macro); + + min_dx_to_push = std::min(min_dx_to_push, hard_macro->getRealWidthDBU()); + min_dy_to_push = std::min(min_dy_to_push, hard_macro->getRealHeightDBU()); + + if (std::abs(hard_macro->getXDBU() - core_.xMin()) < min_dx_to_push + && horizontal_move_allowed) { + moveHorizontally(hard_macro, core_.xMin()); + } + + if (std::abs(hard_macro->getUYDBU() - core_.yMax()) < min_dy_to_push + && vertical_move_allowed) { + moveVertically(hard_macro, core_.yMax() - hard_macro->getHeightDBU()); + } + + if (std::abs(hard_macro->getUXDBU() - core_.xMax()) < min_dx_to_push + && horizontal_move_allowed) { + moveHorizontally(hard_macro, core_.xMax() - hard_macro->getWidthDBU()); + } + + if (std::abs(hard_macro->getUYDBU() - core_.yMin()) < min_dy_to_push + && vertical_move_allowed) { + moveHorizontally(hard_macro, core_.yMin()); + } + } + } +} + +bool BoundaryPusher::moveVertically(HardMacro* hard_macro, int y) +{ + const int y_old = hard_macro->getYDBU(); + + hard_macro->setYDBU(y); + + if (!fitsInCore(hard_macro) || overlapsWithOtherHardMacro(hard_macro)) { + hard_macro->setYDBU(y_old); + return false; + } + + return true; +} + +bool BoundaryPusher::moveHorizontally(HardMacro* hard_macro, int x) +{ + const int x_old = hard_macro->getXDBU(); + + hard_macro->setXDBU(x); + + if (!fitsInCore(hard_macro) || overlapsWithOtherHardMacro(hard_macro)) { + hard_macro->setXDBU(x_old); + return false; + } + + return true; +} + +bool BoundaryPusher::fitsInCore(HardMacro* hard_macro) +{ + if (hard_macro->getXDBU() < core_.xMin() + || hard_macro->getYDBU() < core_.yMin() + || hard_macro->getUXDBU() > core_.xMax() + || hard_macro->getUYDBU() > core_.yMax()) { + return false; + } + + return true; +} + +bool BoundaryPusher::overlapsWithOtherHardMacro(HardMacro* hard_macro) +{ + for (const HardMacro* other_hard_macro : hard_macros_) { + if (hard_macro == other_hard_macro) { + continue; + } + + if (hard_macro->getXDBU() >= other_hard_macro->getUXDBU() + || hard_macro->getYDBU() >= other_hard_macro->getUYDBU() + || hard_macro->getUXDBU() <= other_hard_macro->getXDBU() + || hard_macro->getUYDBU() <= other_hard_macro->getYDBU()) + { + continue; + } + + return true; + } + + return false; +} + } // namespace mpl2 diff --git a/src/mpl2/src/hier_rtlmp.h b/src/mpl2/src/hier_rtlmp.h index 7c8738d295a..520d6e0bcef 100644 --- a/src/mpl2/src/hier_rtlmp.h +++ b/src/mpl2/src/hier_rtlmp.h @@ -484,4 +484,31 @@ class HierRTLMP std::unique_ptr graphics_; }; + +class BoundaryPusher +{ + public: + BoundaryPusher(Cluster* root, odb::dbBlock* block); + + void pushMacrosToCoreBoundaries(); + + void fetchMacroClusters(Cluster* parent, std::vector& macro_clusters); + + bool moveHorizontally(HardMacro* hard_macro, int x); + bool moveVertically(HardMacro* hard_macro, int y); + + bool fitsInCore(HardMacro* hard_macro); + bool overlapsWithOtherHardMacro(HardMacro* hard_macro); + + private: + Cluster* root_; + odb::dbBlock* block_; + odb::Rect core_; + + float dbu_ = 0.0f; + + std::vector hard_macros_; +}; + + } // namespace mpl2 From f86bcbc124859b24291be9e9fe840a4fcf89a08c Mon Sep 17 00:00:00 2001 From: Arthur Koucher Date: Mon, 22 Apr 2024 19:15:06 -0300 Subject: [PATCH 02/23] mpl2: rename enum / create functions to get boundary distance and push macros inside macro cluster to boundary Signed-off-by: Arthur Koucher --- src/mpl2/src/bus_synthesis.cpp | 2 +- src/mpl2/src/bus_synthesis.h | 2 +- src/mpl2/src/hier_rtlmp.cpp | 145 ++++++++++++++++++++------------- src/mpl2/src/hier_rtlmp.h | 21 +++-- src/mpl2/src/object.cpp | 20 ++--- src/mpl2/src/object.h | 20 ++--- 6 files changed, 123 insertions(+), 87 deletions(-) diff --git a/src/mpl2/src/bus_synthesis.cpp b/src/mpl2/src/bus_synthesis.cpp index 56a546b92b4..c34be315b04 100644 --- a/src/mpl2/src/bus_synthesis.cpp +++ b/src/mpl2/src/bus_synthesis.cpp @@ -1030,7 +1030,7 @@ bool calNetPaths(std::vector& soft_macros, // placed soft macros debugPrint(logger, MPL, "bus_planning", 1, "working on path {}", i); auto target_cluster = soft_macros[nets[path_net_map[i]].terminals.second].getCluster(); - PinAccess src_pin = NONE; + Boundary src_pin = NONE; Cluster* pre_cluster = nullptr; int last_edge_id = -1; const float net_weight = nets[path_net_map[i]].weight; diff --git a/src/mpl2/src/bus_synthesis.h b/src/mpl2/src/bus_synthesis.h index 0e560b3f23d..97e7146026c 100644 --- a/src/mpl2/src/bus_synthesis.h +++ b/src/mpl2/src/bus_synthesis.h @@ -102,7 +102,7 @@ struct Edge std::pair terminals; // the vertex_id of two terminal vertices bool direction = false; // True for horizontal and False for vertical bool internal = true; // True for edge within one SoftMacro otherwise false - PinAccess pin_access + Boundary pin_access = NONE; // pin_access for internal == false (for src vertex) float length = 0.0; // the length of edge float length_w = 0.0; // weighted length : weight * length diff --git a/src/mpl2/src/hier_rtlmp.cpp b/src/mpl2/src/hier_rtlmp.cpp index b5894a29ad8..a29ddb0bd19 100644 --- a/src/mpl2/src/hier_rtlmp.cpp +++ b/src/mpl2/src/hier_rtlmp.cpp @@ -3432,7 +3432,7 @@ void HierRTLMP::runHierarchicalMacroPlacement(Cluster* parent) // height = 0.0) In our simulated annealing engine, the dummary softmacro // will no effect on SA We have four dummy SoftMacros based on our // definition - std::vector pins = {L, T, R, B}; + std::vector pins = {L, T, R, B}; for (auto& pin : pins) { soft_macro_id_map[toString(pin)] = macros.size(); macros.emplace_back(0.0, 0.0, toString(pin)); @@ -6637,6 +6637,8 @@ void HierRTLMP::setDebugShowBundledNets(bool show_bundled_nets) graphics_->setShowBundledNets(show_bundled_nets); } +//////// BoundaryPusher //////// + BoundaryPusher::BoundaryPusher(Cluster* root, odb::dbBlock* block) : root_(root), block_(block) { @@ -6645,7 +6647,7 @@ BoundaryPusher::BoundaryPusher(Cluster* root, odb::dbBlock* block) } void BoundaryPusher::fetchMacroClusters(Cluster* parent, - std::vector& macro_clusters) + std::vector& macro_clusters) { for (Cluster* child : parent->getChildren()) { if (child->getClusterType() == HardMacroCluster) { @@ -6662,8 +6664,8 @@ void BoundaryPusher::pushMacrosToCoreBoundaries() fetchMacroClusters(root_, macro_clusters); for (Cluster* macro_cluster : macro_clusters) { - std::vector hard_macros = macro_cluster->getHardMacros(); - + // We don't push macros to the boundaries if that will destroy + // the shape of an array of macros. bool horizontal_move_allowed = true; bool vertical_move_allowed = true; @@ -6681,77 +6683,109 @@ void BoundaryPusher::pushMacrosToCoreBoundaries() continue; } - // A partir daqui ja pode ser uma nova função eu acho - int min_dx_to_push = std::numeric_limits::max(); - int min_dy_to_push = std::numeric_limits::max(); + std::map boundaries_distance = getDistanceToCloseBoundaries( + macro_cluster, vertical_move_allowed, horizontal_move_allowed); - for (auto& hard_macro : hard_macros) { - hard_macros_.push_back(hard_macro); + pushMacrosToCoreBoundaries(macro_cluster, boundaries_distance); + } +} - min_dx_to_push = std::min(min_dx_to_push, hard_macro->getRealWidthDBU()); - min_dy_to_push = std::min(min_dy_to_push, hard_macro->getRealHeightDBU()); +std::map BoundaryPusher::getDistanceToCloseBoundaries( + Cluster* macro_cluster, + bool vertical_move_allowed, + bool horizontal_move_allowed) +{ + std::map boundaries_distance; - if (std::abs(hard_macro->getXDBU() - core_.xMin()) < min_dx_to_push - && horizontal_move_allowed) { - moveHorizontally(hard_macro, core_.xMin()); - } + std::vector hard_macros = macro_cluster->getHardMacros(); - if (std::abs(hard_macro->getUYDBU() - core_.yMax()) < min_dy_to_push - && vertical_move_allowed) { - moveVertically(hard_macro, core_.yMax() - hard_macro->getHeightDBU()); - } + int min_dx_to_core = std::numeric_limits::max(); + int min_dy_to_core = std::numeric_limits::max(); - if (std::abs(hard_macro->getUXDBU() - core_.xMax()) < min_dx_to_push - && horizontal_move_allowed) { - moveHorizontally(hard_macro, core_.xMax() - hard_macro->getWidthDBU()); - } + for (HardMacro* hard_macro : hard_macros) { + hard_macros_.push_back(hard_macro); - if (std::abs(hard_macro->getUYDBU() - core_.yMin()) < min_dy_to_push - && vertical_move_allowed) { - moveHorizontally(hard_macro, core_.yMin()); - } - } + min_dx_to_core = std::min(min_dy_to_core, hard_macro->getRealWidthDBU()); + min_dy_to_core = std::min(min_dy_to_core, hard_macro->getRealHeightDBU()); } -} -bool BoundaryPusher::moveVertically(HardMacro* hard_macro, int y) -{ - const int y_old = hard_macro->getYDBU(); + for (HardMacro* hard_macro : hard_macros) { + int dx_to_core = std::abs(hard_macro->getXDBU() - core_.xMin()); + if (dx_to_core < min_dx_to_core && horizontal_move_allowed) { + boundaries_distance[L] = -dx_to_core; + } - hard_macro->setYDBU(y); + dx_to_core = std::abs(hard_macro->getUXDBU() - core_.xMax()); + if (dx_to_core < min_dx_to_core && horizontal_move_allowed) { + boundaries_distance[R] = dx_to_core; + } - if (!fitsInCore(hard_macro) || overlapsWithOtherHardMacro(hard_macro)) { - hard_macro->setYDBU(y_old); - return false; + int dy_to_core = std::abs(hard_macro->getUYDBU() - core_.yMax()); + if (std::abs(hard_macro->getUYDBU() - core_.yMax()) < min_dy_to_core + && vertical_move_allowed) { + boundaries_distance[T] = dy_to_core; + } + + dy_to_core = std::abs(hard_macro->getUYDBU() - core_.yMin()); + if (dy_to_core < min_dy_to_core && vertical_move_allowed) { + boundaries_distance[B] = -dy_to_core; + } } - return true; + return boundaries_distance; } -bool BoundaryPusher::moveHorizontally(HardMacro* hard_macro, int x) +void BoundaryPusher::pushMacrosToCoreBoundaries( + Cluster* macro_cluster, + const std::map& boundaries_distance) { - const int x_old = hard_macro->getXDBU(); + std::vector hard_macros = macro_cluster->getHardMacros(); - hard_macro->setXDBU(x); + for (const auto& [boundary, distance] : boundaries_distance) { + std::vector moved_hard_macros; + bool produced_overlap = false; - if (!fitsInCore(hard_macro) || overlapsWithOtherHardMacro(hard_macro)) { - hard_macro->setXDBU(x_old); - return false; - } + // The distance to revert the move that caused the overlap. + int overlap_distance = 0; + Boundary overlap_boundary; - return true; -} + for (HardMacro* hard_macro : hard_macros) { + moveHardMacro(hard_macro, boundary, distance); + } -bool BoundaryPusher::fitsInCore(HardMacro* hard_macro) -{ - if (hard_macro->getXDBU() < core_.xMin() - || hard_macro->getYDBU() < core_.yMin() - || hard_macro->getUXDBU() > core_.xMax() - || hard_macro->getUYDBU() > core_.yMax()) { - return false; + for (HardMacro* hard_macro : hard_macros) { + if (overlapsWithOtherHardMacro(hard_macro)) { + produced_overlap = true; + overlap_distance = -distance; + overlap_boundary = boundary; + break; + } + } + + if (produced_overlap) { + for (HardMacro* hard_macro : moved_hard_macros) { + moveHardMacro(hard_macro, overlap_boundary, overlap_distance); + } + } } +} - return true; +void BoundaryPusher::moveHardMacro(HardMacro* hard_macro, Boundary boundary, int distance) +{ + switch(boundary) { + case NONE: + return; + case L: + case R: { + hard_macro->setXDBU(hard_macro->getXDBU() + distance); + break; + } + case T: + case B: { + hard_macro->setYDBU(hard_macro->getYDBU() + distance); + break; + } + } } bool BoundaryPusher::overlapsWithOtherHardMacro(HardMacro* hard_macro) @@ -6764,8 +6798,7 @@ bool BoundaryPusher::overlapsWithOtherHardMacro(HardMacro* hard_macro) if (hard_macro->getXDBU() >= other_hard_macro->getUXDBU() || hard_macro->getYDBU() >= other_hard_macro->getUYDBU() || hard_macro->getUXDBU() <= other_hard_macro->getXDBU() - || hard_macro->getUYDBU() <= other_hard_macro->getYDBU()) - { + || hard_macro->getUYDBU() <= other_hard_macro->getYDBU()) { continue; } diff --git a/src/mpl2/src/hier_rtlmp.h b/src/mpl2/src/hier_rtlmp.h index 520d6e0bcef..e187722b44d 100644 --- a/src/mpl2/src/hier_rtlmp.h +++ b/src/mpl2/src/hier_rtlmp.h @@ -138,7 +138,7 @@ class HierRTLMP void writeMacroPlacement(const std::string& file_name); private: - using IOSpans = std::map>; + using IOSpans = std::map>; // General Hier-RTLMP flow functions void initMacroPlacer(); @@ -492,15 +492,19 @@ class BoundaryPusher void pushMacrosToCoreBoundaries(); - void fetchMacroClusters(Cluster* parent, std::vector& macro_clusters); - - bool moveHorizontally(HardMacro* hard_macro, int x); - bool moveVertically(HardMacro* hard_macro, int y); - - bool fitsInCore(HardMacro* hard_macro); + private: + void pushMacrosToCoreBoundaries( + Cluster* macro_cluster, + const std::map& boundaries_distance); + + void fetchMacroClusters(Cluster* parent, + std::vector& macro_clusters); + std::map getDistanceToCloseBoundaries(Cluster* macro_cluster, + bool vertical_move_allowed, + bool horizontal_move_allowed); + void moveHardMacro(HardMacro* hard_macro, Boundary boundary, int distance); bool overlapsWithOtherHardMacro(HardMacro* hard_macro); - private: Cluster* root_; odb::dbBlock* block_; odb::Rect core_; @@ -510,5 +514,4 @@ class BoundaryPusher std::vector hard_macros_; }; - } // namespace mpl2 diff --git a/src/mpl2/src/object.cpp b/src/mpl2/src/object.cpp index ce8c9338200..06310713379 100644 --- a/src/mpl2/src/object.cpp +++ b/src/mpl2/src/object.cpp @@ -57,7 +57,7 @@ int micronToDbu(float metric, float dbu) return std::round(metric * dbu); } -std::string toString(const PinAccess& pin_access) +std::string toString(const Boundary& pin_access) { switch (pin_access) { case L: @@ -73,7 +73,7 @@ std::string toString(const PinAccess& pin_access) } } -PinAccess opposite(const PinAccess& pin_access) +Boundary opposite(const Boundary& pin_access) { switch (pin_access) { case L: @@ -646,7 +646,7 @@ int Cluster::getCloseCluster(const std::vector& candidate_clusters, // Pin Access Support void Cluster::setPinAccess(int cluster_id, - PinAccess pin_access, + Boundary pin_access, float net_weight) { if (cluster_id < 0) { @@ -656,32 +656,32 @@ void Cluster::setPinAccess(int cluster_id, toString(pin_access)); } pin_access_map_[cluster_id] - = std::pair(pin_access, net_weight); + = std::pair(pin_access, net_weight); } -const std::pair Cluster::getPinAccess(int cluster_id) +const std::pair Cluster::getPinAccess(int cluster_id) { return pin_access_map_[cluster_id]; } -const std::map> Cluster::getPinAccessMap() +const std::map> Cluster::getPinAccessMap() const { return pin_access_map_; } -const std::map> +const std::map> Cluster::getBoundaryConnection() const { return boundary_connection_map_; } -void Cluster::addBoundaryConnection(PinAccess pin_a, - PinAccess pin_b, +void Cluster::addBoundaryConnection(Boundary pin_a, + Boundary pin_b, float num_net) { if (boundary_connection_map_.find(pin_a) == boundary_connection_map_.end()) { - std::map pin_map; + std::map pin_map; pin_map[pin_b] = num_net; boundary_connection_map_[pin_a] = pin_map; } else { diff --git a/src/mpl2/src/object.h b/src/mpl2/src/object.h index c6e799630b1..496d2d28ae5 100644 --- a/src/mpl2/src/object.h +++ b/src/mpl2/src/object.h @@ -108,7 +108,7 @@ int micronToDbu(float metric, float dbu); // along the corresponding { B, L, T, R } boundary // The size of the hard macro blockage is determined the by the // size of that cluster -enum PinAccess +enum Boundary { NONE, B, @@ -117,8 +117,8 @@ enum PinAccess R }; -std::string toString(const PinAccess& pin_access); -PinAccess opposite(const PinAccess& pin_access); +std::string toString(const Boundary& pin_access); +Boundary opposite(const Boundary& pin_access); // Define the type for clusters // StdCellCluster only has std cells. In the cluster type, it @@ -269,11 +269,11 @@ class Cluster // not have any connections outsize the parent cluster // All the outside connections have been converted to the connections // related to pin access - void setPinAccess(int cluster_id, PinAccess pin_access, float weight); - void addBoundaryConnection(PinAccess pin_a, PinAccess pin_b, float num_net); - const std::pair getPinAccess(int cluster_id); - const std::map> getPinAccessMap() const; - const std::map> getBoundaryConnection() + void setPinAccess(int cluster_id, Boundary pin_access, float weight); + void addBoundaryConnection(Boundary pin_a, Boundary pin_b, float num_net); + const std::pair getPinAccess(int cluster_id); + const std::map> getPinAccessMap() const; + const std::map> getBoundaryConnection() const; // virtual connections @@ -338,8 +338,8 @@ class Cluster std::vector> virtual_connections_; // pin access for each bundled connection - std::map> pin_access_map_; - std::map> boundary_connection_map_; + std::map> pin_access_map_; + std::map> boundary_connection_map_; utl::Logger* logger_; }; From 05c9b318eea9a778b25855a8fb47cc1f1719c32c Mon Sep 17 00:00:00 2001 From: Arthur Koucher Date: Mon, 22 Apr 2024 19:18:00 -0300 Subject: [PATCH 03/23] mpl2: format Signed-off-by: Arthur Koucher --- src/mpl2/src/hier_rtlmp.cpp | 8 +++++--- src/mpl2/src/hier_rtlmp.h | 7 ++++--- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/mpl2/src/hier_rtlmp.cpp b/src/mpl2/src/hier_rtlmp.cpp index a29ddb0bd19..f5e7e2d3fc8 100644 --- a/src/mpl2/src/hier_rtlmp.cpp +++ b/src/mpl2/src/hier_rtlmp.cpp @@ -6770,9 +6770,11 @@ void BoundaryPusher::pushMacrosToCoreBoundaries( } } -void BoundaryPusher::moveHardMacro(HardMacro* hard_macro, Boundary boundary, int distance) -{ - switch(boundary) { +void BoundaryPusher::moveHardMacro(HardMacro* hard_macro, + Boundary boundary, + int distance) +{ + switch (boundary) { case NONE: return; case L: diff --git a/src/mpl2/src/hier_rtlmp.h b/src/mpl2/src/hier_rtlmp.h index e187722b44d..d1a4ba5da80 100644 --- a/src/mpl2/src/hier_rtlmp.h +++ b/src/mpl2/src/hier_rtlmp.h @@ -499,9 +499,10 @@ class BoundaryPusher void fetchMacroClusters(Cluster* parent, std::vector& macro_clusters); - std::map getDistanceToCloseBoundaries(Cluster* macro_cluster, - bool vertical_move_allowed, - bool horizontal_move_allowed); + std::map getDistanceToCloseBoundaries( + Cluster* macro_cluster, + bool vertical_move_allowed, + bool horizontal_move_allowed); void moveHardMacro(HardMacro* hard_macro, Boundary boundary, int distance); bool overlapsWithOtherHardMacro(HardMacro* hard_macro); From 2ede89a32064b3d1b81acceb65793676889ba85b Mon Sep 17 00:00:00 2001 From: Arthur Koucher Date: Mon, 22 Apr 2024 19:33:49 -0300 Subject: [PATCH 04/23] mpl2: remove unneeded variables and container Signed-off-by: Arthur Koucher --- src/mpl2/src/hier_rtlmp.cpp | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/src/mpl2/src/hier_rtlmp.cpp b/src/mpl2/src/hier_rtlmp.cpp index f5e7e2d3fc8..676d4709cdd 100644 --- a/src/mpl2/src/hier_rtlmp.cpp +++ b/src/mpl2/src/hier_rtlmp.cpp @@ -6742,13 +6742,8 @@ void BoundaryPusher::pushMacrosToCoreBoundaries( std::vector hard_macros = macro_cluster->getHardMacros(); for (const auto& [boundary, distance] : boundaries_distance) { - std::vector moved_hard_macros; bool produced_overlap = false; - // The distance to revert the move that caused the overlap. - int overlap_distance = 0; - Boundary overlap_boundary; - for (HardMacro* hard_macro : hard_macros) { moveHardMacro(hard_macro, boundary, distance); } @@ -6756,15 +6751,14 @@ void BoundaryPusher::pushMacrosToCoreBoundaries( for (HardMacro* hard_macro : hard_macros) { if (overlapsWithOtherHardMacro(hard_macro)) { produced_overlap = true; - overlap_distance = -distance; - overlap_boundary = boundary; break; } } if (produced_overlap) { - for (HardMacro* hard_macro : moved_hard_macros) { - moveHardMacro(hard_macro, overlap_boundary, overlap_distance); + // Move back to original position + for (HardMacro* hard_macro : hard_macros) { + moveHardMacro(hard_macro, boundary, (-distance)); } } } From a44c5929c36f5b56f36c284312af523b4f9bb984 Mon Sep 17 00:00:00 2001 From: Arthur Koucher Date: Mon, 22 Apr 2024 19:39:14 -0300 Subject: [PATCH 05/23] mpl2: fix iterations Signed-off-by: Arthur Koucher --- src/mpl2/src/hier_rtlmp.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/mpl2/src/hier_rtlmp.cpp b/src/mpl2/src/hier_rtlmp.cpp index 676d4709cdd..0a3298d3f59 100644 --- a/src/mpl2/src/hier_rtlmp.cpp +++ b/src/mpl2/src/hier_rtlmp.cpp @@ -6751,12 +6751,11 @@ void BoundaryPusher::pushMacrosToCoreBoundaries( for (HardMacro* hard_macro : hard_macros) { if (overlapsWithOtherHardMacro(hard_macro)) { produced_overlap = true; - break; } } if (produced_overlap) { - // Move back to original position + // Move back to original position. for (HardMacro* hard_macro : hard_macros) { moveHardMacro(hard_macro, boundary, (-distance)); } From 1a81be4f4a3cad41adfb84268cdc67300e3795ff Mon Sep 17 00:00:00 2001 From: Arthur Koucher Date: Mon, 22 Apr 2024 20:21:32 -0300 Subject: [PATCH 06/23] mpl2: use instantiated object Signed-off-by: Arthur Koucher --- src/mpl2/src/hier_rtlmp.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mpl2/src/hier_rtlmp.cpp b/src/mpl2/src/hier_rtlmp.cpp index 0a3298d3f59..edbbf461d72 100644 --- a/src/mpl2/src/hier_rtlmp.cpp +++ b/src/mpl2/src/hier_rtlmp.cpp @@ -6643,7 +6643,7 @@ BoundaryPusher::BoundaryPusher(Cluster* root, odb::dbBlock* block) : root_(root), block_(block) { core_ = block_->getCoreArea(); - dbu_ = block->getTech()->getDbUnitsPerMicron(); + dbu_ = block_->getTech()->getDbUnitsPerMicron(); } void BoundaryPusher::fetchMacroClusters(Cluster* parent, From 4642744b5a0751e1568cb8ff15c31bb48f939ff9 Mon Sep 17 00:00:00 2001 From: Arthur Koucher Date: Tue, 23 Apr 2024 11:38:08 -0300 Subject: [PATCH 07/23] mpl2: nest ifs Signed-off-by: Arthur Koucher --- src/mpl2/src/hier_rtlmp.cpp | 37 ++++++++++++++++++++++--------------- 1 file changed, 22 insertions(+), 15 deletions(-) diff --git a/src/mpl2/src/hier_rtlmp.cpp b/src/mpl2/src/hier_rtlmp.cpp index edbbf461d72..91942ae23d0 100644 --- a/src/mpl2/src/hier_rtlmp.cpp +++ b/src/mpl2/src/hier_rtlmp.cpp @@ -6710,25 +6710,32 @@ std::map BoundaryPusher::getDistanceToCloseBoundaries( } for (HardMacro* hard_macro : hard_macros) { - int dx_to_core = std::abs(hard_macro->getXDBU() - core_.xMin()); - if (dx_to_core < min_dx_to_core && horizontal_move_allowed) { - boundaries_distance[L] = -dx_to_core; - } + if (horizontal_move_allowed) { + int dx_to_core = std::abs(hard_macro->getXDBU() - core_.xMin()); - dx_to_core = std::abs(hard_macro->getUXDBU() - core_.xMax()); - if (dx_to_core < min_dx_to_core && horizontal_move_allowed) { - boundaries_distance[R] = dx_to_core; - } + if (dx_to_core < min_dx_to_core) { + boundaries_distance[L] = -dx_to_core; + } - int dy_to_core = std::abs(hard_macro->getUYDBU() - core_.yMax()); - if (std::abs(hard_macro->getUYDBU() - core_.yMax()) < min_dy_to_core - && vertical_move_allowed) { - boundaries_distance[T] = dy_to_core; + dx_to_core = std::abs(hard_macro->getUXDBU() - core_.xMax()); + + if (dx_to_core < min_dx_to_core) { + boundaries_distance[R] = dx_to_core; + } } - dy_to_core = std::abs(hard_macro->getUYDBU() - core_.yMin()); - if (dy_to_core < min_dy_to_core && vertical_move_allowed) { - boundaries_distance[B] = -dy_to_core; + if (vertical_move_allowed) { + int dy_to_core = std::abs(hard_macro->getUYDBU() - core_.yMax()); + + if (std::abs(hard_macro->getUYDBU() - core_.yMax()) < min_dy_to_core) { + boundaries_distance[T] = dy_to_core; + } + + dy_to_core = std::abs(hard_macro->getUYDBU() - core_.yMin()); + + if (dy_to_core < min_dy_to_core) { + boundaries_distance[B] = -dy_to_core; + } } } From d5c07d9eca55a6ff609a932b89dddc4021328a8a Mon Sep 17 00:00:00 2001 From: Arthur Koucher Date: Tue, 23 Apr 2024 19:02:33 -0300 Subject: [PATCH 08/23] mpl2: 1) some renaming 2) create map to store io blockages data 3) use width / height considering halos 4) avoid moving macros when distance to boundary is 0 5) add check to verify if the hardmacro overlap is happening inside the macro cluster we're trying to move Signed-off-by: Arthur Koucher --- src/mpl2/src/hier_rtlmp.cpp | 140 ++++++++++++++++++++++++------------ src/mpl2/src/hier_rtlmp.h | 16 +++-- 2 files changed, 106 insertions(+), 50 deletions(-) diff --git a/src/mpl2/src/hier_rtlmp.cpp b/src/mpl2/src/hier_rtlmp.cpp index 91942ae23d0..98a556db6a3 100644 --- a/src/mpl2/src/hier_rtlmp.cpp +++ b/src/mpl2/src/hier_rtlmp.cpp @@ -377,7 +377,8 @@ void HierRTLMP::run() runHierarchicalMacroPlacementWithoutBusPlanning(root_cluster_); } - BoundaryPusher boundary_pusher(root_cluster_, block_); + BoundaryPusher boundary_pusher( + root_cluster_, block_, boundary_to_io_blockage_); boundary_pusher.pushMacrosToCoreBoundaries(); generateTemporaryStdCellsPlacement(root_cluster_); @@ -3151,31 +3152,43 @@ void HierRTLMP::setIOClustersBlockages() // Note that the range can be larger than the respective core dimension. // As SA only sees what is inside its current outline, this is not a problem. if (io_spans[L].second > io_spans[L].first) { - macro_blockages_.emplace_back(root.xMin(), - io_spans[L].first, - root.xMin() + depth, - io_spans[L].second); + Rect left_io_blockage(root.xMin(), + io_spans[L].first, + root.xMin() + depth, + io_spans[L].second); + + boundary_to_io_blockage_[L] = left_io_blockage; + macro_blockages_.push_back(left_io_blockage); } if (io_spans[T].second > io_spans[T].first) { - macro_blockages_.emplace_back(io_spans[T].first, - root.yMax() - depth, - io_spans[T].second, - root.yMax()); + Rect top_io_blockage(io_spans[T].first, + root.yMax() - depth, + io_spans[T].second, + root.yMax()); + + boundary_to_io_blockage_[T] = top_io_blockage; + macro_blockages_.push_back(top_io_blockage); } if (io_spans[R].second > io_spans[R].first) { - macro_blockages_.emplace_back(root.xMax() - depth, - io_spans[R].first, - root.xMax(), - io_spans[R].second); + Rect right_io_blockage(root.xMax() - depth, + io_spans[R].first, + root.xMax(), + io_spans[R].second); + + boundary_to_io_blockage_[R] = right_io_blockage; + macro_blockages_.push_back(right_io_blockage); } if (io_spans[B].second > io_spans[B].first) { - macro_blockages_.emplace_back(io_spans[B].first, - root.yMin(), - io_spans[B].second, - root.yMin() + depth); + Rect bottom_io_blockage(io_spans[B].first, + root.yMin(), + io_spans[B].second, + root.yMin() + depth); + + boundary_to_io_blockage_[B] = bottom_io_blockage; + macro_blockages_.push_back(bottom_io_blockage); } } @@ -6639,11 +6652,28 @@ void HierRTLMP::setDebugShowBundledNets(bool show_bundled_nets) //////// BoundaryPusher //////// -BoundaryPusher::BoundaryPusher(Cluster* root, odb::dbBlock* block) +BoundaryPusher::BoundaryPusher( + Cluster* root, + odb::dbBlock* block, + const std::map& boundary_to_io_blockage) : root_(root), block_(block) { core_ = block_->getCoreArea(); dbu_ = block_->getTech()->getDbUnitsPerMicron(); + + setIOBlockages(boundary_to_io_blockage); +} + +void BoundaryPusher::setIOBlockages( + const std::map& boundary_to_io_blockage) +{ + for (const auto& [boundary, box] : boundary_to_io_blockage) { + boundary_to_io_blockage_[boundary] + = odb::Rect(micronToDbu(box.getX(), dbu_), + micronToDbu(box.getY(), dbu_), + micronToDbu(box.getX() + box.getWidth(), dbu_), + micronToDbu(box.getY() + box.getHeight(), dbu_)); + } } void BoundaryPusher::fetchMacroClusters(Cluster* parent, @@ -6705,36 +6735,36 @@ std::map BoundaryPusher::getDistanceToCloseBoundaries( for (HardMacro* hard_macro : hard_macros) { hard_macros_.push_back(hard_macro); - min_dx_to_core = std::min(min_dy_to_core, hard_macro->getRealWidthDBU()); - min_dy_to_core = std::min(min_dy_to_core, hard_macro->getRealHeightDBU()); + min_dx_to_core = std::min(min_dy_to_core, hard_macro->getWidthDBU()); + min_dy_to_core = std::min(min_dy_to_core, hard_macro->getHeightDBU()); } for (HardMacro* hard_macro : hard_macros) { if (horizontal_move_allowed) { - int dx_to_core = std::abs(hard_macro->getXDBU() - core_.xMin()); - - if (dx_to_core < min_dx_to_core) { - boundaries_distance[L] = -dx_to_core; + const int distance_to_left + = std::abs(hard_macro->getXDBU() - core_.xMin()); + if (distance_to_left < min_dx_to_core) { + boundaries_distance[L] = -distance_to_left; } - dx_to_core = std::abs(hard_macro->getUXDBU() - core_.xMax()); - - if (dx_to_core < min_dx_to_core) { - boundaries_distance[R] = dx_to_core; + const int distance_to_right + = std::abs(hard_macro->getUXDBU() - core_.xMax()); + if (distance_to_right < min_dx_to_core) { + boundaries_distance[R] = distance_to_right; } } if (vertical_move_allowed) { - int dy_to_core = std::abs(hard_macro->getUYDBU() - core_.yMax()); - - if (std::abs(hard_macro->getUYDBU() - core_.yMax()) < min_dy_to_core) { - boundaries_distance[T] = dy_to_core; + const int distance_to_top + = std::abs(hard_macro->getUYDBU() - core_.yMax()); + if (distance_to_top < min_dy_to_core) { + boundaries_distance[T] = distance_to_top; } - dy_to_core = std::abs(hard_macro->getUYDBU() - core_.yMin()); - - if (dy_to_core < min_dy_to_core) { - boundaries_distance[B] = -dy_to_core; + const int distance_to_bottom + = std::abs(hard_macro->getUYDBU() - core_.yMin()); + if (distance_to_bottom < min_dy_to_core) { + boundaries_distance[B] = -distance_to_bottom; } } } @@ -6749,6 +6779,10 @@ void BoundaryPusher::pushMacrosToCoreBoundaries( std::vector hard_macros = macro_cluster->getHardMacros(); for (const auto& [boundary, distance] : boundaries_distance) { + if (distance == 0) { + continue; + } + bool produced_overlap = false; for (HardMacro* hard_macro : hard_macros) { @@ -6756,7 +6790,7 @@ void BoundaryPusher::pushMacrosToCoreBoundaries( } for (HardMacro* hard_macro : hard_macros) { - if (overlapsWithOtherHardMacro(hard_macro)) { + if (overlapsWithOtherHardMacro(hard_macro, hard_macros)) { produced_overlap = true; } } @@ -6790,24 +6824,40 @@ void BoundaryPusher::moveHardMacro(HardMacro* hard_macro, } } -bool BoundaryPusher::overlapsWithOtherHardMacro(HardMacro* hard_macro) +bool BoundaryPusher::overlapsWithOtherHardMacro( + HardMacro* hard_macro, + const std::vector& same_cluster_hard_macros) { for (const HardMacro* other_hard_macro : hard_macros_) { - if (hard_macro == other_hard_macro) { - continue; + // Due to floating point evilness, there might exist overlap across the + // HardMacros inside a macro cluster so we don't consider those. + bool other_hard_macro_belongs_to_same_cluster = false; + + for (const HardMacro* same_cluster_hard_macro : same_cluster_hard_macros) { + if (other_hard_macro == same_cluster_hard_macro) { + other_hard_macro_belongs_to_same_cluster = true; + break; + } } - if (hard_macro->getXDBU() >= other_hard_macro->getUXDBU() - || hard_macro->getYDBU() >= other_hard_macro->getUYDBU() - || hard_macro->getUXDBU() <= other_hard_macro->getXDBU() - || hard_macro->getUYDBU() <= other_hard_macro->getYDBU()) { + if (other_hard_macro_belongs_to_same_cluster) { continue; } - return true; + if (hard_macro->getXDBU() < other_hard_macro->getUXDBU() + && hard_macro->getYDBU() < other_hard_macro->getUYDBU() + && hard_macro->getUXDBU() > other_hard_macro->getXDBU() + && hard_macro->getUYDBU() > other_hard_macro->getYDBU()) { + return true; + } } return false; } +bool BoundaryPusher::overlapsWithIOBlockage(HardMacro* hard_macro, + Boundary boundary) +{ +} + } // namespace mpl2 diff --git a/src/mpl2/src/hier_rtlmp.h b/src/mpl2/src/hier_rtlmp.h index d1a4ba5da80..ac8dd8d9896 100644 --- a/src/mpl2/src/hier_rtlmp.h +++ b/src/mpl2/src/hier_rtlmp.h @@ -386,6 +386,7 @@ class HierRTLMP std::map guides_; // macro_name, guide std::vector placement_blockages_; std::vector macro_blockages_; + std::map boundary_to_io_blockage_; // Fast SA hyperparameter float init_prob_ = 0.9; @@ -488,15 +489,17 @@ class HierRTLMP class BoundaryPusher { public: - BoundaryPusher(Cluster* root, odb::dbBlock* block); + BoundaryPusher(Cluster* root, + odb::dbBlock* block, + const std::map& boundary_to_io_blockage); void pushMacrosToCoreBoundaries(); private: + void setIOBlockages(const std::map& boundary_to_io_blockage); void pushMacrosToCoreBoundaries( Cluster* macro_cluster, const std::map& boundaries_distance); - void fetchMacroClusters(Cluster* parent, std::vector& macro_clusters); std::map getDistanceToCloseBoundaries( @@ -504,14 +507,17 @@ class BoundaryPusher bool vertical_move_allowed, bool horizontal_move_allowed); void moveHardMacro(HardMacro* hard_macro, Boundary boundary, int distance); - bool overlapsWithOtherHardMacro(HardMacro* hard_macro); + bool overlapsWithOtherHardMacro( + HardMacro* hard_macro, + const std::vector& cluster_hard_macros); + bool overlapsWithIOBlockage(HardMacro* hard_macro, Boundary boundary); Cluster* root_; odb::dbBlock* block_; odb::Rect core_; + float dbu_; - float dbu_ = 0.0f; - + std::map boundary_to_io_blockage_; std::vector hard_macros_; }; From 36a09d3180b419f54159c1649b87615c26e70868 Mon Sep 17 00:00:00 2001 From: Arthur Koucher Date: Tue, 23 Apr 2024 22:27:41 -0300 Subject: [PATCH 09/23] mpl2: 1) avoid iterating empty map 2) checking overlap based on cluster box rather than individual HardMacros 3) consider IOBlockage overlap Signed-off-by: Arthur Koucher --- src/mpl2/src/hier_rtlmp.cpp | 73 +++++++++++++++++++++++++------------ src/mpl2/src/hier_rtlmp.h | 7 ++-- 2 files changed, 53 insertions(+), 27 deletions(-) diff --git a/src/mpl2/src/hier_rtlmp.cpp b/src/mpl2/src/hier_rtlmp.cpp index 98a556db6a3..6f905dec09c 100644 --- a/src/mpl2/src/hier_rtlmp.cpp +++ b/src/mpl2/src/hier_rtlmp.cpp @@ -6776,6 +6776,10 @@ void BoundaryPusher::pushMacrosToCoreBoundaries( Cluster* macro_cluster, const std::map& boundaries_distance) { + if (boundaries_distance.empty()) { + return; + } + std::vector hard_macros = macro_cluster->getHardMacros(); for (const auto& [boundary, distance] : boundaries_distance) { @@ -6783,19 +6787,26 @@ void BoundaryPusher::pushMacrosToCoreBoundaries( continue; } - bool produced_overlap = false; + odb::Rect cluster_box( + micronToDbu(macro_cluster->getX(), dbu_), + micronToDbu(macro_cluster->getY(), dbu_), + micronToDbu(macro_cluster->getX() + macro_cluster->getWidth(), dbu_), + micronToDbu(macro_cluster->getY() + macro_cluster->getHeight(), dbu_)); for (HardMacro* hard_macro : hard_macros) { moveHardMacro(hard_macro, boundary, distance); } - for (HardMacro* hard_macro : hard_macros) { - if (overlapsWithOtherHardMacro(hard_macro, hard_macros)) { - produced_overlap = true; - } + if (boundary == L || boundary == R) { + cluster_box.moveDelta(distance, 0); + } else if (boundary == T || boundary == B) { + cluster_box.moveDelta(0, distance); } - if (produced_overlap) { + // Check based on the shape of the macro cluster to avoid iterating each + // of its HardMacros. + if (overlapsWithHardMacro(cluster_box, hard_macros) + || overlapsWithIOBlockage(cluster_box, boundary)) { // Move back to original position. for (HardMacro* hard_macro : hard_macros) { moveHardMacro(hard_macro, boundary, (-distance)); @@ -6824,30 +6835,28 @@ void BoundaryPusher::moveHardMacro(HardMacro* hard_macro, } } -bool BoundaryPusher::overlapsWithOtherHardMacro( - HardMacro* hard_macro, - const std::vector& same_cluster_hard_macros) +bool BoundaryPusher::overlapsWithHardMacro( + const odb::Rect& cluster_box, + const std::vector& cluster_hard_macros) { - for (const HardMacro* other_hard_macro : hard_macros_) { - // Due to floating point evilness, there might exist overlap across the - // HardMacros inside a macro cluster so we don't consider those. - bool other_hard_macro_belongs_to_same_cluster = false; - - for (const HardMacro* same_cluster_hard_macro : same_cluster_hard_macros) { - if (other_hard_macro == same_cluster_hard_macro) { - other_hard_macro_belongs_to_same_cluster = true; + for (const HardMacro* hard_macro : hard_macros_) { + bool hard_macro_belongs_to_cluster = false; + + for (const HardMacro* cluster_hard_macro : cluster_hard_macros) { + if (hard_macro == cluster_hard_macro) { + hard_macro_belongs_to_cluster = true; break; } } - if (other_hard_macro_belongs_to_same_cluster) { + if (hard_macro_belongs_to_cluster) { continue; } - if (hard_macro->getXDBU() < other_hard_macro->getUXDBU() - && hard_macro->getYDBU() < other_hard_macro->getUYDBU() - && hard_macro->getUXDBU() > other_hard_macro->getXDBU() - && hard_macro->getUYDBU() > other_hard_macro->getYDBU()) { + if (cluster_box.xMin() < hard_macro->getUXDBU() + && cluster_box.yMin() < hard_macro->getUYDBU() + && cluster_box.xMax() > hard_macro->getXDBU() + && cluster_box.yMax() > hard_macro->getYDBU()) { return true; } } @@ -6855,9 +6864,25 @@ bool BoundaryPusher::overlapsWithOtherHardMacro( return false; } -bool BoundaryPusher::overlapsWithIOBlockage(HardMacro* hard_macro, - Boundary boundary) +bool BoundaryPusher::overlapsWithIOBlockage( + const odb::Rect& cluster_box, + Boundary boundary) { + if (boundary_to_io_blockage_.find(boundary) + == boundary_to_io_blockage_.end()) { + return false; + } + + const odb::Rect box = boundary_to_io_blockage_.at(boundary); + + if (cluster_box.xMin() < box.xMax() + && cluster_box.yMin() < box.yMax() + && cluster_box.xMax() > box.xMin() + && cluster_box.yMax() > box.yMin()) { + return true; + } + + return false; } } // namespace mpl2 diff --git a/src/mpl2/src/hier_rtlmp.h b/src/mpl2/src/hier_rtlmp.h index ac8dd8d9896..bdb4d32fa9c 100644 --- a/src/mpl2/src/hier_rtlmp.h +++ b/src/mpl2/src/hier_rtlmp.h @@ -507,10 +507,11 @@ class BoundaryPusher bool vertical_move_allowed, bool horizontal_move_allowed); void moveHardMacro(HardMacro* hard_macro, Boundary boundary, int distance); - bool overlapsWithOtherHardMacro( - HardMacro* hard_macro, + bool overlapsWithHardMacro( + const odb::Rect& cluster_box, const std::vector& cluster_hard_macros); - bool overlapsWithIOBlockage(HardMacro* hard_macro, Boundary boundary); + bool overlapsWithIOBlockage(const odb::Rect& cluster_box, + Boundary boundary); Cluster* root_; odb::dbBlock* block_; From edf80ea6658ef597409564d6b604aee1c651ee6a Mon Sep 17 00:00:00 2001 From: Arthur Koucher Date: Tue, 23 Apr 2024 22:33:45 -0300 Subject: [PATCH 10/23] mpl2: renaming / format Signed-off-by: Arthur Koucher --- src/mpl2/src/hier_rtlmp.cpp | 47 +++++++++++++++++-------------------- src/mpl2/src/hier_rtlmp.h | 13 +++++----- 2 files changed, 27 insertions(+), 33 deletions(-) diff --git a/src/mpl2/src/hier_rtlmp.cpp b/src/mpl2/src/hier_rtlmp.cpp index 6f905dec09c..ac52d0a626b 100644 --- a/src/mpl2/src/hier_rtlmp.cpp +++ b/src/mpl2/src/hier_rtlmp.cpp @@ -377,9 +377,8 @@ void HierRTLMP::run() runHierarchicalMacroPlacementWithoutBusPlanning(root_cluster_); } - BoundaryPusher boundary_pusher( - root_cluster_, block_, boundary_to_io_blockage_); - boundary_pusher.pushMacrosToCoreBoundaries(); + Pusher pusher(root_cluster_, block_, boundary_to_io_blockage_); + pusher.pushMacrosToCoreBoundaries(); generateTemporaryStdCellsPlacement(root_cluster_); @@ -6650,12 +6649,11 @@ void HierRTLMP::setDebugShowBundledNets(bool show_bundled_nets) graphics_->setShowBundledNets(show_bundled_nets); } -//////// BoundaryPusher //////// +//////// Pusher //////// -BoundaryPusher::BoundaryPusher( - Cluster* root, - odb::dbBlock* block, - const std::map& boundary_to_io_blockage) +Pusher::Pusher(Cluster* root, + odb::dbBlock* block, + const std::map& boundary_to_io_blockage) : root_(root), block_(block) { core_ = block_->getCoreArea(); @@ -6664,7 +6662,7 @@ BoundaryPusher::BoundaryPusher( setIOBlockages(boundary_to_io_blockage); } -void BoundaryPusher::setIOBlockages( +void Pusher::setIOBlockages( const std::map& boundary_to_io_blockage) { for (const auto& [boundary, box] : boundary_to_io_blockage) { @@ -6676,8 +6674,8 @@ void BoundaryPusher::setIOBlockages( } } -void BoundaryPusher::fetchMacroClusters(Cluster* parent, - std::vector& macro_clusters) +void Pusher::fetchMacroClusters(Cluster* parent, + std::vector& macro_clusters) { for (Cluster* child : parent->getChildren()) { if (child->getClusterType() == HardMacroCluster) { @@ -6688,7 +6686,7 @@ void BoundaryPusher::fetchMacroClusters(Cluster* parent, } } -void BoundaryPusher::pushMacrosToCoreBoundaries() +void Pusher::pushMacrosToCoreBoundaries() { std::vector macro_clusters; fetchMacroClusters(root_, macro_clusters); @@ -6716,11 +6714,11 @@ void BoundaryPusher::pushMacrosToCoreBoundaries() std::map boundaries_distance = getDistanceToCloseBoundaries( macro_cluster, vertical_move_allowed, horizontal_move_allowed); - pushMacrosToCoreBoundaries(macro_cluster, boundaries_distance); + pushMacroClusterToCoreBoundaries(macro_cluster, boundaries_distance); } } -std::map BoundaryPusher::getDistanceToCloseBoundaries( +std::map Pusher::getDistanceToCloseBoundaries( Cluster* macro_cluster, bool vertical_move_allowed, bool horizontal_move_allowed) @@ -6772,7 +6770,7 @@ std::map BoundaryPusher::getDistanceToCloseBoundaries( return boundaries_distance; } -void BoundaryPusher::pushMacrosToCoreBoundaries( +void Pusher::pushMacroClusterToCoreBoundaries( Cluster* macro_cluster, const std::map& boundaries_distance) { @@ -6815,9 +6813,9 @@ void BoundaryPusher::pushMacrosToCoreBoundaries( } } -void BoundaryPusher::moveHardMacro(HardMacro* hard_macro, - Boundary boundary, - int distance) +void Pusher::moveHardMacro(HardMacro* hard_macro, + Boundary boundary, + int distance) { switch (boundary) { case NONE: @@ -6835,7 +6833,7 @@ void BoundaryPusher::moveHardMacro(HardMacro* hard_macro, } } -bool BoundaryPusher::overlapsWithHardMacro( +bool Pusher::overlapsWithHardMacro( const odb::Rect& cluster_box, const std::vector& cluster_hard_macros) { @@ -6864,9 +6862,8 @@ bool BoundaryPusher::overlapsWithHardMacro( return false; } -bool BoundaryPusher::overlapsWithIOBlockage( - const odb::Rect& cluster_box, - Boundary boundary) +bool Pusher::overlapsWithIOBlockage(const odb::Rect& cluster_box, + Boundary boundary) { if (boundary_to_io_blockage_.find(boundary) == boundary_to_io_blockage_.end()) { @@ -6875,10 +6872,8 @@ bool BoundaryPusher::overlapsWithIOBlockage( const odb::Rect box = boundary_to_io_blockage_.at(boundary); - if (cluster_box.xMin() < box.xMax() - && cluster_box.yMin() < box.yMax() - && cluster_box.xMax() > box.xMin() - && cluster_box.yMax() > box.yMin()) { + if (cluster_box.xMin() < box.xMax() && cluster_box.yMin() < box.yMax() + && cluster_box.xMax() > box.xMin() && cluster_box.yMax() > box.yMin()) { return true; } diff --git a/src/mpl2/src/hier_rtlmp.h b/src/mpl2/src/hier_rtlmp.h index bdb4d32fa9c..7394d764d6b 100644 --- a/src/mpl2/src/hier_rtlmp.h +++ b/src/mpl2/src/hier_rtlmp.h @@ -486,18 +486,18 @@ class HierRTLMP std::unique_ptr graphics_; }; -class BoundaryPusher +class Pusher { public: - BoundaryPusher(Cluster* root, - odb::dbBlock* block, - const std::map& boundary_to_io_blockage); + Pusher(Cluster* root, + odb::dbBlock* block, + const std::map& boundary_to_io_blockage); void pushMacrosToCoreBoundaries(); private: void setIOBlockages(const std::map& boundary_to_io_blockage); - void pushMacrosToCoreBoundaries( + void pushMacroClusterToCoreBoundaries( Cluster* macro_cluster, const std::map& boundaries_distance); void fetchMacroClusters(Cluster* parent, @@ -510,8 +510,7 @@ class BoundaryPusher bool overlapsWithHardMacro( const odb::Rect& cluster_box, const std::vector& cluster_hard_macros); - bool overlapsWithIOBlockage(const odb::Rect& cluster_box, - Boundary boundary); + bool overlapsWithIOBlockage(const odb::Rect& cluster_box, Boundary boundary); Cluster* root_; odb::dbBlock* block_; From ff4e5f3d238d4c11e150e6c0f9bbd9b928a48998 Mon Sep 17 00:00:00 2001 From: Arthur Koucher Date: Wed, 24 Apr 2024 10:08:06 -0300 Subject: [PATCH 11/23] mpl2: change order Signed-off-by: Arthur Koucher --- src/mpl2/src/hier_rtlmp.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/mpl2/src/hier_rtlmp.cpp b/src/mpl2/src/hier_rtlmp.cpp index ac52d0a626b..e0517c16922 100644 --- a/src/mpl2/src/hier_rtlmp.cpp +++ b/src/mpl2/src/hier_rtlmp.cpp @@ -6785,16 +6785,16 @@ void Pusher::pushMacroClusterToCoreBoundaries( continue; } + for (HardMacro* hard_macro : hard_macros) { + moveHardMacro(hard_macro, boundary, distance); + } + odb::Rect cluster_box( micronToDbu(macro_cluster->getX(), dbu_), micronToDbu(macro_cluster->getY(), dbu_), micronToDbu(macro_cluster->getX() + macro_cluster->getWidth(), dbu_), micronToDbu(macro_cluster->getY() + macro_cluster->getHeight(), dbu_)); - for (HardMacro* hard_macro : hard_macros) { - moveHardMacro(hard_macro, boundary, distance); - } - if (boundary == L || boundary == R) { cluster_box.moveDelta(distance, 0); } else if (boundary == T || boundary == B) { From 6fd8b1839f364f60843631a8a9795b3cc16b3b38 Mon Sep 17 00:00:00 2001 From: Arthur Koucher Date: Wed, 24 Apr 2024 10:11:39 -0300 Subject: [PATCH 12/23] mpl2: remove old function Signed-off-by: Arthur Koucher --- src/mpl2/src/hier_rtlmp.cpp | 408 ------------------------------------ src/mpl2/src/hier_rtlmp.h | 1 - 2 files changed, 409 deletions(-) diff --git a/src/mpl2/src/hier_rtlmp.cpp b/src/mpl2/src/hier_rtlmp.cpp index e0517c16922..4da85cb6214 100644 --- a/src/mpl2/src/hier_rtlmp.cpp +++ b/src/mpl2/src/hier_rtlmp.cpp @@ -5817,414 +5817,6 @@ std::vector HierRTLMP::computeBundledNets( return nets; } -// Align all the macros globally to reduce the waste of standard cell space -void HierRTLMP::alignHardMacroGlobal(Cluster* parent) -{ - debugPrint(logger_, - MPL, - "hierarchical_macro_placement", - 1, - "Aligning macros within the cluster {}", - parent->getName()); - - // get the floorplan information - const odb::Rect core_box = block_->getCoreArea(); - int core_lx = core_box.xMin(); - int core_ly = core_box.yMin(); - int core_ux = core_box.xMax(); - int core_uy = core_box.yMax(); - // if the current parent cluster is not the root cluster - if (parent->getParent() != nullptr) { - core_lx = micronToDbu(parent->getX(), dbu_); - core_ly = micronToDbu(parent->getY(), dbu_); - core_ux = micronToDbu(parent->getX() + parent->getWidth(), dbu_); - core_uy = micronToDbu(parent->getY() + parent->getHeight(), dbu_); - } - - std::vector hard_macros = parent->getHardMacros(); - int boundary_v_th = std::numeric_limits::max(); - int boundary_h_th = std::numeric_limits::max(); - for (auto& macro_inst : hard_macros) { - boundary_h_th = std::min( - boundary_h_th, static_cast(macro_inst->getRealWidthDBU() * 1.0)); - boundary_v_th = std::min( - boundary_v_th, static_cast(macro_inst->getHeightDBU() * 1.0)); - } - // const int notch_v_th = std::min(micronToDbu(notch_v_th_, dbu_), - // boundary_v_th); const int notch_h_th = std::min(micronToDbu(notch_h_th_, - // dbu_), boundary_h_th); - const int notch_v_th = boundary_v_th * 1.25; - const int notch_h_th = boundary_h_th * 1.25; - // const int notch_v_th = micronToDbu(notch_v_th_, dbu_) + boundary_v_th; - // const int notch_h_th = micronToDbu(notch_h_th_, dbu_) + boundary_h_th; - debugPrint(logger_, - MPL, - "hierarchical_macro_placement", - 1, - "boundary_h_th : {}, boundary_v_th : {}", - dbuToMicron(boundary_h_th, dbu_), - dbuToMicron(boundary_v_th, dbu_)); - debugPrint(logger_, - MPL, - "hierarchical_macro_placement", - 1, - "notch_h_th : {}, notch_v_th : {}", - dbuToMicron(notch_h_th, dbu_), - dbuToMicron(notch_v_th, dbu_)); - // define lamda function for check if the move is allowed - auto isValidMove = [&](size_t macro_id) { - // check if the macro can fit into the core area - const int macro_lx = hard_macros[macro_id]->getXDBU(); - const int macro_ly = hard_macros[macro_id]->getYDBU(); - const int macro_ux = hard_macros[macro_id]->getUXDBU(); - const int macro_uy = hard_macros[macro_id]->getUYDBU(); - if (macro_lx < core_lx || macro_ly < core_ly || macro_ux > core_ux - || macro_uy > core_uy) { - return false; - } - // check if there is some overlap with other macros - for (auto i = 0; i < hard_macros.size(); i++) { - if (i == macro_id) { - continue; - } - const int lx = hard_macros[i]->getXDBU(); - const int ly = hard_macros[i]->getYDBU(); - const int ux = hard_macros[i]->getUXDBU(); - const int uy = hard_macros[i]->getUYDBU(); - if (macro_lx >= ux || macro_ly >= uy || macro_ux <= lx - || macro_uy <= ly) { - continue; - } - return false; // there is some overlap with others - } - return true; // this move is valid - }; - // define lamda function for move a hard macro horizontally and vertically - auto moveHor = [&](size_t macro_id, int x) { - const int x_old = hard_macros[macro_id]->getXDBU(); - hard_macros[macro_id]->setXDBU(x); - if (isValidMove(macro_id) == false) { - hard_macros[macro_id]->setXDBU(x_old); - return false; - } - return true; - }; - - auto moveVer = [&](size_t macro_id, int y) { - const int y_old = hard_macros[macro_id]->getYDBU(); - hard_macros[macro_id]->setYDBU(y); - if (isValidMove(macro_id) == false) { - hard_macros[macro_id]->setYDBU(y_old); - return false; - } - return true; - }; - - // Align macros with the corresponding boundaries - // follow the order of left, top, right, bottom - // left boundary - for (auto j = 0; j < hard_macros.size(); j++) { - if (std::abs(hard_macros[j]->getXDBU() - core_lx) < boundary_h_th) { - moveHor(j, core_lx); - } - } - // top boundary - for (auto j = 0; j < hard_macros.size(); j++) { - if (std::abs(hard_macros[j]->getUYDBU() - core_uy) < boundary_v_th) { - moveVer(j, core_uy - hard_macros[j]->getHeightDBU()); - } - } - // right boundary - for (auto j = 0; j < hard_macros.size(); j++) { - if (std::abs(hard_macros[j]->getUXDBU() - core_ux) < boundary_h_th) { - moveHor(j, core_ux - hard_macros[j]->getWidthDBU()); - } - } - // bottom boundary - for (auto j = 0; j < hard_macros.size(); j++) { - if (std::abs(hard_macros[j]->getUYDBU() - core_ly) < boundary_v_th) { - moveVer(j, core_ly); - } - } - - // Comparator function to sort pairs according to second value - auto LessOrEqualX = [&](std::pair>& a, - std::pair>& b) { - if (a.second.first < b.second.first) { - return true; - } - if (a.second.first == b.second.first) { - return a.second.second < b.second.second; - } - return false; - }; - - auto LargeOrEqualX = [&](std::pair>& a, - std::pair>& b) { - if (a.second.first > b.second.first) { - return true; - } - if (a.second.first == b.second.first) { - return a.second.second > b.second.second; - } - return false; - }; - - auto LessOrEqualY = [&](std::pair>& a, - std::pair>& b) { - if (a.second.second < b.second.second) { - return true; - } - if (a.second.second == b.second.second) { - return a.second.first > b.second.first; - } - return false; - }; - - auto LargeOrEqualY = [&](std::pair>& a, - std::pair>& b) { - if (a.second.second > b.second.second) { - return true; - } - if (a.second.second == b.second.second) { - return a.second.first < b.second.first; - } - return false; - }; - - std::queue macro_queue; - std::vector macro_list; - std::vector flags(hard_macros.size(), false); - // align to the left - std::vector>> macro_lx_map; - for (size_t j = 0; j < hard_macros.size(); j++) { - macro_lx_map.emplace_back(j, - std::pair(hard_macros[j]->getXDBU(), - hard_macros[j]->getYDBU())); - } - std::sort(macro_lx_map.begin(), macro_lx_map.end(), LessOrEqualX); - for (auto& pair : macro_lx_map) { - if (pair.second.first <= core_lx + boundary_h_th) { - flags[pair.first] = true; // fix this - macro_queue.push(pair.first); // use this as an anchor - } else if (hard_macros[pair.first]->getUXDBU() >= core_ux - boundary_h_th) { - flags[pair.first] = true; // fix this - } else if (hard_macros[pair.first]->getUXDBU() <= core_ux / 2) { - macro_list.push_back(pair.first); - } - } - while (!macro_queue.empty()) { - const size_t macro_id = macro_queue.front(); - macro_queue.pop(); - const int lx = hard_macros[macro_id]->getXDBU(); - const int ly = hard_macros[macro_id]->getYDBU(); - const int ux = hard_macros[macro_id]->getUXDBU(); - const int uy = hard_macros[macro_id]->getUYDBU(); - for (auto j : macro_list) { - if (flags[j] == true) { - continue; - } - const int lx_b = hard_macros[j]->getXDBU(); - const int ly_b = hard_macros[j]->getYDBU(); - const int ux_b = hard_macros[j]->getUXDBU(); - const int uy_b = hard_macros[j]->getUYDBU(); - // check if adjacent - const bool y_flag = std::abs(ly - ly_b) < notch_v_th - || std::abs(ly - uy_b) < notch_v_th - || std::abs(uy - ly_b) < notch_v_th - || std::abs(uy - uy_b) < notch_v_th; - if (y_flag == false) { - continue; - } - // try to move horizontally - if (lx_b >= lx && lx_b <= lx + notch_h_th && lx_b < ux) { - flags[j] = moveHor(j, lx); - } else if (ux_b >= lx && ux_b <= ux && ux_b >= ux - notch_h_th) { - flags[j] = moveHor(j, ux - hard_macros[j]->getWidthDBU()); - } else if (lx_b >= ux && lx_b <= ux + notch_h_th) { - flags[j] = moveHor(j, ux); - } - // check if moved correctly - if (flags[j] == true) { - macro_queue.push(j); - } - } - } - - // align to the top - macro_list.clear(); - std::fill(flags.begin(), flags.end(), false); - std::vector>> macro_uy_map; - for (size_t j = 0; j < hard_macros.size(); j++) { - macro_uy_map.emplace_back(j, - std::pair(hard_macros[j]->getUXDBU(), - hard_macros[j]->getUYDBU())); - } - std::sort(macro_uy_map.begin(), macro_uy_map.end(), LargeOrEqualY); - for (auto& pair : macro_uy_map) { - if (hard_macros[pair.first]->getYDBU() <= core_ly + boundary_v_th) { - flags[pair.first] = true; // fix this - } else if (hard_macros[pair.first]->getUYDBU() >= core_uy - boundary_v_th) { - flags[pair.first] = true; // fix this - macro_queue.push(pair.first); // use this as an anchor - } else if (hard_macros[pair.first]->getYDBU() >= core_uy / 2) { - macro_list.push_back(pair.first); - } - } - while (!macro_queue.empty()) { - const size_t macro_id = macro_queue.front(); - macro_queue.pop(); - const int lx = hard_macros[macro_id]->getXDBU(); - const int ly = hard_macros[macro_id]->getYDBU(); - const int ux = hard_macros[macro_id]->getUXDBU(); - const int uy = hard_macros[macro_id]->getUYDBU(); - for (auto j : macro_list) { - if (flags[j] == true) { - continue; - } - const int lx_b = hard_macros[j]->getXDBU(); - const int ly_b = hard_macros[j]->getYDBU(); - const int ux_b = hard_macros[j]->getUXDBU(); - const int uy_b = hard_macros[j]->getUYDBU(); - // check if adjacent - const bool x_flag = std::abs(lx - lx_b) < notch_h_th - || std::abs(lx - ux_b) < notch_h_th - || std::abs(ux - lx_b) < notch_h_th - || std::abs(ux - ux_b) < notch_h_th; - if (x_flag == false) { - continue; - } - // try to move vertically - if (uy_b < uy && uy_b >= uy - notch_v_th && uy_b > ly) { - flags[j] = moveVer(j, uy - hard_macros[j]->getHeightDBU()); - } else if (ly_b >= ly && ly_b <= uy && ly_b <= ly + notch_v_th) { - flags[j] = moveVer(j, ly); - } else if (uy_b <= ly && uy_b >= ly - notch_v_th) { - flags[j] = moveVer(j, ly - hard_macros[j]->getHeightDBU()); - } - // check if moved correctly - if (flags[j] == true) { - macro_queue.push(j); - } - } - } - - // align to the right - macro_list.clear(); - std::fill(flags.begin(), flags.end(), false); - std::vector>> macro_ux_map; - for (size_t j = 0; j < hard_macros.size(); j++) { - macro_ux_map.emplace_back(j, - std::pair(hard_macros[j]->getUXDBU(), - hard_macros[j]->getUYDBU())); - } - std::sort(macro_ux_map.begin(), macro_ux_map.end(), LargeOrEqualX); - for (auto& pair : macro_ux_map) { - if (hard_macros[pair.first]->getXDBU() <= core_lx + boundary_h_th) { - flags[pair.first] = true; // fix this - } else if (hard_macros[pair.first]->getUXDBU() >= core_ux - boundary_h_th) { - flags[pair.first] = true; // fix this - macro_queue.push(pair.first); // use this as an anchor - } else if (hard_macros[pair.first]->getUXDBU() >= core_ux / 2) { - macro_list.push_back(pair.first); - } - } - while (!macro_queue.empty()) { - const size_t macro_id = macro_queue.front(); - macro_queue.pop(); - const int lx = hard_macros[macro_id]->getXDBU(); - const int ly = hard_macros[macro_id]->getYDBU(); - const int ux = hard_macros[macro_id]->getUXDBU(); - const int uy = hard_macros[macro_id]->getUYDBU(); - for (auto j : macro_list) { - if (flags[j] == true) { - continue; - } - const int lx_b = hard_macros[j]->getXDBU(); - const int ly_b = hard_macros[j]->getYDBU(); - const int ux_b = hard_macros[j]->getUXDBU(); - const int uy_b = hard_macros[j]->getUYDBU(); - // check if adjacent - const bool y_flag = std::abs(ly - ly_b) < notch_v_th - || std::abs(ly - uy_b) < notch_v_th - || std::abs(uy - ly_b) < notch_v_th - || std::abs(uy - uy_b) < notch_v_th; - if (y_flag == false) { - continue; - } - // try to move horizontally - if (ux_b < ux && ux_b >= ux - notch_h_th && ux_b > lx) { - flags[j] = moveHor(j, ux - hard_macros[j]->getWidthDBU()); - } else if (lx_b >= lx && lx_b <= ux && lx_b <= lx + notch_h_th) { - flags[j] = moveHor(j, lx); - } else if (ux_b <= lx && ux_b >= lx - notch_h_th) { - flags[j] = moveHor(j, lx - hard_macros[j]->getWidthDBU()); - } - // check if moved correctly - if (flags[j] == true) { - macro_queue.push(j); - } - } - } - // align to the bottom - macro_list.clear(); - std::fill(flags.begin(), flags.end(), false); - std::vector>> macro_ly_map; - for (size_t j = 0; j < hard_macros.size(); j++) { - macro_ly_map.emplace_back(j, - std::pair(hard_macros[j]->getXDBU(), - hard_macros[j]->getYDBU())); - } - std::sort(macro_ly_map.begin(), macro_ly_map.end(), LessOrEqualY); - for (auto& pair : macro_ly_map) { - if (hard_macros[pair.first]->getYDBU() <= core_ly + boundary_v_th) { - flags[pair.first] = true; // fix this - macro_queue.push(pair.first); // use this as an anchor - } else if (hard_macros[pair.first]->getUYDBU() >= core_uy - boundary_v_th) { - flags[pair.first] = true; // fix this - } else if (hard_macros[pair.first]->getUYDBU() <= core_uy / 2) { - macro_list.push_back(pair.first); - } - } - while (!macro_queue.empty()) { - const size_t macro_id = macro_queue.front(); - macro_queue.pop(); - const int lx = hard_macros[macro_id]->getXDBU(); - const int ly = hard_macros[macro_id]->getYDBU(); - const int ux = hard_macros[macro_id]->getUXDBU(); - const int uy = hard_macros[macro_id]->getUYDBU(); - for (auto j : macro_list) { - if (flags[j] == true) { - continue; - } - const int lx_b = hard_macros[j]->getXDBU(); - const int ly_b = hard_macros[j]->getYDBU(); - const int ux_b = hard_macros[j]->getUXDBU(); - const int uy_b = hard_macros[j]->getUYDBU(); - // check if adjacent - const bool x_flag = std::abs(lx - lx_b) < notch_h_th - || std::abs(lx - ux_b) < notch_h_th - || std::abs(ux - lx_b) < notch_h_th - || std::abs(uy - ux_b) < notch_h_th; - if (x_flag == false) { - continue; - } - // try to move vertically - if (ly_b >= ly && ly_b < ly + notch_v_th && ly_b < uy) { - flags[j] = moveVer(j, ly); - } else if (uy_b >= ly && uy_b <= uy && uy_b >= uy - notch_v_th) { - flags[j] = moveVer(j, uy - hard_macros[j]->getHeightDBU()); - } else if (ly_b >= uy && ly_b <= uy + notch_v_th) { - flags[j] = moveVer(j, uy); - } - // check if moved correctly - if (flags[j] == true) { - macro_queue.push(j); - } - } - } -} - // Update the location based on the parent's perspective. void HierRTLMP::updateChildrenShapesAndLocations( Cluster* parent, diff --git a/src/mpl2/src/hier_rtlmp.h b/src/mpl2/src/hier_rtlmp.h index 7394d764d6b..7a68d4aa5a8 100644 --- a/src/mpl2/src/hier_rtlmp.h +++ b/src/mpl2/src/hier_rtlmp.h @@ -270,7 +270,6 @@ class HierRTLMP float offset_x, float offset_y); void mergeNets(std::vector& nets); - void alignHardMacroGlobal(Cluster* parent); // Hierarchical Macro Placement 2nd stage: Macro Placement void placeMacros(Cluster* cluster); From 3d3cbfdfccbcb075d4aa83182b4db304e10512a8 Mon Sep 17 00:00:00 2001 From: Arthur Koucher Date: Wed, 24 Apr 2024 10:16:31 -0300 Subject: [PATCH 13/23] mpl2: const Signed-off-by: Arthur Koucher --- src/mpl2/src/hier_rtlmp.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/mpl2/src/hier_rtlmp.cpp b/src/mpl2/src/hier_rtlmp.cpp index 4da85cb6214..88c8c24f640 100644 --- a/src/mpl2/src/hier_rtlmp.cpp +++ b/src/mpl2/src/hier_rtlmp.cpp @@ -3151,7 +3151,7 @@ void HierRTLMP::setIOClustersBlockages() // Note that the range can be larger than the respective core dimension. // As SA only sees what is inside its current outline, this is not a problem. if (io_spans[L].second > io_spans[L].first) { - Rect left_io_blockage(root.xMin(), + const Rect left_io_blockage(root.xMin(), io_spans[L].first, root.xMin() + depth, io_spans[L].second); @@ -3161,7 +3161,7 @@ void HierRTLMP::setIOClustersBlockages() } if (io_spans[T].second > io_spans[T].first) { - Rect top_io_blockage(io_spans[T].first, + const Rect top_io_blockage(io_spans[T].first, root.yMax() - depth, io_spans[T].second, root.yMax()); @@ -3171,7 +3171,7 @@ void HierRTLMP::setIOClustersBlockages() } if (io_spans[R].second > io_spans[R].first) { - Rect right_io_blockage(root.xMax() - depth, + const Rect right_io_blockage(root.xMax() - depth, io_spans[R].first, root.xMax(), io_spans[R].second); @@ -3181,7 +3181,7 @@ void HierRTLMP::setIOClustersBlockages() } if (io_spans[B].second > io_spans[B].first) { - Rect bottom_io_blockage(io_spans[B].first, + const Rect bottom_io_blockage(io_spans[B].first, root.yMin(), io_spans[B].second, root.yMin() + depth); From feed1f87499e910b660d4ff79d400739d8040d94 Mon Sep 17 00:00:00 2001 From: Arthur Koucher Date: Wed, 24 Apr 2024 10:53:00 -0300 Subject: [PATCH 14/23] mpl2: format Signed-off-by: Arthur Koucher --- src/mpl2/src/hier_rtlmp.cpp | 24 ++++++++++++------------ src/mpl2/src/object.cpp | 3 +-- 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/src/mpl2/src/hier_rtlmp.cpp b/src/mpl2/src/hier_rtlmp.cpp index 88c8c24f640..4b8ecc87c96 100644 --- a/src/mpl2/src/hier_rtlmp.cpp +++ b/src/mpl2/src/hier_rtlmp.cpp @@ -3152,9 +3152,9 @@ void HierRTLMP::setIOClustersBlockages() // As SA only sees what is inside its current outline, this is not a problem. if (io_spans[L].second > io_spans[L].first) { const Rect left_io_blockage(root.xMin(), - io_spans[L].first, - root.xMin() + depth, - io_spans[L].second); + io_spans[L].first, + root.xMin() + depth, + io_spans[L].second); boundary_to_io_blockage_[L] = left_io_blockage; macro_blockages_.push_back(left_io_blockage); @@ -3162,9 +3162,9 @@ void HierRTLMP::setIOClustersBlockages() if (io_spans[T].second > io_spans[T].first) { const Rect top_io_blockage(io_spans[T].first, - root.yMax() - depth, - io_spans[T].second, - root.yMax()); + root.yMax() - depth, + io_spans[T].second, + root.yMax()); boundary_to_io_blockage_[T] = top_io_blockage; macro_blockages_.push_back(top_io_blockage); @@ -3172,9 +3172,9 @@ void HierRTLMP::setIOClustersBlockages() if (io_spans[R].second > io_spans[R].first) { const Rect right_io_blockage(root.xMax() - depth, - io_spans[R].first, - root.xMax(), - io_spans[R].second); + io_spans[R].first, + root.xMax(), + io_spans[R].second); boundary_to_io_blockage_[R] = right_io_blockage; macro_blockages_.push_back(right_io_blockage); @@ -3182,9 +3182,9 @@ void HierRTLMP::setIOClustersBlockages() if (io_spans[B].second > io_spans[B].first) { const Rect bottom_io_blockage(io_spans[B].first, - root.yMin(), - io_spans[B].second, - root.yMin() + depth); + root.yMin(), + io_spans[B].second, + root.yMin() + depth); boundary_to_io_blockage_[B] = bottom_io_blockage; macro_blockages_.push_back(bottom_io_blockage); diff --git a/src/mpl2/src/object.cpp b/src/mpl2/src/object.cpp index 06310713379..975535d0513 100644 --- a/src/mpl2/src/object.cpp +++ b/src/mpl2/src/object.cpp @@ -664,8 +664,7 @@ const std::pair Cluster::getPinAccess(int cluster_id) return pin_access_map_[cluster_id]; } -const std::map> Cluster::getPinAccessMap() - const +const std::map> Cluster::getPinAccessMap() const { return pin_access_map_; } From b57925f0a0ba13d0bbd4fc53a6ebe46211f74009 Mon Sep 17 00:00:00 2001 From: Arthur Koucher Date: Wed, 24 Apr 2024 14:20:48 -0300 Subject: [PATCH 15/23] mpl2: 1) avoid pushing when design has only macros 2) const parameters 3) populate HardMacros* vector during macro cluster fetching 4) use distance from cluster --> core rather than individual HardMacros Signed-off-by: Arthur Koucher --- src/mpl2/src/hier_rtlmp.cpp | 70 ++++++++++++++++++++----------------- 1 file changed, 37 insertions(+), 33 deletions(-) diff --git a/src/mpl2/src/hier_rtlmp.cpp b/src/mpl2/src/hier_rtlmp.cpp index 4b8ecc87c96..54d1a0838e4 100644 --- a/src/mpl2/src/hier_rtlmp.cpp +++ b/src/mpl2/src/hier_rtlmp.cpp @@ -6272,6 +6272,11 @@ void Pusher::fetchMacroClusters(Cluster* parent, for (Cluster* child : parent->getChildren()) { if (child->getClusterType() == HardMacroCluster) { macro_clusters.push_back(child); + + for (HardMacro* hard_macro : child->getHardMacros()) { + hard_macros_.push_back(hard_macro); + } + } else if (child->getClusterType() == MixedCluster) { fetchMacroClusters(child, macro_clusters); } @@ -6280,6 +6285,10 @@ void Pusher::fetchMacroClusters(Cluster* parent, void Pusher::pushMacrosToCoreBoundaries() { + if (root_->getClusterType() == HardMacroCluster) { + return; + } + std::vector macro_clusters; fetchMacroClusters(root_, macro_clusters); @@ -6312,50 +6321,45 @@ void Pusher::pushMacrosToCoreBoundaries() std::map Pusher::getDistanceToCloseBoundaries( Cluster* macro_cluster, - bool vertical_move_allowed, - bool horizontal_move_allowed) + const bool vertical_move_allowed, + const bool horizontal_move_allowed) { std::map boundaries_distance; + const odb::Rect cluster_box( + micronToDbu(macro_cluster->getX(), dbu_), + micronToDbu(macro_cluster->getY(), dbu_), + micronToDbu(macro_cluster->getX() + macro_cluster->getWidth(), dbu_), + micronToDbu(macro_cluster->getY() + macro_cluster->getHeight(), dbu_)); + std::vector hard_macros = macro_cluster->getHardMacros(); - int min_dx_to_core = std::numeric_limits::max(); - int min_dy_to_core = std::numeric_limits::max(); + // We only group macros of the same size, so here we + // can use any HardMacro from the cluster. + const int hard_macro_width = hard_macros.front()->getWidthDBU(); + const int hard_macro_height = hard_macros.front()->getHeightDBU(); - for (HardMacro* hard_macro : hard_macros) { - hard_macros_.push_back(hard_macro); + if (horizontal_move_allowed) { + const int distance_to_left = std::abs(cluster_box.xMin() - core_.xMin()); + if (distance_to_left < hard_macro_width) { + boundaries_distance[L] = -distance_to_left; + } - min_dx_to_core = std::min(min_dy_to_core, hard_macro->getWidthDBU()); - min_dy_to_core = std::min(min_dy_to_core, hard_macro->getHeightDBU()); + const int distance_to_right = std::abs(cluster_box.xMax() - core_.xMax()); + if (distance_to_right < hard_macro_width) { + boundaries_distance[R] = distance_to_right; + } } - for (HardMacro* hard_macro : hard_macros) { - if (horizontal_move_allowed) { - const int distance_to_left - = std::abs(hard_macro->getXDBU() - core_.xMin()); - if (distance_to_left < min_dx_to_core) { - boundaries_distance[L] = -distance_to_left; - } - - const int distance_to_right - = std::abs(hard_macro->getUXDBU() - core_.xMax()); - if (distance_to_right < min_dx_to_core) { - boundaries_distance[R] = distance_to_right; - } + if (vertical_move_allowed) { + const int distance_to_top = std::abs(cluster_box.yMax() - core_.yMax()); + if (distance_to_top < hard_macro_height) { + boundaries_distance[T] = distance_to_top; } - if (vertical_move_allowed) { - const int distance_to_top - = std::abs(hard_macro->getUYDBU() - core_.yMax()); - if (distance_to_top < min_dy_to_core) { - boundaries_distance[T] = distance_to_top; - } - - const int distance_to_bottom - = std::abs(hard_macro->getUYDBU() - core_.yMin()); - if (distance_to_bottom < min_dy_to_core) { - boundaries_distance[B] = -distance_to_bottom; - } + const int distance_to_bottom = std::abs(cluster_box.yMin() - core_.yMin()); + if (distance_to_bottom < hard_macro_height) { + boundaries_distance[B] = -distance_to_bottom; } } From cef81e1db2d4c4dca4c9fd90a2f5fff225a68062 Mon Sep 17 00:00:00 2001 From: Arthur Koucher Date: Thu, 25 Apr 2024 11:08:10 -0300 Subject: [PATCH 16/23] mpl2: 1) add new debug group 2) compute distance to close boundaries based on cluster box 3) check overlap based on cluster box Signed-off-by: Arthur Koucher --- src/mpl2/doc/debugMessages.md | 17 ++-- src/mpl2/src/hier_rtlmp.cpp | 149 ++++++++++++++++++++++------------ src/mpl2/src/hier_rtlmp.h | 13 +-- 3 files changed, 115 insertions(+), 64 deletions(-) diff --git a/src/mpl2/doc/debugMessages.md b/src/mpl2/doc/debugMessages.md index cc1f7dc2a6a..235f5ec8d0a 100644 --- a/src/mpl2/doc/debugMessages.md +++ b/src/mpl2/doc/debugMessages.md @@ -1,7 +1,8 @@ # MPL2 Debug Messages MPL2 debug messages are divided in: -- 4 groups according to HierRTLMP flow stages. +- 5 groups according to HierRTLMP flow stages. +- 1 group for a post-process stage responsible for pushing the macros to the boundaries if possible. - 1 group for the special case in which bus planning is used. ## Groups @@ -34,11 +35,17 @@ MPL2 debug messages are divided in: * Clusters' connections; * Simulated annealing results for both SoftMacro and HardMacro. +### Orientation Improvement +- Group Name: `flipping` +- Levels: +1. Print the wire length before and after flipping + +### Boundary Push +- Group Name: `boundary_push` +- Levels: +1. Print name of the macro cluster currently being pushed, its distance to the close boundaries and a message if the move was not possible due to overlap. + ### Bus Planning Special case for bus planning with a single level. - Group Name: `bus_planning` -### Fine Shaping -- Group Name: `flipping` -- Levels: -1. Print the wire length before and after flipping diff --git a/src/mpl2/src/hier_rtlmp.cpp b/src/mpl2/src/hier_rtlmp.cpp index 54d1a0838e4..55ad46ef0e1 100644 --- a/src/mpl2/src/hier_rtlmp.cpp +++ b/src/mpl2/src/hier_rtlmp.cpp @@ -377,7 +377,7 @@ void HierRTLMP::run() runHierarchicalMacroPlacementWithoutBusPlanning(root_cluster_); } - Pusher pusher(root_cluster_, block_, boundary_to_io_blockage_); + Pusher pusher(logger_, root_cluster_, block_, boundary_to_io_blockage_); pusher.pushMacrosToCoreBoundaries(); generateTemporaryStdCellsPlacement(root_cluster_); @@ -6243,10 +6243,11 @@ void HierRTLMP::setDebugShowBundledNets(bool show_bundled_nets) //////// Pusher //////// -Pusher::Pusher(Cluster* root, +Pusher::Pusher(utl::Logger* logger, + Cluster* root, odb::dbBlock* block, const std::map& boundary_to_io_blockage) - : root_(root), block_(block) + : logger_(logger), root_(root), block_(block) { core_ = block_->getCoreArea(); dbu_ = block_->getTech()->getDbUnitsPerMicron(); @@ -6293,36 +6294,33 @@ void Pusher::pushMacrosToCoreBoundaries() fetchMacroClusters(root_, macro_clusters); for (Cluster* macro_cluster : macro_clusters) { - // We don't push macros to the boundaries if that will destroy - // the shape of an array of macros. - bool horizontal_move_allowed = true; - bool vertical_move_allowed = true; + debugPrint(logger_, + MPL, + "boundary_push", + 1, + "Macro Cluster {}", + macro_cluster->getName()); - const int width = micronToDbu(macro_cluster->getWidth(), dbu_); - if (width > (core_.dx() / 2)) { - horizontal_move_allowed = false; - } + std::map boundaries_distance + = getDistanceToCloseBoundaries(macro_cluster); - const int height = micronToDbu(macro_cluster->getHeight(), dbu_); - if (height > (core_.dy() / 2)) { - vertical_move_allowed = false; - } + if (logger_->debugCheck(MPL, "boundary_push", 1)) { + logger_->report("Distance to Close Boundaries:"); - if (!horizontal_move_allowed && !vertical_move_allowed) { - continue; + for (auto& [boundary, distance] : boundaries_distance) { + logger_->report("{} {}", toString(boundary), distance); + } } - std::map boundaries_distance = getDistanceToCloseBoundaries( - macro_cluster, vertical_move_allowed, horizontal_move_allowed); - pushMacroClusterToCoreBoundaries(macro_cluster, boundaries_distance); } } +// We only group macros of the same size, so here we can use any HardMacro +// from the cluster to set the minimum distance from the respective +// boundary to trigger a push. std::map Pusher::getDistanceToCloseBoundaries( - Cluster* macro_cluster, - const bool vertical_move_allowed, - const bool horizontal_move_allowed) + Cluster* macro_cluster) { std::map boundaries_distance; @@ -6332,35 +6330,42 @@ std::map Pusher::getDistanceToCloseBoundaries( micronToDbu(macro_cluster->getX() + macro_cluster->getWidth(), dbu_), micronToDbu(macro_cluster->getY() + macro_cluster->getHeight(), dbu_)); - std::vector hard_macros = macro_cluster->getHardMacros(); + HardMacro* hard_macro = macro_cluster->getHardMacros().front(); - // We only group macros of the same size, so here we - // can use any HardMacro from the cluster. - const int hard_macro_width = hard_macros.front()->getWidthDBU(); - const int hard_macro_height = hard_macros.front()->getHeightDBU(); + Boundary hor_boundary_to_push; + const int distance_to_left = std::abs(cluster_box.xMin() - core_.xMin()); + const int distance_to_right = std::abs(cluster_box.xMax() - core_.xMax()); + int smaller_hor_distance = 0; - if (horizontal_move_allowed) { - const int distance_to_left = std::abs(cluster_box.xMin() - core_.xMin()); - if (distance_to_left < hard_macro_width) { - boundaries_distance[L] = -distance_to_left; - } + if (distance_to_left < distance_to_right) { + hor_boundary_to_push = L; + smaller_hor_distance = distance_to_left; + } else { + hor_boundary_to_push = R; + smaller_hor_distance = distance_to_right; + } - const int distance_to_right = std::abs(cluster_box.xMax() - core_.xMax()); - if (distance_to_right < hard_macro_width) { - boundaries_distance[R] = distance_to_right; - } + const int hard_macro_width = hard_macro->getWidthDBU(); + if (smaller_hor_distance < hard_macro_width) { + boundaries_distance[hor_boundary_to_push] = smaller_hor_distance; } - if (vertical_move_allowed) { - const int distance_to_top = std::abs(cluster_box.yMax() - core_.yMax()); - if (distance_to_top < hard_macro_height) { - boundaries_distance[T] = distance_to_top; - } + Boundary ver_boundary_to_push; + const int distance_to_top = std::abs(cluster_box.yMax() - core_.yMax()); + const int distance_to_bottom = std::abs(cluster_box.yMin() - core_.yMin()); + int smaller_ver_distance = 0; - const int distance_to_bottom = std::abs(cluster_box.yMin() - core_.yMin()); - if (distance_to_bottom < hard_macro_height) { - boundaries_distance[B] = -distance_to_bottom; - } + if (distance_to_bottom < distance_to_top) { + ver_boundary_to_push = B; + smaller_ver_distance = distance_to_bottom; + } else { + ver_boundary_to_push = T; + smaller_ver_distance = distance_to_top; + } + + const int hard_macro_height = hard_macro->getHeightDBU(); + if (smaller_ver_distance < hard_macro_height) { + boundaries_distance[ver_boundary_to_push] = smaller_ver_distance; } return boundaries_distance; @@ -6391,16 +6396,20 @@ void Pusher::pushMacroClusterToCoreBoundaries( micronToDbu(macro_cluster->getX() + macro_cluster->getWidth(), dbu_), micronToDbu(macro_cluster->getY() + macro_cluster->getHeight(), dbu_)); - if (boundary == L || boundary == R) { - cluster_box.moveDelta(distance, 0); - } else if (boundary == T || boundary == B) { - cluster_box.moveDelta(0, distance); - } + moveMacroClusterBox(cluster_box, boundary, distance); // Check based on the shape of the macro cluster to avoid iterating each // of its HardMacros. if (overlapsWithHardMacro(cluster_box, hard_macros) || overlapsWithIOBlockage(cluster_box, boundary)) { + debugPrint(logger_, + MPL, + "boundary_push", + 1, + "Overlap found when moving {} to {}. Push reverted.", + macro_cluster->getName(), + toString(boundary)); + // Move back to original position. for (HardMacro* hard_macro : hard_macros) { moveHardMacro(hard_macro, boundary, (-distance)); @@ -6409,6 +6418,32 @@ void Pusher::pushMacroClusterToCoreBoundaries( } } +void Pusher::moveMacroClusterBox(odb::Rect& cluster_box, + Boundary boundary, + const int distance) +{ + switch (boundary) { + case NONE: + return; + case L: { + cluster_box.moveDelta(-distance, 0); + break; + } + case R: { + cluster_box.moveDelta(distance, 0); + break; + } + case T: { + cluster_box.moveDelta(0, distance); + break; + } + case B: { + cluster_box.moveDelta(0, -distance); + break; + } + } +} + void Pusher::moveHardMacro(HardMacro* hard_macro, Boundary boundary, int distance) @@ -6416,16 +6451,22 @@ void Pusher::moveHardMacro(HardMacro* hard_macro, switch (boundary) { case NONE: return; - case L: + case L: { + hard_macro->setXDBU(hard_macro->getXDBU() - distance); + break; + } case R: { hard_macro->setXDBU(hard_macro->getXDBU() + distance); break; } - case T: - case B: { + case T: { hard_macro->setYDBU(hard_macro->getYDBU() + distance); break; } + case B: { + hard_macro->setYDBU(hard_macro->getYDBU() - distance); + break; + } } } diff --git a/src/mpl2/src/hier_rtlmp.h b/src/mpl2/src/hier_rtlmp.h index 7a68d4aa5a8..b215ba6abad 100644 --- a/src/mpl2/src/hier_rtlmp.h +++ b/src/mpl2/src/hier_rtlmp.h @@ -488,7 +488,8 @@ class HierRTLMP class Pusher { public: - Pusher(Cluster* root, + Pusher(utl::Logger* logger, + Cluster* root, odb::dbBlock* block, const std::map& boundary_to_io_blockage); @@ -501,16 +502,18 @@ class Pusher const std::map& boundaries_distance); void fetchMacroClusters(Cluster* parent, std::vector& macro_clusters); - std::map getDistanceToCloseBoundaries( - Cluster* macro_cluster, - bool vertical_move_allowed, - bool horizontal_move_allowed); + std::map getDistanceToCloseBoundaries(Cluster* macro_cluster); void moveHardMacro(HardMacro* hard_macro, Boundary boundary, int distance); + void moveMacroClusterBox(odb::Rect& cluster_box, + Boundary boundary, + const int distance); bool overlapsWithHardMacro( const odb::Rect& cluster_box, const std::vector& cluster_hard_macros); bool overlapsWithIOBlockage(const odb::Rect& cluster_box, Boundary boundary); + utl::Logger* logger_; + Cluster* root_; odb::dbBlock* block_; odb::Rect core_; From d1dd49a9642a23ca03064fbcdd9255e7caf87617 Mon Sep 17 00:00:00 2001 From: Arthur Koucher Date: Fri, 26 Apr 2024 15:33:51 -0300 Subject: [PATCH 17/23] mpl2: include check for mock-array's corner case in boundary push Signed-off-by: Arthur Koucher --- src/mpl2/src/hier_rtlmp.cpp | 34 ++++++++++++++++++++++++++++++++++ src/mpl2/src/hier_rtlmp.h | 1 + 2 files changed, 35 insertions(+) diff --git a/src/mpl2/src/hier_rtlmp.cpp b/src/mpl2/src/hier_rtlmp.cpp index 55ad46ef0e1..e240525bad8 100644 --- a/src/mpl2/src/hier_rtlmp.cpp +++ b/src/mpl2/src/hier_rtlmp.cpp @@ -6286,10 +6286,15 @@ void Pusher::fetchMacroClusters(Cluster* parent, void Pusher::pushMacrosToCoreBoundaries() { + // Case in which the design has nothing but macros. if (root_->getClusterType() == HardMacroCluster) { return; } + if (designHasSingleCentralizedMacroArray()) { + return; + } + std::vector macro_clusters; fetchMacroClusters(root_, macro_clusters); @@ -6316,6 +6321,35 @@ void Pusher::pushMacrosToCoreBoundaries() } } +bool Pusher::designHasSingleCentralizedMacroArray() +{ + int macro_cluster_count = 0; + + for (Cluster* child : root_->getChildren()) { + switch (child->getClusterType()) { + case MixedCluster: + return false; + case HardMacroCluster: + ++macro_cluster_count; + break; + case StdCellCluster: { + // Note: the Cluster area comes from the metrics (std cell area), + // while the SoftMacro area is the "tiny std cell cluster" area + // which is 0. + if (child->getSoftMacro()->getArea() != 0) { + return false; + } + } + } + + if (macro_cluster_count > 1) { + return false; + } + } + + return true; +} + // We only group macros of the same size, so here we can use any HardMacro // from the cluster to set the minimum distance from the respective // boundary to trigger a push. diff --git a/src/mpl2/src/hier_rtlmp.h b/src/mpl2/src/hier_rtlmp.h index b215ba6abad..73525952beb 100644 --- a/src/mpl2/src/hier_rtlmp.h +++ b/src/mpl2/src/hier_rtlmp.h @@ -497,6 +497,7 @@ class Pusher private: void setIOBlockages(const std::map& boundary_to_io_blockage); + bool designHasSingleCentralizedMacroArray(); void pushMacroClusterToCoreBoundaries( Cluster* macro_cluster, const std::map& boundaries_distance); From 8c8a6d4cb692a0ce09c4c1f27d46ad381630d03f Mon Sep 17 00:00:00 2001 From: Arthur Koucher Date: Fri, 26 Apr 2024 15:37:58 -0300 Subject: [PATCH 18/23] mpl2: clang-tidy Signed-off-by: Arthur Koucher --- src/mpl2/src/hier_rtlmp.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mpl2/src/hier_rtlmp.h b/src/mpl2/src/hier_rtlmp.h index 73525952beb..da41fd221d8 100644 --- a/src/mpl2/src/hier_rtlmp.h +++ b/src/mpl2/src/hier_rtlmp.h @@ -507,7 +507,7 @@ class Pusher void moveHardMacro(HardMacro* hard_macro, Boundary boundary, int distance); void moveMacroClusterBox(odb::Rect& cluster_box, Boundary boundary, - const int distance); + int distance); bool overlapsWithHardMacro( const odb::Rect& cluster_box, const std::vector& cluster_hard_macros); From 42a201c0ad982a07ba853ad904339b3bd13420cf Mon Sep 17 00:00:00 2001 From: Arthur Koucher Date: Fri, 26 Apr 2024 15:48:22 -0300 Subject: [PATCH 19/23] mpl2: improve comment Signed-off-by: Arthur Koucher --- src/mpl2/src/hier_rtlmp.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/mpl2/src/hier_rtlmp.cpp b/src/mpl2/src/hier_rtlmp.cpp index e240525bad8..f3a13bc001c 100644 --- a/src/mpl2/src/hier_rtlmp.cpp +++ b/src/mpl2/src/hier_rtlmp.cpp @@ -6333,9 +6333,10 @@ bool Pusher::designHasSingleCentralizedMacroArray() ++macro_cluster_count; break; case StdCellCluster: { - // Note: the Cluster area comes from the metrics (std cell area), - // while the SoftMacro area is the "tiny std cell cluster" area - // which is 0. + // Note: to check whether or not a std cell cluster is "tiny" + // we use the area of its SoftMacro abstraction, because the + // Cluster::getArea() will give us the actual std cell area + // of the instances from that cluster. if (child->getSoftMacro()->getArea() != 0) { return false; } From a768aa73f1f78db6375ac04645dd7d8168f8bdfb Mon Sep 17 00:00:00 2001 From: Arthur Koucher Date: Fri, 26 Apr 2024 15:51:51 -0300 Subject: [PATCH 20/23] mpl2: missing consts Signed-off-by: Arthur Koucher --- src/mpl2/src/hier_rtlmp.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/mpl2/src/hier_rtlmp.cpp b/src/mpl2/src/hier_rtlmp.cpp index f3a13bc001c..f786bccef67 100644 --- a/src/mpl2/src/hier_rtlmp.cpp +++ b/src/mpl2/src/hier_rtlmp.cpp @@ -6454,7 +6454,7 @@ void Pusher::pushMacroClusterToCoreBoundaries( } void Pusher::moveMacroClusterBox(odb::Rect& cluster_box, - Boundary boundary, + const Boundary boundary, const int distance) { switch (boundary) { @@ -6480,8 +6480,8 @@ void Pusher::moveMacroClusterBox(odb::Rect& cluster_box, } void Pusher::moveHardMacro(HardMacro* hard_macro, - Boundary boundary, - int distance) + const Boundary boundary, + const int distance) { switch (boundary) { case NONE: @@ -6535,7 +6535,7 @@ bool Pusher::overlapsWithHardMacro( } bool Pusher::overlapsWithIOBlockage(const odb::Rect& cluster_box, - Boundary boundary) + const Boundary boundary) { if (boundary_to_io_blockage_.find(boundary) == boundary_to_io_blockage_.end()) { From 54d8553859f681473deb5598d2203314e1ca5e86 Mon Sep 17 00:00:00 2001 From: Arthur Koucher Date: Mon, 29 Apr 2024 15:41:05 -0300 Subject: [PATCH 21/23] mpl2: fix comment Signed-off-by: Arthur Koucher --- src/mpl2/src/hier_rtlmp.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/mpl2/src/hier_rtlmp.cpp b/src/mpl2/src/hier_rtlmp.cpp index f786bccef67..f47e4a86c00 100644 --- a/src/mpl2/src/hier_rtlmp.cpp +++ b/src/mpl2/src/hier_rtlmp.cpp @@ -346,7 +346,7 @@ void HierRTLMP::setDefaultThresholds() } // Top Level Function -// The flow of our MacroPlacer is divided into 5 stages. +// The flow of our MacroPlacer is divided into 6 stages. // 1) Multilevel Autoclustering: // Transform logical hierarchy into physical hierarchy. // 2) Coarse Shaping -> Bottom - Up: @@ -356,10 +356,13 @@ void HierRTLMP::setDefaultThresholds() // outline and location of its parent cluster. // *This is executed within hierarchical placement method. // 4) Hierarchical Macro Placement -> Top - Down -// a) Placement of Cluster (one level at a time); +// a) Placement of Clusters (one level at a time); // b) Placement of Macros (one macro cluster at a time). -// 5) Orientation Improvement -// Attempts macro flipping to improve WR +// 5) Boundary Pushing +// Push macro clusters to the boundaries of the design if they don't +// overlap with either bundled IOs' blockages or other macros. +// 6) Orientation Improvement +// Attempts macro flipping to improve WR. void HierRTLMP::run() { initMacroPlacer(); From b7f7e3ea8b30bad68968a73f0ddd2d9d88aebe16 Mon Sep 17 00:00:00 2001 From: Arthur Koucher Date: Mon, 29 Apr 2024 18:53:44 -0300 Subject: [PATCH 22/23] mpl2: decrease signature threshold] Signed-off-by: Arthur Koucher --- src/mpl2/src/hier_rtlmp.h | 2 +- src/mpl2/src/mpl.tcl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mpl2/src/hier_rtlmp.h b/src/mpl2/src/hier_rtlmp.h index da41fd221d8..a7eb266f585 100644 --- a/src/mpl2/src/hier_rtlmp.h +++ b/src/mpl2/src/hier_rtlmp.h @@ -445,7 +445,7 @@ class HierRTLMP // minimum number of connections between two clusters // for them to be identified as connected - int signature_net_threshold_ = 20; + int signature_net_threshold_ = 0; int large_net_threshold_ = 100; // ignore global nets when clustering const int bus_net_threshold_ = 32; // only for bus planning float congestion_weight_ = 0.5; // for balance timing and congestion diff --git a/src/mpl2/src/mpl.tcl b/src/mpl2/src/mpl.tcl index f48dee0054d..d5e57d018ce 100644 --- a/src/mpl2/src/mpl.tcl +++ b/src/mpl2/src/mpl.tcl @@ -94,7 +94,7 @@ proc rtl_macro_placer { args } { set coarsening_ratio 10.0 set num_bundled_ios 3 set large_net_threshold 50 - set signature_net_threshold 50 + set signature_net_threshold 20 set halo_width 0.0 set halo_height 0.0 set fence_lx 0.0 From e662868bafc730e9e0077c701645893c0898c6bc Mon Sep 17 00:00:00 2001 From: Arthur Koucher Date: Thu, 2 May 2024 13:46:12 -0300 Subject: [PATCH 23/23] Revert "mpl2: decrease signature threshold]" This reverts commit b7f7e3ea8b30bad68968a73f0ddd2d9d88aebe16. Signed-off-by: Arthur Koucher --- src/mpl2/src/hier_rtlmp.h | 2 +- src/mpl2/src/mpl.tcl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mpl2/src/hier_rtlmp.h b/src/mpl2/src/hier_rtlmp.h index 8df9590b0ec..2dee5665b61 100644 --- a/src/mpl2/src/hier_rtlmp.h +++ b/src/mpl2/src/hier_rtlmp.h @@ -445,7 +445,7 @@ class HierRTLMP // minimum number of connections between two clusters // for them to be identified as connected - int signature_net_threshold_ = 0; + int signature_net_threshold_ = 20; int large_net_threshold_ = 100; // ignore global nets when clustering const int bus_net_threshold_ = 32; // only for bus planning float congestion_weight_ = 0.5; // for balance timing and congestion diff --git a/src/mpl2/src/mpl.tcl b/src/mpl2/src/mpl.tcl index d5e57d018ce..f48dee0054d 100644 --- a/src/mpl2/src/mpl.tcl +++ b/src/mpl2/src/mpl.tcl @@ -94,7 +94,7 @@ proc rtl_macro_placer { args } { set coarsening_ratio 10.0 set num_bundled_ios 3 set large_net_threshold 50 - set signature_net_threshold 20 + set signature_net_threshold 50 set halo_width 0.0 set halo_height 0.0 set fence_lx 0.0