Skip to content

Commit bb4801b

Browse files
Merge pull request #2542 from The-OpenROAD-Project-staging/mpl2_part
Interface to MLPart for mpl2
2 parents 6371989 + 1db6573 commit bb4801b

File tree

12 files changed

+156
-67
lines changed

12 files changed

+156
-67
lines changed

src/mpl2/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,5 +77,6 @@ target_link_libraries(mpl2
7777
gui
7878
ortools::ortools
7979
dl
80+
par
8081
)
8182

src/mpl2/include/mpl2/rtl_mp.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ class MacroPlacer2
8585
const float fence_weight,
8686
const float boundary_weight,
8787
const float notch_weight,
88+
const float macro_blockage_weight,
8889
const float pin_access_th,
8990
const float target_util,
9091
const float target_dead_space,

src/mpl2/src/hier_rtlmp.cpp

Lines changed: 79 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -40,15 +40,14 @@
4040

4141
// Partitioner note : currently we are still using MLPart to partition large
4242
// flat clusters Later this will be replaced by our TritonPart
43-
//#include "par/MLPart.h"
44-
4543
#include "SACoreHardMacro.h"
4644
#include "SACoreSoftMacro.h"
4745
#include "bus_synthesis.h"
4846
#include "db_sta/dbNetwork.hh"
4947
#include "graphics.h"
5048
#include "object.h"
5149
#include "odb/db.h"
50+
#include "par/MLPart.h"
5251
#include "sta/Liberty.hh"
5352
#include "utl/Logger.h"
5453

@@ -113,6 +112,11 @@ void HierRTLMP::setNotchWeight(float weight)
113112
notch_weight_ = weight;
114113
}
115114

115+
void HierRTLMP::setMacroBlockageWeight(float weight)
116+
{
117+
macro_blockage_weight_ = weight;
118+
}
119+
116120
void HierRTLMP::setGlobalFence(float fence_lx,
117121
float fence_ly,
118122
float fence_ux,
@@ -135,10 +139,10 @@ void HierRTLMP::setNumBundledIOsPerBoundary(int num_bundled_ios)
135139
num_bundled_IOs_ = num_bundled_ios;
136140
}
137141

138-
void HierRTLMP::setTopLevelClusterSize(int max_num_macro,
139-
int min_num_macro,
140-
int max_num_inst,
141-
int min_num_inst)
142+
void HierRTLMP::setClusterSize(int max_num_macro,
143+
int min_num_macro,
144+
int max_num_inst,
145+
int min_num_inst)
142146
{
143147
max_num_macro_base_ = max_num_macro;
144148
min_num_macro_base_ = min_num_macro;
@@ -324,10 +328,14 @@ void HierRTLMP::hierRTLMacroPlacer()
324328
// create data flow information
325329
createDataFlow();
326330

327-
logger_->report("Finish Calculate Data Flow detailed CR done");
331+
logger_->report("Finish Calculate Data Flow");
328332

329333
// Create physical hierarchy tree in a post-order DFS manner
334+
logger_->report("Call multi level clustering max level: {}", max_num_level_);
335+
330336
multiLevelCluster(root_cluster_); // Recursive call for creating the tree
337+
logger_->report("Print Physical Hierarchy Tree ** max_hier_level: {}",
338+
max_hier_level_);
331339
printPhysicalHierarchyTree(root_cluster_, 0);
332340

333341
//
@@ -351,6 +359,8 @@ void HierRTLMP::hierRTLMacroPlacer()
351359
// and they can tune the options to get better
352360
// clustering results
353361
//
362+
logger_->report(
363+
"Print Physical Hierarchy Tree after breaking mixed clusters **");
354364
printPhysicalHierarchyTree(root_cluster_, 0);
355365

356366
// Map the macros in each cluster to their HardMacro objects
@@ -439,6 +449,8 @@ Metric* HierRTLMP::computeMetric(odb::dbModule* module)
439449

440450
for (odb::dbInst* inst : module->getInsts()) {
441451
const sta::LibertyCell* liberty_cell = network_->libertyCell(inst);
452+
if (liberty_cell == nullptr)
453+
continue;
442454
odb::dbMaster* master = inst->getMaster();
443455
// check if the instance is a pad or a cover macro
444456
if (master->isPad() || master->isCover()) {
@@ -713,7 +725,7 @@ void HierRTLMP::createBundledIOs()
713725
// delete the IO clusters that do not have any pins assigned to them
714726
for (auto& [cluster_id, flag] : cluster_io_map) {
715727
if (!flag) {
716-
logger_->report("remove cluster : {}, id: {}",
728+
logger_->report("remove bundled pin cluster : {}, id: {}",
717729
cluster_map_[cluster_id]->getName(),
718730
cluster_id);
719731
cluster_map_[cluster_id]->getParent()->removeChild(
@@ -724,25 +736,37 @@ void HierRTLMP::createBundledIOs()
724736
}
725737
}
726738

739+
//
727740
// Create physical hierarchy tree in a post-order DFS manner
728741
// Recursive call for creating the physical hierarchy tree
742+
//
729743
void HierRTLMP::multiLevelCluster(Cluster* parent)
730744
{
745+
bool force_split = false;
746+
if (level_ == 0) {
747+
// check if root cluster is below the max size of a leaf cluster
748+
// Force create child clusters in this case
749+
const int leaf_cluster_size
750+
= max_num_inst_base_ / std::pow(coarsening_ratio_, max_num_level_ - 1);
751+
if (parent->getNumStdCell() < leaf_cluster_size)
752+
force_split = true;
753+
logger_->report(
754+
"Set force split: leaf cluster size: {} root cluster size: {}",
755+
leaf_cluster_size,
756+
parent->getNumStdCell());
757+
}
731758
if (level_ >= max_num_level_) { // limited by the user-specified parameter
732759
return;
733760
}
734761
level_++;
735-
// for debug
736-
if (1) {
737-
logger_->report(
738-
"[Debug][HierRTLMP::MultiLevelCluster] {} {}: num_macro {} "
739-
"num_stdcell {}",
740-
parent->getName(),
741-
level_,
742-
parent->getNumMacro(),
743-
parent->getNumStdCell());
744-
}
745-
// end debug
762+
763+
logger_->report(
764+
"[Debug][HierRTLMP::MultiLevelCluster] {} {}: num_macro {} num_stdcell "
765+
"{}",
766+
parent->getName(),
767+
level_,
768+
parent->getNumMacro(),
769+
parent->getNumStdCell());
746770

747771
// a large coarsening_ratio_ helps the clustering process converge fast
748772
max_num_macro_
@@ -758,8 +782,9 @@ void HierRTLMP::multiLevelCluster(Cluster* parent)
758782
max_num_macro_ = max_num_macro_ * (1 + tolerance_);
759783
min_num_macro_ = min_num_macro_ * (1 - tolerance_);
760784

761-
if (parent->getNumMacro() > max_num_macro_
762-
|| parent->getNumStdCell() > max_num_inst_) {
785+
if (force_split || (parent->getNumStdCell() > max_num_inst_)) {
786+
if ((max_num_level_ - level_) > max_hier_level_)
787+
max_hier_level_ = max_num_level_ - level_;
763788
breakCluster(parent); // Break the parent cluster into children clusters
764789
updateSubTree(parent); // update the subtree to the physical hierarchy tree
765790
for (auto& child : parent->getChildren()) {
@@ -836,18 +861,22 @@ void HierRTLMP::setInstProperty(odb::dbModule* module,
836861
}
837862
}
838863

864+
//
839865
// Break the parent cluster into children clusters
840866
// We expand the parent cluster into a subtree based on logical
841867
// hierarchy in a DFS manner. During the expansion process,
842868
// we merge small clusters in the same logical hierarchy
869+
//
843870
void HierRTLMP::breakCluster(Cluster* parent)
844871
{
845872
logger_->report("[Debug][HierRTLMP::BreakCluster] cluster_name : {}",
846873
parent->getName());
874+
//
847875
// Consider three different cases:
848876
// (a) parent is an empty cluster
849877
// (b) parent is a cluster corresponding to a logical module
850878
// (c) parent is a cluster generated by merging small clusters
879+
//
851880
if ((parent->getLeafStdCells().size() == 0)
852881
&& (parent->getLeafMacros().size() == 0)
853882
&& (parent->getDbModules().size() == 0)) {
@@ -868,10 +897,11 @@ void HierRTLMP::breakCluster(Cluster* parent)
868897
if (module->getChildren().size() == 0) {
869898
for (odb::dbInst* inst : module->getInsts()) {
870899
const sta::LibertyCell* liberty_cell = network_->libertyCell(inst);
900+
if (liberty_cell == nullptr)
901+
continue;
871902
odb::dbMaster* master = inst->getMaster();
872903
// check if the instance is a Pad, Cover or empty block (such as marker)
873-
if (master->isPad() || master->isCover()
874-
|| (master->isBlock() && liberty_cell == nullptr)) {
904+
if (master->isPad() || master->isCover()) {
875905
continue;
876906
} else if (master->isBlock()) {
877907
parent->addLeafMacro(inst);
@@ -887,6 +917,7 @@ void HierRTLMP::breakCluster(Cluster* parent)
887917
// we first model each child logical module as a cluster
888918
for (odb::dbModInst* child : module->getChildren()) {
889919
std::string cluster_name = child->getMaster()->getHierarchicalName();
920+
// Create a new cluster for the child module
890921
Cluster* cluster = new Cluster(cluster_id_, cluster_name, logger_);
891922
cluster->addDbModule(child->getMaster());
892923
setInstProperty(cluster);
@@ -897,23 +928,28 @@ void HierRTLMP::breakCluster(Cluster* parent)
897928
parent->addChild(cluster);
898929
}
899930
// Check the glue logics
931+
// Glue logic instances are loose instances in a given module that also
932+
// contain module instances
933+
//
900934
std::string cluster_name
901935
= std::string("(") + parent->getName() + ")_glue_logic";
902936
Cluster* cluster = new Cluster(cluster_id_, cluster_name, logger_);
903937
for (odb::dbInst* inst : module->getInsts()) {
904938
const sta::LibertyCell* liberty_cell = network_->libertyCell(inst);
939+
if (liberty_cell == nullptr)
940+
continue;
905941
odb::dbMaster* master = inst->getMaster();
906942
// check if the instance is a Pad, Cover or empty block (such as marker)
907-
if (master->isPad() || master->isCover()
908-
|| (master->isBlock() && liberty_cell == nullptr)) {
943+
if (master->isPad() || master->isCover()) {
909944
continue;
910945
} else if (master->isBlock()) {
911946
cluster->addLeafMacro(inst);
912947
} else {
913948
cluster->addLeafStdCell(inst);
914949
}
915950
}
916-
// if the module has no meaningful glue instances
951+
//
952+
// if the module has no meaningful glue instances, delete it
917953
if (cluster->getLeafStdCells().size() == 0
918954
&& cluster->getLeafMacros().size() == 0) {
919955
delete cluster;
@@ -986,6 +1022,7 @@ void HierRTLMP::breakCluster(Cluster* parent)
9861022
setInstProperty(parent);
9871023
}
9881024

1025+
//
9891026
// Merge small clusters with the same parent cluster
9901027
// Recursively merge clusters
9911028
// Here is an example process based on connection signature
@@ -1005,6 +1042,7 @@ void HierRTLMP::breakCluster(Cluster* parent)
10051042
// have the same connection signature, A and C have the same connection
10061043
// signature, then B and C also have the same connection signature.
10071044
// Note in both types, we only merge clusters with the same parent cluster
1045+
//
10081046
void HierRTLMP::mergeClusters(std::vector<Cluster*>& candidate_clusters)
10091047
{
10101048
// for debug
@@ -1257,11 +1295,12 @@ void HierRTLMP::createDataFlow()
12571295
for (odb::dbITerm* iterm : net->getITerms()) {
12581296
odb::dbInst* inst = iterm->getInst();
12591297
const sta::LibertyCell* liberty_cell = network_->libertyCell(inst);
1298+
if (liberty_cell == nullptr)
1299+
continue;
12601300
odb::dbMaster* master = inst->getMaster();
12611301
// check if the instance is a Pad, Cover or empty block (such as marker)
12621302
// We ignore nets connecting Pads, Covers, or markers
1263-
if (master->isPad() || master->isCover()
1264-
|| (master->isBlock() && liberty_cell == nullptr)) {
1303+
if (master->isPad() || master->isCover()) {
12651304
pad_flag = true;
12661305
break;
12671306
}
@@ -2078,10 +2117,11 @@ void HierRTLMP::getHardMacros(odb::dbModule* module,
20782117
{
20792118
for (odb::dbInst* inst : module->getInsts()) {
20802119
const sta::LibertyCell* liberty_cell = network_->libertyCell(inst);
2120+
if (liberty_cell == nullptr)
2121+
continue;
20812122
odb::dbMaster* master = inst->getMaster();
20822123
// check if the instance is a pad or empty block (such as marker)
2083-
if (master->isPad() || master->isCover()
2084-
|| (master->isBlock() && liberty_cell == nullptr)) {
2124+
if (master->isPad() || master->isCover()) {
20852125
continue;
20862126
}
20872127
if (master->isBlock()) {
@@ -2794,7 +2834,7 @@ void HierRTLMP::multiLevelMacroPlacement(Cluster* parent)
27942834
// update the connnection
27952835
calculateConnection();
27962836
logger_->report("finish calculate connection");
2797-
updateDataFlow();
2837+
// updateDataFlow();
27982838
logger_->report("finish updating dataflow");
27992839
if (parent->getParent() != nullptr) {
28002840
// the parent cluster is not the root cluster
@@ -3179,12 +3219,14 @@ void HierRTLMP::multiLevelMacroPlacement(Cluster* parent)
31793219
}
31803220

31813221
// check if the parent cluster still need bus planning
3182-
for (auto& child : parent->getChildren()) {
3183-
if (child->getClusterType() == MixedCluster) {
3184-
logger_->report("\n\n Call Bus Synthesis\n\n");
3185-
// Call Path Synthesis to route buses
3186-
callBusPlanning(shaped_macros, nets);
3187-
break;
3222+
if (max_hier_level_ > 0) {
3223+
for (auto& child : parent->getChildren()) {
3224+
if (child->getClusterType() == MixedCluster) {
3225+
logger_->report("\n\n Call Bus Synthesis\n\n");
3226+
// Call Path Synthesis to route buses
3227+
// callBusPlanning(shaped_macros, nets);
3228+
break;
3229+
}
31883230
}
31893231
}
31903232

src/mpl2/src/hier_rtlmp.h

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -110,10 +110,10 @@ class HierRTLMP
110110
void setHaloWidth(float halo_width);
111111
// Hierarchical Clustering Related Options
112112
void setNumBundledIOsPerBoundary(int num_bundled_ios);
113-
void setTopLevelClusterSize(int max_num_macro,
114-
int min_num_macro,
115-
int max_num_inst,
116-
int min_num_inst);
113+
void setClusterSize(int max_num_macro,
114+
int min_num_macro,
115+
int max_num_inst,
116+
int min_num_inst);
117117
void setClusterSizeTolerance(float tolerance);
118118
void setMaxNumLevel(int max_num_level);
119119
void setClusterSizeRatioPerLevel(float coarsening_ratio);
@@ -126,6 +126,7 @@ class HierRTLMP
126126
void setFenceWeight(float fence_weight);
127127
void setBoundaryWeight(float boundary_weight);
128128
void setNotchWeight(float notch_weight);
129+
void setMacroBlockageWeight(float macro_blockage_weight);
129130
void setPinAccessThreshold(float pin_access_th);
130131
void setTargetUtil(float target_util);
131132
void setTargetDeadSpace(float target_dead_space);
@@ -352,6 +353,7 @@ class HierRTLMP
352353

353354
// Multilevel support
354355
int max_num_level_ = 2;
356+
int max_hier_level_ = 0;
355357
int level_ = 0;
356358
float coarsening_ratio_ = 5.0;
357359

src/mpl2/src/mpl.i

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ bool rtl_macro_placer_cmd(const int max_num_macro,
7171
const float fence_weight,
7272
const float boundary_weight,
7373
const float notch_weight,
74+
const float macro_blockage_weight,
7475
const float pin_access_th,
7576
const float target_util,
7677
const float target_dead_space,
@@ -101,6 +102,7 @@ bool rtl_macro_placer_cmd(const int max_num_macro,
101102
fence_weight,
102103
boundary_weight,
103104
notch_weight,
105+
macro_blockage_weight,
104106
pin_access_th,
105107
target_util,
106108
target_dead_space,

0 commit comments

Comments
 (0)