diff --git a/src/mpl2/src/hier_rtlmp.cpp b/src/mpl2/src/hier_rtlmp.cpp index 42965e645c5..b339302b167 100644 --- a/src/mpl2/src/hier_rtlmp.cpp +++ b/src/mpl2/src/hier_rtlmp.cpp @@ -539,7 +539,10 @@ void HierRTLMP::runMultilevelAutoclustering() } else { multilevelAutocluster(root_cluster_); - breakMixedLeafCluster(root_cluster_); + + std::vector> mixed_leaves; + fetchMixedLeaves(root_cluster_, mixed_leaves); + breakMixedLeaves(mixed_leaves); if (graphics_) { graphics_->finishedClustering(root_cluster_); @@ -2211,42 +2214,57 @@ void HierRTLMP::breakLargeFlatCluster(Cluster* parent) breakLargeFlatCluster(cluster_part_1); } -// Break mixed leaves into standard-cell and hard-macro clusters. -// Merge macros based on connection signature and footprint. -// Based on types of designs, we support two types of breaking up: -// Suppose current cluster is A. -// 1) Replace A by A1, A2, A3 -// 2) Type 2: Create a subtree: -// A -> A -// | | | -// A1 A2 A3 -void HierRTLMP::breakMixedLeafCluster(Cluster* root_cluster) +// Traverse the physical hierarchy tree in a DFS manner (post-order) +void HierRTLMP::fetchMixedLeaves( + Cluster* parent, + std::vector>& mixed_leaves) { - if (root_cluster->getChildren().empty() || root_cluster->getNumMacro() == 0) { + if (parent->getChildren().empty() || parent->getNumMacro() == 0) { return; } - // Traverse the physical hierarchy tree in a DFS manner (post-order) - std::vector mixed_leaves; - for (auto& child : root_cluster->getChildren()) { + std::vector sister_mixed_leaves; + + for (auto& child : parent->getChildren()) { setInstProperty(child); if (child->getNumMacro() > 0) { if (child->getChildren().empty()) { - mixed_leaves.push_back(child); + sister_mixed_leaves.push_back(child); } else { - breakMixedLeafCluster(child); + fetchMixedLeaves(child, mixed_leaves); } } else { child->setClusterType(StdCellCluster); } } - for (auto& mixed_leaf : mixed_leaves) { - breakMixedLeaf(mixed_leaf); - } + // We push the leaves after finishing searching the children so + // that each vector of clusters represents the children of one + // parent. + mixed_leaves.push_back(sister_mixed_leaves); +} - // Set the inst property back - setInstProperty(root_cluster); +// Break mixed leaves into standard-cell and hard-macro clusters. +// Merge macros based on connection signature and footprint. +// Based on types of designs, we support two types of breaking up: +// Suppose current cluster is A. +// 1) Replace A by A1, A2, A3 +// 2) Type 2: Create a subtree: +// A -> A +// | | | +// A1 A2 A3 +void HierRTLMP::breakMixedLeaves( + const std::vector>& mixed_leaves) +{ + for (const std::vector& sister_mixed_leaves : mixed_leaves) { + Cluster* parent = sister_mixed_leaves[0]->getParent(); + + for (Cluster* mixed_leaf : sister_mixed_leaves) { + breakMixedLeaf(mixed_leaf); + } + + setInstProperty(parent); + } } void HierRTLMP::breakMixedLeaf(Cluster* mixed_leaf) diff --git a/src/mpl2/src/hier_rtlmp.h b/src/mpl2/src/hier_rtlmp.h index 5497f463bbb..18cb999d836 100644 --- a/src/mpl2/src/hier_rtlmp.h +++ b/src/mpl2/src/hier_rtlmp.h @@ -203,7 +203,11 @@ class HierRTLMP void mergeClusters(std::vector& candidate_clusters); void updateSubTree(Cluster* parent); void breakLargeFlatCluster(Cluster* parent); - void breakMixedLeafCluster(Cluster* root_cluster); + + void fetchMixedLeaves(Cluster* parent, + std::vector>& mixed_leaves); + void breakMixedLeaves(const std::vector>& mixed_leaves); + void breakMixedLeaf(Cluster* mixed_leaf); void mapMacroInCluster2HardMacro(Cluster* cluster); void createOneClusterForEachMacro(Cluster* parent,