Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
158 changes: 82 additions & 76 deletions src/mpl/src/clusterEngine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ void ClusteringEngine::run()
createRoot();
setBaseThresholds();

mapIOPinsAndPads();
createDataFlow();
createIOClusters();

Expand Down Expand Up @@ -78,7 +77,8 @@ void ClusteringEngine::setTree(PhysicalHierarchy* tree)
}

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

tree_->io_pads = getIOPads();

reportDesignData();
}

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

std::vector<odb::dbInst*> ClusteringEngine::getIOPads() const
{
std::vector<odb::dbInst*> io_pads;

for (odb::dbInst* inst : block_->getInsts()) {
const odb::dbMasterType& master_type = inst->getMaster()->getType();

// Skip PADs without core signal connections.
if (master_type == odb::dbMasterType::PAD_POWER
|| master_type == odb::dbMasterType::PAD_SPACER) {
continue;
}

if (inst->isPad()) {
io_pads.push_back(inst);
}
}

return io_pads;
}

void ClusteringEngine::reportDesignData()
{
const odb::Rect& die = block_->getDieArea();
Expand Down Expand Up @@ -357,7 +380,7 @@ void ClusteringEngine::setBaseThresholds()
// shape is the die area.
void ClusteringEngine::createIOClusters()
{
if (!tree_->maps.pad_to_bterm.empty()) {
if (!tree_->io_pads.empty()) {
createIOPadClusters();
return;
}
Expand Down Expand Up @@ -432,64 +455,17 @@ void ClusteringEngine::createClusterOfUnplacedIOs(odb::dbBTerm* bterm)
tree_->root->addChild(std::move(cluster));
}

void ClusteringEngine::mapIOPinsAndPads()
{
bool design_has_io_pads = false;
for (auto inst : block_->getInsts()) {
if (inst->getMaster()->isPad()) {
design_has_io_pads = true;
break;
}
}

if (!design_has_io_pads) {
return;
}

for (odb::dbNet* net : block_->getNets()) {
if (net->getBTerms().size() == 0) {
continue;
}

for (odb::dbBTerm* bterm : net->getBTerms()) {
for (odb::dbITerm* iterm : net->getITerms()) {
odb::dbInst* inst = iterm->getInst();
tree_->maps.pad_to_bterm[inst] = bterm;
tree_->maps.bterm_to_pad[bterm] = inst;
}
}
}
}

void ClusteringEngine::createIOPadClusters()
{
for (const auto& io_pad_path : data_connections_.io_and_regs) {
// Registers or Macros
const PathInsts& connected_insts = io_pad_path.second;
bool path_is_empty = true;
for (const std::set<odb::dbInst*>& insts_of_curr_hop_dist :
connected_insts) {
if (!insts_of_curr_hop_dist.empty()) {
path_is_empty = false;
break;
}
}

if (path_is_empty) {
continue;
}

odb::dbBTerm* bterm = io_pad_path.first;
odb::dbInst* pad = tree_->maps.bterm_to_pad.at(bterm);

createIOPadCluster(pad, bterm);
for (odb::dbInst* pad : tree_->io_pads) {
createIOPadCluster(pad);
}
}

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

const odb::Rect& pad_bbox = pad->getBBox()->getBox();
Expand Down Expand Up @@ -567,7 +543,13 @@ bool ClusteringEngine::stdCellsHaveLiberty()
VerticesMaps ClusteringEngine::computeVertices()
{
VerticesMaps vertices_maps;
computeIOVertices(vertices_maps);

if (tree_->io_pads.empty()) {
computeIOVertices(vertices_maps);
} else {
computePadVertices(vertices_maps);
}

computeStdCellVertices(vertices_maps);
computeMacroPinVertices(vertices_maps);

Expand All @@ -591,6 +573,16 @@ void ClusteringEngine::computeIOVertices(VerticesMaps& vertices_maps)
}
}

void ClusteringEngine::computePadVertices(VerticesMaps& vertices_maps)
{
for (odb::dbInst* pad : tree_->io_pads) {
const int id = static_cast<int>(vertices_maps.stoppers.size());
odb::dbIntProperty::create(pad, "vertex_id", id);
vertices_maps.id_to_std_cell[id] = pad;
vertices_maps.stoppers.push_back(true);
}
}

void ClusteringEngine::computeStdCellVertices(VerticesMaps& vertices_maps)
{
for (odb::dbInst* inst : block_->getInsts()) {
Expand Down Expand Up @@ -656,11 +648,7 @@ DataFlowHypergraph ClusteringEngine::computeHypergraph(
if (inst->isBlock()) {
vertex_id = odb::dbIntProperty::find(iterm, "vertex_id")->getValue();
} else if (inst->isPad()) {
// To properly consider the path of a signal that travels from a PAD
// to the core we use the path's bterm as the vertex.
odb::dbBTerm* pad_bterm = tree_->maps.pad_to_bterm.at(inst);
vertex_id
= odb::dbIntProperty::find(pad_bterm, "vertex_id")->getValue();
vertex_id = odb::dbIntProperty::find(inst, "vertex_id")->getValue();
} else {
odb::dbIntProperty* int_prop
= odb::dbIntProperty::find(inst, "vertex_id");
Expand Down Expand Up @@ -974,18 +962,35 @@ void ClusteringEngine::incorporateNewCluster(std::unique_ptr<Cluster> cluster,
parent->addChild(std::move(cluster));
}

// We don't change the association of ignored instances throughout
// the multilevel autoclustering process. I.e., ignored instances
// should remain at the root.
//
// Attention: A pad is a special ignored instance in the sense that
// it will be associated with a pad cluster. By not changing the
// association of ignored instances during autoclustering, we prevent
// the autoclustering process from messing up the association of
// PAD inst -> PAD Cluster as these last ones are created beforehand.
void ClusteringEngine::updateInstancesAssociation(Cluster* cluster)
{
const int cluster_id = cluster->getId();
const ClusterType cluster_type = cluster->getClusterType();
if (cluster_type == HardMacroCluster || cluster_type == MixedCluster) {
for (odb::dbInst* inst : cluster->getLeafMacros()) {
if (isIgnoredInst(inst)) {
continue;
}

tree_->maps.inst_to_cluster_id[inst] = cluster_id;
}
}

if (cluster_type == StdCellCluster || cluster_type == MixedCluster) {
for (odb::dbInst* inst : cluster->getLeafStdCells()) {
if (isIgnoredInst(inst)) {
continue;
}

tree_->maps.inst_to_cluster_id[inst] = cluster_id;
}
}
Expand All @@ -1008,19 +1013,18 @@ void ClusteringEngine::updateInstancesAssociation(odb::dbModule* module,
int cluster_id,
bool include_macro)
{
if (include_macro) {
for (odb::dbInst* inst : module->getInsts()) {
tree_->maps.inst_to_cluster_id[inst] = cluster_id;
for (odb::dbInst* inst : module->getInsts()) {
if (isIgnoredInst(inst)) {
continue;
}
} else { // only consider standard cells
for (odb::dbInst* inst : module->getInsts()) {
if (isIgnoredInst(inst) || inst->isBlock()) {
continue;
}

tree_->maps.inst_to_cluster_id[inst] = cluster_id;
if (!include_macro && inst->isBlock()) {
continue;
}

tree_->maps.inst_to_cluster_id[inst] = cluster_id;
}

for (odb::dbModInst* child_module_inst : module->getChildren()) {
updateInstancesAssociation(
child_module_inst->getMaster(), cluster_id, include_macro);
Expand Down Expand Up @@ -1716,14 +1720,16 @@ void ClusteringEngine::updateConnections()
}

bool net_has_io_pin = false;
for (odb::dbBTerm* bterm : net->getBTerms()) {
const int cluster_id = tree_->maps.bterm_to_cluster_id.at(bterm);
net_has_io_pin = true;
if (tree_->io_pads.empty()) {
for (odb::dbBTerm* bterm : net->getBTerms()) {
const int cluster_id = tree_->maps.bterm_to_cluster_id.at(bterm);
net_has_io_pin = true;

if (bterm->getIoType() == odb::dbIoType::INPUT) {
driver_cluster_id = cluster_id;
} else {
load_clusters_ids.push_back(cluster_id);
if (bterm->getIoType() == odb::dbIoType::INPUT) {
driver_cluster_id = cluster_id;
} else {
load_clusters_ids.push_back(cluster_id);
}
}
}

Expand Down
10 changes: 4 additions & 6 deletions src/mpl/src/clusterEngine.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,15 +79,12 @@ struct PhysicalHierarchyMaps

InstToHardMap inst_to_hard;
ModuleToMetricsMap module_to_metrics;

// Only for designs with IO Pads
std::map<odb::dbInst*, odb::dbBTerm*> pad_to_bterm;
std::map<odb::dbBTerm*, odb::dbInst*> bterm_to_pad;
};

struct PhysicalHierarchy
{
std::unique_ptr<Cluster> root;
std::vector<odb::dbInst*> io_pads;
PhysicalHierarchyMaps maps;

BoundaryRegionList available_regions_for_unconstrained_pins;
Expand Down Expand Up @@ -171,15 +168,15 @@ class ClusteringEngine
void searchForFixedInstsInsideFloorplanShape();
float computeMacroWithHaloArea(
const std::vector<odb::dbInst*>& unfixed_macros);
std::vector<odb::dbInst*> getIOPads() const;
void reportDesignData();
void createRoot();
void setBaseThresholds();
void createIOClusters();
Cluster* findIOClusterWithSameConstraint(odb::dbBTerm* bterm) const;
void createClusterOfUnplacedIOs(odb::dbBTerm* bterm);
void createIOPadClusters();
void createIOPadCluster(odb::dbInst* pad, odb::dbBTerm* bterm);
void mapIOPinsAndPads();
void createIOPadCluster(odb::dbInst* pad);
void treatEachMacroAsSingleCluster();
void incorporateNewCluster(std::unique_ptr<Cluster> cluster, Cluster* parent);
void setClusterMetrics(Cluster* cluster);
Expand Down Expand Up @@ -230,6 +227,7 @@ class ClusteringEngine
bool stdCellsHaveLiberty();
VerticesMaps computeVertices();
void computeIOVertices(VerticesMaps& vertices_maps);
void computePadVertices(VerticesMaps& vertices_maps);
void computeStdCellVertices(VerticesMaps& vertices_maps);
void computeMacroPinVertices(VerticesMaps& vertices_maps);
DataFlowHypergraph computeHypergraph(int num_of_vertices);
Expand Down
2 changes: 1 addition & 1 deletion src/mpl/src/hier_rtlmp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -902,7 +902,7 @@ void HierRTLMP::searchAvailableRegionsForUnconstrainedPins()

void HierRTLMP::createPinAccessBlockages()
{
if (!tree_->maps.pad_to_bterm.empty()) {
if (!tree_->io_pads.empty()) {
return;
}

Expand Down