Skip to content

Commit d5e2cb7

Browse files
authored
Merge pull request #6894 from AcKoucher/mpl-pad-inst-association
mpl: fix pad clusters' connections
2 parents 00a2fe2 + 800aa9b commit d5e2cb7

File tree

3 files changed

+87
-83
lines changed

3 files changed

+87
-83
lines changed

src/mpl/src/clusterEngine.cpp

Lines changed: 82 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,6 @@ void ClusteringEngine::run()
4545
createRoot();
4646
setBaseThresholds();
4747

48-
mapIOPinsAndPads();
4948
createDataFlow();
5049
createIOClusters();
5150

@@ -78,7 +77,8 @@ void ClusteringEngine::setTree(PhysicalHierarchy* tree)
7877
}
7978

8079
// Check if macro placement is both needed and feasible.
81-
// Also report some design data relevant for the user.
80+
// Also report some design data relevant for the user and
81+
// initialize the tree with data from the design.
8282
void ClusteringEngine::init()
8383
{
8484
const std::vector<odb::dbInst*> unfixed_macros = getUnfixedMacros();
@@ -105,6 +105,8 @@ void ClusteringEngine::init()
105105
tree_->floorplan_shape.getArea());
106106
}
107107

108+
tree_->io_pads = getIOPads();
109+
108110
reportDesignData();
109111
}
110112

@@ -222,6 +224,27 @@ Metrics* ClusteringEngine::computeModuleMetrics(odb::dbModule* module)
222224
return tree_->maps.module_to_metrics[module].get();
223225
}
224226

227+
std::vector<odb::dbInst*> ClusteringEngine::getIOPads() const
228+
{
229+
std::vector<odb::dbInst*> io_pads;
230+
231+
for (odb::dbInst* inst : block_->getInsts()) {
232+
const odb::dbMasterType& master_type = inst->getMaster()->getType();
233+
234+
// Skip PADs without core signal connections.
235+
if (master_type == odb::dbMasterType::PAD_POWER
236+
|| master_type == odb::dbMasterType::PAD_SPACER) {
237+
continue;
238+
}
239+
240+
if (inst->isPad()) {
241+
io_pads.push_back(inst);
242+
}
243+
}
244+
245+
return io_pads;
246+
}
247+
225248
void ClusteringEngine::reportDesignData()
226249
{
227250
const odb::Rect& die = block_->getDieArea();
@@ -357,7 +380,7 @@ void ClusteringEngine::setBaseThresholds()
357380
// shape is the die area.
358381
void ClusteringEngine::createIOClusters()
359382
{
360-
if (!tree_->maps.pad_to_bterm.empty()) {
383+
if (!tree_->io_pads.empty()) {
361384
createIOPadClusters();
362385
return;
363386
}
@@ -432,64 +455,17 @@ void ClusteringEngine::createClusterOfUnplacedIOs(odb::dbBTerm* bterm)
432455
tree_->root->addChild(std::move(cluster));
433456
}
434457

435-
void ClusteringEngine::mapIOPinsAndPads()
436-
{
437-
bool design_has_io_pads = false;
438-
for (auto inst : block_->getInsts()) {
439-
if (inst->getMaster()->isPad()) {
440-
design_has_io_pads = true;
441-
break;
442-
}
443-
}
444-
445-
if (!design_has_io_pads) {
446-
return;
447-
}
448-
449-
for (odb::dbNet* net : block_->getNets()) {
450-
if (net->getBTerms().size() == 0) {
451-
continue;
452-
}
453-
454-
for (odb::dbBTerm* bterm : net->getBTerms()) {
455-
for (odb::dbITerm* iterm : net->getITerms()) {
456-
odb::dbInst* inst = iterm->getInst();
457-
tree_->maps.pad_to_bterm[inst] = bterm;
458-
tree_->maps.bterm_to_pad[bterm] = inst;
459-
}
460-
}
461-
}
462-
}
463-
464458
void ClusteringEngine::createIOPadClusters()
465459
{
466-
for (const auto& io_pad_path : data_connections_.io_and_regs) {
467-
// Registers or Macros
468-
const PathInsts& connected_insts = io_pad_path.second;
469-
bool path_is_empty = true;
470-
for (const std::set<odb::dbInst*>& insts_of_curr_hop_dist :
471-
connected_insts) {
472-
if (!insts_of_curr_hop_dist.empty()) {
473-
path_is_empty = false;
474-
break;
475-
}
476-
}
477-
478-
if (path_is_empty) {
479-
continue;
480-
}
481-
482-
odb::dbBTerm* bterm = io_pad_path.first;
483-
odb::dbInst* pad = tree_->maps.bterm_to_pad.at(bterm);
484-
485-
createIOPadCluster(pad, bterm);
460+
for (odb::dbInst* pad : tree_->io_pads) {
461+
createIOPadCluster(pad);
486462
}
487463
}
488464

489-
void ClusteringEngine::createIOPadCluster(odb::dbInst* pad, odb::dbBTerm* bterm)
465+
void ClusteringEngine::createIOPadCluster(odb::dbInst* pad)
490466
{
491467
auto cluster = std::make_unique<Cluster>(id_, pad->getName(), logger_);
492-
tree_->maps.bterm_to_cluster_id[bterm] = id_;
468+
tree_->maps.inst_to_cluster_id[pad] = id_;
493469
tree_->maps.id_to_cluster[id_++] = cluster.get();
494470

495471
const odb::Rect& pad_bbox = pad->getBBox()->getBox();
@@ -567,7 +543,13 @@ bool ClusteringEngine::stdCellsHaveLiberty()
567543
VerticesMaps ClusteringEngine::computeVertices()
568544
{
569545
VerticesMaps vertices_maps;
570-
computeIOVertices(vertices_maps);
546+
547+
if (tree_->io_pads.empty()) {
548+
computeIOVertices(vertices_maps);
549+
} else {
550+
computePadVertices(vertices_maps);
551+
}
552+
571553
computeStdCellVertices(vertices_maps);
572554
computeMacroPinVertices(vertices_maps);
573555

@@ -591,6 +573,16 @@ void ClusteringEngine::computeIOVertices(VerticesMaps& vertices_maps)
591573
}
592574
}
593575

576+
void ClusteringEngine::computePadVertices(VerticesMaps& vertices_maps)
577+
{
578+
for (odb::dbInst* pad : tree_->io_pads) {
579+
const int id = static_cast<int>(vertices_maps.stoppers.size());
580+
odb::dbIntProperty::create(pad, "vertex_id", id);
581+
vertices_maps.id_to_std_cell[id] = pad;
582+
vertices_maps.stoppers.push_back(true);
583+
}
584+
}
585+
594586
void ClusteringEngine::computeStdCellVertices(VerticesMaps& vertices_maps)
595587
{
596588
for (odb::dbInst* inst : block_->getInsts()) {
@@ -656,11 +648,7 @@ DataFlowHypergraph ClusteringEngine::computeHypergraph(
656648
if (inst->isBlock()) {
657649
vertex_id = odb::dbIntProperty::find(iterm, "vertex_id")->getValue();
658650
} else if (inst->isPad()) {
659-
// To properly consider the path of a signal that travels from a PAD
660-
// to the core we use the path's bterm as the vertex.
661-
odb::dbBTerm* pad_bterm = tree_->maps.pad_to_bterm.at(inst);
662-
vertex_id
663-
= odb::dbIntProperty::find(pad_bterm, "vertex_id")->getValue();
651+
vertex_id = odb::dbIntProperty::find(inst, "vertex_id")->getValue();
664652
} else {
665653
odb::dbIntProperty* int_prop
666654
= odb::dbIntProperty::find(inst, "vertex_id");
@@ -974,18 +962,35 @@ void ClusteringEngine::incorporateNewCluster(std::unique_ptr<Cluster> cluster,
974962
parent->addChild(std::move(cluster));
975963
}
976964

965+
// We don't change the association of ignored instances throughout
966+
// the multilevel autoclustering process. I.e., ignored instances
967+
// should remain at the root.
968+
//
969+
// Attention: A pad is a special ignored instance in the sense that
970+
// it will be associated with a pad cluster. By not changing the
971+
// association of ignored instances during autoclustering, we prevent
972+
// the autoclustering process from messing up the association of
973+
// PAD inst -> PAD Cluster as these last ones are created beforehand.
977974
void ClusteringEngine::updateInstancesAssociation(Cluster* cluster)
978975
{
979976
const int cluster_id = cluster->getId();
980977
const ClusterType cluster_type = cluster->getClusterType();
981978
if (cluster_type == HardMacroCluster || cluster_type == MixedCluster) {
982979
for (odb::dbInst* inst : cluster->getLeafMacros()) {
980+
if (isIgnoredInst(inst)) {
981+
continue;
982+
}
983+
983984
tree_->maps.inst_to_cluster_id[inst] = cluster_id;
984985
}
985986
}
986987

987988
if (cluster_type == StdCellCluster || cluster_type == MixedCluster) {
988989
for (odb::dbInst* inst : cluster->getLeafStdCells()) {
990+
if (isIgnoredInst(inst)) {
991+
continue;
992+
}
993+
989994
tree_->maps.inst_to_cluster_id[inst] = cluster_id;
990995
}
991996
}
@@ -1008,19 +1013,18 @@ void ClusteringEngine::updateInstancesAssociation(odb::dbModule* module,
10081013
int cluster_id,
10091014
bool include_macro)
10101015
{
1011-
if (include_macro) {
1012-
for (odb::dbInst* inst : module->getInsts()) {
1013-
tree_->maps.inst_to_cluster_id[inst] = cluster_id;
1016+
for (odb::dbInst* inst : module->getInsts()) {
1017+
if (isIgnoredInst(inst)) {
1018+
continue;
10141019
}
1015-
} else { // only consider standard cells
1016-
for (odb::dbInst* inst : module->getInsts()) {
1017-
if (isIgnoredInst(inst) || inst->isBlock()) {
1018-
continue;
1019-
}
10201020

1021-
tree_->maps.inst_to_cluster_id[inst] = cluster_id;
1021+
if (!include_macro && inst->isBlock()) {
1022+
continue;
10221023
}
1024+
1025+
tree_->maps.inst_to_cluster_id[inst] = cluster_id;
10231026
}
1027+
10241028
for (odb::dbModInst* child_module_inst : module->getChildren()) {
10251029
updateInstancesAssociation(
10261030
child_module_inst->getMaster(), cluster_id, include_macro);
@@ -1727,14 +1731,16 @@ void ClusteringEngine::buildNetListConnections()
17271731
}
17281732

17291733
bool net_has_io_pin = false;
1730-
for (odb::dbBTerm* bterm : net->getBTerms()) {
1731-
const int cluster_id = tree_->maps.bterm_to_cluster_id.at(bterm);
1732-
net_has_io_pin = true;
1734+
if (tree_->io_pads.empty()) {
1735+
for (odb::dbBTerm* bterm : net->getBTerms()) {
1736+
const int cluster_id = tree_->maps.bterm_to_cluster_id.at(bterm);
1737+
net_has_io_pin = true;
17331738

1734-
if (bterm->getIoType() == odb::dbIoType::INPUT) {
1735-
driver_cluster_id = cluster_id;
1736-
} else {
1737-
load_clusters_ids.push_back(cluster_id);
1739+
if (bterm->getIoType() == odb::dbIoType::INPUT) {
1740+
driver_cluster_id = cluster_id;
1741+
} else {
1742+
load_clusters_ids.push_back(cluster_id);
1743+
}
17381744
}
17391745
}
17401746

src/mpl/src/clusterEngine.h

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -79,15 +79,12 @@ struct PhysicalHierarchyMaps
7979

8080
InstToHardMap inst_to_hard;
8181
ModuleToMetricsMap module_to_metrics;
82-
83-
// Only for designs with IO Pads
84-
std::map<odb::dbInst*, odb::dbBTerm*> pad_to_bterm;
85-
std::map<odb::dbBTerm*, odb::dbInst*> bterm_to_pad;
8682
};
8783

8884
struct PhysicalHierarchy
8985
{
9086
std::unique_ptr<Cluster> root;
87+
std::vector<odb::dbInst*> io_pads;
9188
PhysicalHierarchyMaps maps;
9289

9390
BoundaryRegionList available_regions_for_unconstrained_pins;
@@ -170,15 +167,15 @@ class ClusteringEngine
170167
void searchForFixedInstsInsideFloorplanShape();
171168
float computeMacroWithHaloArea(
172169
const std::vector<odb::dbInst*>& unfixed_macros);
170+
std::vector<odb::dbInst*> getIOPads() const;
173171
void reportDesignData();
174172
void createRoot();
175173
void setBaseThresholds();
176174
void createIOClusters();
177175
Cluster* findIOClusterWithSameConstraint(odb::dbBTerm* bterm) const;
178176
void createClusterOfUnplacedIOs(odb::dbBTerm* bterm);
179177
void createIOPadClusters();
180-
void createIOPadCluster(odb::dbInst* pad, odb::dbBTerm* bterm);
181-
void mapIOPinsAndPads();
178+
void createIOPadCluster(odb::dbInst* pad);
182179
void treatEachMacroAsSingleCluster();
183180
void incorporateNewCluster(std::unique_ptr<Cluster> cluster, Cluster* parent);
184181
void setClusterMetrics(Cluster* cluster);
@@ -233,6 +230,7 @@ class ClusteringEngine
233230
bool stdCellsHaveLiberty();
234231
VerticesMaps computeVertices();
235232
void computeIOVertices(VerticesMaps& vertices_maps);
233+
void computePadVertices(VerticesMaps& vertices_maps);
236234
void computeStdCellVertices(VerticesMaps& vertices_maps);
237235
void computeMacroPinVertices(VerticesMaps& vertices_maps);
238236
DataFlowHypergraph computeHypergraph(int num_of_vertices);

src/mpl/src/hier_rtlmp.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -907,7 +907,7 @@ void HierRTLMP::searchAvailableRegionsForUnconstrainedPins()
907907
// extension of all edges of the die area.
908908
void HierRTLMP::createPinAccessBlockages()
909909
{
910-
if (!tree_->maps.pad_to_bterm.empty()) {
910+
if (!tree_->io_pads.empty()) {
911911
return;
912912
}
913913

0 commit comments

Comments
 (0)