From 48ed28ac94f8ce9f62a7589db74021b8bdba8d91 Mon Sep 17 00:00:00 2001 From: Arthur Koucher Date: Mon, 9 Sep 2024 19:57:42 -0300 Subject: [PATCH 01/38] mpl2: add cluster data to HardMacro Signed-off-by: Arthur Koucher --- src/mpl2/src/clusterEngine.cpp | 4 ++++ src/mpl2/src/object.h | 5 +++++ 2 files changed, 9 insertions(+) diff --git a/src/mpl2/src/clusterEngine.cpp b/src/mpl2/src/clusterEngine.cpp index 57acba0026a..e65089af569 100644 --- a/src/mpl2/src/clusterEngine.cpp +++ b/src/mpl2/src/clusterEngine.cpp @@ -1871,6 +1871,10 @@ void ClusteringEngine::mapMacroInCluster2HardMacro(Cluster* cluster) getHardMacros(module, hard_macros); } cluster->specifyHardMacros(hard_macros); + + for (HardMacro* hard_macro : hard_macros) { + hard_macro->setCluster(cluster); + } } // Get all the hard macros in a logical module diff --git a/src/mpl2/src/object.h b/src/mpl2/src/object.h index 763d656ea02..d1185f02284 100644 --- a/src/mpl2/src/object.h +++ b/src/mpl2/src/object.h @@ -356,6 +356,9 @@ class HardMacro bool operator<(const HardMacro& macro) const; bool operator==(const HardMacro& macro) const; + void setCluster(Cluster* cluster) { cluster_ = cluster; } + Cluster* getCluster() const { return cluster_; } + // Get Physical Information // Note that the default X and Y include halo_width void setLocation(const std::pair& location); @@ -444,6 +447,8 @@ class HardMacro odb::dbInst* inst_ = nullptr; odb::dbBlock* block_ = nullptr; + + Cluster* cluster_ = nullptr; }; // We have three types of SoftMacros From 662f9e858b371e6ac15679991c62801efc5d4851 Mon Sep 17 00:00:00 2001 From: Arthur Koucher Date: Tue, 10 Sep 2024 20:06:04 -0300 Subject: [PATCH 02/38] mpl2: 1) Remove logic of bundled ios per edge and add one constraint cluster per edge 2) Add checks to prevent crash - for testing 3) Comment blockages creation based on IO placement Signed-off-by: Arthur Koucher --- src/mpl2/src/clusterEngine.cpp | 238 ++++++++++++--------------------- src/mpl2/src/clusterEngine.h | 7 + src/mpl2/src/hier_rtlmp.cpp | 2 +- src/mpl2/src/object.cpp | 3 - 4 files changed, 97 insertions(+), 153 deletions(-) diff --git a/src/mpl2/src/clusterEngine.cpp b/src/mpl2/src/clusterEngine.cpp index e65089af569..0c7a19076bf 100644 --- a/src/mpl2/src/clusterEngine.cpp +++ b/src/mpl2/src/clusterEngine.cpp @@ -330,165 +330,73 @@ void ClusteringEngine::setBaseThresholds() void ClusteringEngine::createIOClusters() { mapIOPads(); - debugPrint(logger_, - MPL, - "multilevel_autoclustering", - 1, - "Creating bundledIO clusters..."); - // Get the floorplan information and get the range of bundled IO regions + std::vector boundaries = getBoundaries(); const odb::Rect die = block_->getDieArea(); - const odb::Rect core = block_->getCoreArea(); - const int x_base = (die.xMax() - die.xMin()) / tree_->bundled_ios_per_edge; - const int y_base = (die.yMax() - die.yMin()) / tree_->bundled_ios_per_edge; - const int cluster_id_base = id_; - - // Map all the BTerms / Pads to Bundled IOs (cluster) - std::vector prefix_vec; - prefix_vec.emplace_back("L"); - prefix_vec.emplace_back("T"); - prefix_vec.emplace_back("R"); - prefix_vec.emplace_back("B"); - std::map cluster_io_map; - for (int i = 0; i < 4; - i++) { // four boundaries (Left, Top, Right and Bottom in order) - for (int j = 0; j < tree_->bundled_ios_per_edge; j++) { - const std::string cluster_name = prefix_vec[i] + std::to_string(j); - auto cluster = std::make_unique(id_, cluster_name, logger_); - cluster->setParent(tree_->root.get()); - cluster_io_map[id_] = false; - tree_->maps.id_to_cluster[id_++] = cluster.get(); - int x = 0.0; - int y = 0.0; - int width = 0; - int height = 0; - if (i == 0) { // Left boundary - x = die.xMin(); - y = die.yMin() + y_base * j; - height = y_base; - } else if (i == 1) { // Top boundary - x = die.xMin() + x_base * j; - y = die.yMax(); - width = x_base; - } else if (i == 2) { // Right boundary - x = die.xMax(); - y = die.yMax() - y_base * (j + 1); - height = y_base; - } else { // Bottom boundary - x = die.xMax() - x_base * (j + 1); - y = die.yMin(); - width = x_base; - } + const int number_of_boundaries = static_cast(boundaries.size()); - // set the cluster to a IO cluster - cluster->setAsIOCluster(std::pair(block_->dbuToMicrons(x), - block_->dbuToMicrons(y)), - block_->dbuToMicrons(width), - block_->dbuToMicrons(height)); - tree_->root->addChild(std::move(cluster)); - } - } - - // Map all the BTerms to bundled IOs - for (auto term : block_->getBTerms()) { - int lx = std::numeric_limits::max(); - int ly = std::numeric_limits::max(); - int ux = 0; - int uy = 0; - // If the design has IO pads, these block terms - // will not have block pins. - // Otherwise, the design will have IO pins. - for (const auto pin : term->getBPins()) { - for (const auto box : pin->getBoxes()) { - lx = std::min(lx, box->xMin()); - ly = std::min(ly, box->yMin()); - ux = std::max(ux, box->xMax()); - uy = std::max(uy, box->yMax()); - } - } - // remove power pins - if (term->getSigType().isSupply()) { - continue; - } + for (int i = 0; i < number_of_boundaries; i++) { + auto cluster + = std::make_unique(id_, toString(boundaries[i]), logger_); + cluster->setParent(tree_->root.get()); + tree_->maps.id_to_cluster[id_++] = cluster.get(); - // If the term has a connected pad, get the bbox from the pad inst - if (tree_->maps.bterm_to_inst.find(term) - != tree_->maps.bterm_to_inst.end()) { - lx = tree_->maps.bterm_to_inst[term]->getBBox()->xMin(); - ly = tree_->maps.bterm_to_inst[term]->getBBox()->yMin(); - ux = tree_->maps.bterm_to_inst[term]->getBBox()->xMax(); - uy = tree_->maps.bterm_to_inst[term]->getBBox()->yMax(); - if (lx <= core.xMin()) { - lx = die.xMin(); - } - if (ly <= core.yMin()) { - ly = die.yMin(); - } - if (ux >= core.xMax()) { - ux = die.xMax(); - } - if (uy >= core.yMax()) { - uy = die.yMax(); - } - } - // calculate cluster id based on the location of IO Pins / Pads - int cluster_id = -1; - if (lx <= die.xMin()) { - // The IO is on the left boundary - cluster_id = cluster_id_base - + std::floor(((ly + uy) / 2.0 - die.yMin()) / y_base); - } else if (uy >= die.yMax()) { - // The IO is on the top boundary - cluster_id = cluster_id_base + tree_->bundled_ios_per_edge - + std::floor(((lx + ux) / 2.0 - die.xMin()) / x_base); - } else if (ux >= die.xMax()) { - // The IO is on the right boundary - cluster_id = cluster_id_base + tree_->bundled_ios_per_edge * 2 - + std::floor((die.yMax() - (ly + uy) / 2.0) / y_base); - } else if (ly <= die.yMin()) { - // The IO is on the bottom boundary - cluster_id = cluster_id_base + tree_->bundled_ios_per_edge * 3 - + std::floor((die.xMax() - (lx + ux) / 2.0) / x_base); - } - - // Check if the IO pins / Pads exist - if (cluster_id == -1) { - logger_->error( - MPL, - 2, - "Floorplan has not been initialized? Pin location error for {}.", - term->getName()); - } else { - tree_->maps.bterm_to_cluster_id[term] = cluster_id; - } + int x = 0, y = 0; + int width = die.dx(), height = die.dy(); + setIoConstraintsClustersDimensions(die, boundaries[i], x, y, width, height); - cluster_io_map[cluster_id] = true; - } + cluster->setAsIOCluster(std::pair(block_->dbuToMicrons(x), + block_->dbuToMicrons(y)), + block_->dbuToMicrons(width), + block_->dbuToMicrons(height)); - // delete the IO clusters that do not have any pins assigned to them - for (auto& [cluster_id, flag] : cluster_io_map) { - if (!flag) { - debugPrint(logger_, - MPL, - "multilevel_autoclustering", - 1, - "Remove IO Cluster with no pins: {}, id: {}", - tree_->maps.id_to_cluster[cluster_id]->getName(), - cluster_id); - std::unique_ptr released_bundled_io - = tree_->maps.id_to_cluster[cluster_id]->getParent()->releaseChild( - tree_->maps.id_to_cluster[cluster_id]); - tree_->maps.id_to_cluster.erase(cluster_id); - } + tree_->root->addChild(std::move(cluster)); } - // At this point the cluster map has only the root (id = 0) and bundledIOs if (tree_->maps.id_to_cluster.size() == 1) { logger_->warn(MPL, 26, "Design has no IO pins!"); tree_->has_io_clusters = false; } } +std::vector ClusteringEngine::getBoundaries() +{ + std::vector boundaries; + + boundaries.push_back(L); + boundaries.push_back(T); + boundaries.push_back(R); + boundaries.push_back(B); + + return boundaries; +} +void ClusteringEngine::setIoConstraintsClustersDimensions( + const odb::Rect& die, + const Boundary boundary, + int& x, + int& y, + int& width, + int& height) +{ + if (boundary == L) { + x = die.xMin(); + y = die.yMin(); + width = 0; + } else if (boundary == T) { + x = die.xMin(); + y = die.yMax(); + height = 0; + } else if (boundary == R) { + x = die.xMax(); + y = die.yMin(); + width = 0; + } else { // Bottom + x = die.xMin(); + y = die.yMin(); + height = 0; + } +} + void ClusteringEngine::mapIOPads() { bool design_has_io_pads = false; @@ -878,12 +786,12 @@ void ClusteringEngine::updateDataFlow() // bterm, macros or ffs for (const auto& [bterm, insts] : data_connections_.io_and_regs) { - if (tree_->maps.bterm_to_cluster_id.find(bterm) - == tree_->maps.bterm_to_cluster_id.end()) { + const auto itr = tree_->maps.bterm_to_cluster_id.find(bterm); + if (itr == tree_->maps.bterm_to_cluster_id.end()) { continue; } - const int driver_id = tree_->maps.bterm_to_cluster_id.at(bterm); + const int driver_id = itr->second; for (int hops = 0; hops < max_num_of_hops_; hops++) { std::set sink_clusters = computeSinks(insts[hops]); @@ -1414,7 +1322,19 @@ void ClusteringEngine::breakLargeFlatCluster(Cluster* parent) continue; } + bool debug_ignore = false; for (odb::dbBTerm* bterm : net->getBTerms()) { + /* + This check does NOT need to exist. It's here + to help validate the implementation from the + beginning where there are not IO Clusters anymore. + */ + if (tree_->maps.bterm_to_cluster_id.find(bterm) + == tree_->maps.bterm_to_cluster_id.end()) { + debug_ignore = true; + break; + } + const int cluster_id = tree_->maps.bterm_to_cluster_id.at(bterm); if (bterm->getIoType() == odb::dbIoType::INPUT) { driver_id = cluster_vertex_id_map[cluster_id]; @@ -1422,6 +1342,11 @@ void ClusteringEngine::breakLargeFlatCluster(Cluster* parent) loads_id.insert(cluster_vertex_id_map[cluster_id]); } } + + if (debug_ignore) { + continue; + } + loads_id.insert(driver_id); if (driver_id != -1 && loads_id.size() > 1 && loads_id.size() < tree_->large_net_threshold) { @@ -1699,8 +1624,19 @@ void ClusteringEngine::updateConnections() } bool net_has_io_pin = false; - + bool debug_ignore = false; for (odb::dbBTerm* bterm : net->getBTerms()) { + /* + This check does NOT need to exist. It's here + to help validate the implementation from the + beginning where there are not IO Clusters anymore. + */ + if (tree_->maps.bterm_to_cluster_id.find(bterm) + == tree_->maps.bterm_to_cluster_id.end()) { + debug_ignore = true; + break; + } + const int cluster_id = tree_->maps.bterm_to_cluster_id.at(bterm); net_has_io_pin = true; @@ -1711,6 +1647,10 @@ void ClusteringEngine::updateConnections() } } + if (debug_ignore) { + continue; + } + if (driver_cluster_id != -1 && !load_clusters_ids.empty() && load_clusters_ids.size() < tree_->large_net_threshold) { const float weight = net_has_io_pin ? tree_->virtual_weight : 1.0; diff --git a/src/mpl2/src/clusterEngine.h b/src/mpl2/src/clusterEngine.h index 36059b83331..bf0793ac366 100644 --- a/src/mpl2/src/clusterEngine.h +++ b/src/mpl2/src/clusterEngine.h @@ -181,6 +181,13 @@ class ClusteringEngine void createRoot(); void setBaseThresholds(); void createIOClusters(); + std::vector getBoundaries(); + void setIoConstraintsClustersDimensions(const odb::Rect& die, + const Boundary boundary, + int& x, + int& y, + int& width, + int& height); void mapIOPads(); void treatEachMacroAsSingleCluster(); void incorporateNewCluster(std::unique_ptr cluster, Cluster* parent); diff --git a/src/mpl2/src/hier_rtlmp.cpp b/src/mpl2/src/hier_rtlmp.cpp index 013c02d5da5..9406e74a91c 100644 --- a/src/mpl2/src/hier_rtlmp.cpp +++ b/src/mpl2/src/hier_rtlmp.cpp @@ -352,7 +352,7 @@ void HierRTLMP::runCoarseShaping() calculateChildrenTilings(tree_->root.get()); - setIOClustersBlockages(); + // setIOClustersBlockages(); setPlacementBlockages(); } diff --git a/src/mpl2/src/object.cpp b/src/mpl2/src/object.cpp index ed770109db3..f8e2526aa85 100644 --- a/src/mpl2/src/object.cpp +++ b/src/mpl2/src/object.cpp @@ -325,14 +325,11 @@ void Cluster::copyInstances(const Cluster& cluster) } } -// Bundled IO (Pads) cluster support -// The position is the center of IO pads in the cluster void Cluster::setAsIOCluster(const std::pair& pos, const float width, const float height) { is_io_cluster_ = true; - // Create a SoftMacro representing the IO cluster soft_macro_ = std::make_unique(pos, name_, width, height, this); } From 1523d901661e85072d425c16104b583b30bc1560 Mon Sep 17 00:00:00 2001 From: Arthur Koucher Date: Wed, 11 Sep 2024 12:28:21 -0300 Subject: [PATCH 03/38] mpl2: group IOs based on constraints Signed-off-by: Arthur Koucher --- src/mpl2/src/clusterEngine.cpp | 82 ++++++++++++++++++++++++---------- src/mpl2/src/clusterEngine.h | 6 ++- src/mpl2/src/object.cpp | 4 +- src/mpl2/src/object.h | 5 ++- 4 files changed, 71 insertions(+), 26 deletions(-) diff --git a/src/mpl2/src/clusterEngine.cpp b/src/mpl2/src/clusterEngine.cpp index 0c7a19076bf..fc4819b16c1 100644 --- a/src/mpl2/src/clusterEngine.cpp +++ b/src/mpl2/src/clusterEngine.cpp @@ -327,30 +327,34 @@ void ClusteringEngine::setBaseThresholds() tree_->base_min_std_cell); } +// Group IOs with the same constraints: +// 1. If an IO has a constraint region in a certain boundary, +// it is constrained to that entire boundary. +// 2. If an IO has no constraints, it is constrained to all boundaries. void ClusteringEngine::createIOClusters() { mapIOPads(); - std::vector boundaries = getBoundaries(); + // Boundary with constrained IOs -> cluster + std::map boundary_to_cluster; const odb::Rect die = block_->getDieArea(); - const int number_of_boundaries = static_cast(boundaries.size()); - for (int i = 0; i < number_of_boundaries; i++) { - auto cluster - = std::make_unique(id_, toString(boundaries[i]), logger_); - cluster->setParent(tree_->root.get()); - tree_->maps.id_to_cluster[id_++] = cluster.get(); - - int x = 0, y = 0; - int width = die.dx(), height = die.dy(); - setIoConstraintsClustersDimensions(die, boundaries[i], x, y, width, height); + for (odb::dbBTerm* bterm : block_->getBTerms()) { + Boundary constraint_boundary = NONE; - cluster->setAsIOCluster(std::pair(block_->dbuToMicrons(x), - block_->dbuToMicrons(y)), - block_->dbuToMicrons(width), - block_->dbuToMicrons(height)); + auto constraint_region = bterm->getConstraintRegion(); + if (constraint_region) { + constraint_boundary + = getConstraintBoundary(die, constraint_region.value()); + } - tree_->root->addChild(std::move(cluster)); + const auto itr = boundary_to_cluster.find(constraint_boundary); + if (itr != boundary_to_cluster.end()) { + Cluster* io_cluster = itr->second; + tree_->maps.bterm_to_cluster_id[bterm] = io_cluster->getId(); + } else { + createIOCluster(die, constraint_boundary, boundary_to_cluster); + } } if (tree_->maps.id_to_cluster.size() == 1) { @@ -359,17 +363,49 @@ void ClusteringEngine::createIOClusters() } } -std::vector ClusteringEngine::getBoundaries() +Boundary ClusteringEngine::getConstraintBoundary( + const odb::Rect& die, + const odb::Rect& constraint_region) { - std::vector boundaries; + if (constraint_region.xMin() == constraint_region.xMax()) { + if (constraint_region.xMin() == die.xMin()) { + return L; + } else { + return R; + } + } else { + if (constraint_region.yMin() == die.yMin()) { + return B; + } else { + return T; + } + } +} - boundaries.push_back(L); - boundaries.push_back(T); - boundaries.push_back(R); - boundaries.push_back(B); +void ClusteringEngine::createIOCluster( + const odb::Rect& die, + const Boundary constraint_boundary, + std::map& boundary_to_cluster) +{ + auto cluster + = std::make_unique(id_, toString(constraint_boundary), logger_); + tree_->maps.id_to_cluster[id_++] = cluster.get(); + + boundary_to_cluster[constraint_boundary] = cluster.get(); - return boundaries; + int x = 0, y = 0; + int width = die.dx(), height = die.dy(); + setIoConstraintsClustersDimensions( + die, constraint_boundary, x, y, width, height); + + cluster->setAsIOCluster( + std::pair(block_->dbuToMicrons(x), block_->dbuToMicrons(y)), + block_->dbuToMicrons(width), + block_->dbuToMicrons(height), + constraint_boundary); + tree_->root->addChild(std::move(cluster)); } + void ClusteringEngine::setIoConstraintsClustersDimensions( const odb::Rect& die, const Boundary boundary, diff --git a/src/mpl2/src/clusterEngine.h b/src/mpl2/src/clusterEngine.h index bf0793ac366..31672b2f548 100644 --- a/src/mpl2/src/clusterEngine.h +++ b/src/mpl2/src/clusterEngine.h @@ -181,7 +181,11 @@ class ClusteringEngine void createRoot(); void setBaseThresholds(); void createIOClusters(); - std::vector getBoundaries(); + Boundary getConstraintBoundary(const odb::Rect& die, + const odb::Rect& constraint_region); + void createIOCluster(const odb::Rect& die, + const Boundary constraint_boundary, + std::map& boundary_to_cluster); void setIoConstraintsClustersDimensions(const odb::Rect& die, const Boundary boundary, int& x, diff --git a/src/mpl2/src/object.cpp b/src/mpl2/src/object.cpp index f8e2526aa85..4354f6c151d 100644 --- a/src/mpl2/src/object.cpp +++ b/src/mpl2/src/object.cpp @@ -327,9 +327,11 @@ void Cluster::copyInstances(const Cluster& cluster) void Cluster::setAsIOCluster(const std::pair& pos, const float width, - const float height) + const float height, + const Boundary constraint_boundary) { is_io_cluster_ = true; + constraint_boundary_ = constraint_boundary; soft_macro_ = std::make_unique(pos, name_, width, height, this); } diff --git a/src/mpl2/src/object.h b/src/mpl2/src/object.h index d1185f02284..369f3e3182a 100644 --- a/src/mpl2/src/object.h +++ b/src/mpl2/src/object.h @@ -202,7 +202,8 @@ class Cluster // Position must be specified when setting an IO cluster void setAsIOCluster(const std::pair& pos, float width, - float height); + float height, + Boundary constraint_boundary); bool isIOCluster() const; void setAsArrayOfInterconnectedMacros(); bool isArrayOfInterconnectedMacros() const; @@ -300,6 +301,8 @@ class Cluster // We model bundled IOS (Pads) as a cluster with no area // The position be the center of IOs bool is_io_cluster_ = false; + Boundary constraint_boundary_ = NONE; + bool is_array_of_interconnected_macros = false; // Each cluster uses metrics to store its statistics From 2b34453509dd5a0bd4de29c8f80ca4c22aa6e328 Mon Sep 17 00:00:00 2001 From: Arthur Koucher Date: Thu, 12 Sep 2024 09:40:29 -0300 Subject: [PATCH 04/38] mpl2: 1) map bterms when creating a new io cluster 2) remove debug check 3) cluster that represent no constraints have the shape of the die Signed-off-by: Arthur Koucher --- src/mpl2/src/clusterEngine.cpp | 48 +++++++--------------------------- src/mpl2/src/clusterEngine.h | 3 ++- src/mpl2/src/graphics.cpp | 10 +++++++ 3 files changed, 22 insertions(+), 39 deletions(-) diff --git a/src/mpl2/src/clusterEngine.cpp b/src/mpl2/src/clusterEngine.cpp index fc4819b16c1..f980eaad61b 100644 --- a/src/mpl2/src/clusterEngine.cpp +++ b/src/mpl2/src/clusterEngine.cpp @@ -353,7 +353,7 @@ void ClusteringEngine::createIOClusters() Cluster* io_cluster = itr->second; tree_->maps.bterm_to_cluster_id[bterm] = io_cluster->getId(); } else { - createIOCluster(die, constraint_boundary, boundary_to_cluster); + createIOCluster(die, constraint_boundary, boundary_to_cluster, bterm); } } @@ -385,18 +385,23 @@ Boundary ClusteringEngine::getConstraintBoundary( void ClusteringEngine::createIOCluster( const odb::Rect& die, const Boundary constraint_boundary, - std::map& boundary_to_cluster) + std::map& boundary_to_cluster, + odb::dbBTerm* bterm) { auto cluster = std::make_unique(id_, toString(constraint_boundary), logger_); + tree_->maps.bterm_to_cluster_id[bterm] = id_; tree_->maps.id_to_cluster[id_++] = cluster.get(); boundary_to_cluster[constraint_boundary] = cluster.get(); - int x = 0, y = 0; + int x = die.xMin(), y = die.yMin(); int width = die.dx(), height = die.dy(); - setIoConstraintsClustersDimensions( - die, constraint_boundary, x, y, width, height); + + if (constraint_boundary != NONE) { + setIoConstraintsClustersDimensions( + die, constraint_boundary, x, y, width, height); + } cluster->setAsIOCluster( std::pair(block_->dbuToMicrons(x), block_->dbuToMicrons(y)), @@ -1358,19 +1363,7 @@ void ClusteringEngine::breakLargeFlatCluster(Cluster* parent) continue; } - bool debug_ignore = false; for (odb::dbBTerm* bterm : net->getBTerms()) { - /* - This check does NOT need to exist. It's here - to help validate the implementation from the - beginning where there are not IO Clusters anymore. - */ - if (tree_->maps.bterm_to_cluster_id.find(bterm) - == tree_->maps.bterm_to_cluster_id.end()) { - debug_ignore = true; - break; - } - const int cluster_id = tree_->maps.bterm_to_cluster_id.at(bterm); if (bterm->getIoType() == odb::dbIoType::INPUT) { driver_id = cluster_vertex_id_map[cluster_id]; @@ -1378,11 +1371,6 @@ void ClusteringEngine::breakLargeFlatCluster(Cluster* parent) loads_id.insert(cluster_vertex_id_map[cluster_id]); } } - - if (debug_ignore) { - continue; - } - loads_id.insert(driver_id); if (driver_id != -1 && loads_id.size() > 1 && loads_id.size() < tree_->large_net_threshold) { @@ -1660,19 +1648,7 @@ void ClusteringEngine::updateConnections() } bool net_has_io_pin = false; - bool debug_ignore = false; for (odb::dbBTerm* bterm : net->getBTerms()) { - /* - This check does NOT need to exist. It's here - to help validate the implementation from the - beginning where there are not IO Clusters anymore. - */ - if (tree_->maps.bterm_to_cluster_id.find(bterm) - == tree_->maps.bterm_to_cluster_id.end()) { - debug_ignore = true; - break; - } - const int cluster_id = tree_->maps.bterm_to_cluster_id.at(bterm); net_has_io_pin = true; @@ -1683,10 +1659,6 @@ void ClusteringEngine::updateConnections() } } - if (debug_ignore) { - continue; - } - if (driver_cluster_id != -1 && !load_clusters_ids.empty() && load_clusters_ids.size() < tree_->large_net_threshold) { const float weight = net_has_io_pin ? tree_->virtual_weight : 1.0; diff --git a/src/mpl2/src/clusterEngine.h b/src/mpl2/src/clusterEngine.h index 31672b2f548..c30d87f27f1 100644 --- a/src/mpl2/src/clusterEngine.h +++ b/src/mpl2/src/clusterEngine.h @@ -185,7 +185,8 @@ class ClusteringEngine const odb::Rect& constraint_region); void createIOCluster(const odb::Rect& die, const Boundary constraint_boundary, - std::map& boundary_to_cluster); + std::map& boundary_to_cluster, + odb::dbBTerm* bterm); void setIoConstraintsClustersDimensions(const odb::Rect& die, const Boundary boundary, int& x, diff --git a/src/mpl2/src/graphics.cpp b/src/mpl2/src/graphics.cpp index b94c46d18cb..57d2f4987c3 100644 --- a/src/mpl2/src/graphics.cpp +++ b/src/mpl2/src/graphics.cpp @@ -361,6 +361,16 @@ void Graphics::drawObjects(gui::Painter& painter) int i = 0; for (const auto& macro : soft_macros_) { + Cluster* cluster = macro.getCluster(); + + if (!cluster) { + continue; + } + + if (cluster->isIOCluster()) { + continue; + } + setSoftMacroBrush(painter, macro); const int lx = block_->micronsToDbu(macro.getX()); From f2daf82cc3007c044302e4d3afa92527424f0c9b Mon Sep 17 00:00:00 2001 From: Arthur Koucher Date: Thu, 12 Sep 2024 15:49:41 -0300 Subject: [PATCH 05/38] mpl2: support to identify io cluster through soft macro Signed-off-by: Arthur Koucher --- src/mpl2/src/object.cpp | 9 +++++++++ src/mpl2/src/object.h | 1 + 2 files changed, 10 insertions(+) diff --git a/src/mpl2/src/object.cpp b/src/mpl2/src/object.cpp index 4354f6c151d..82a5c817433 100644 --- a/src/mpl2/src/object.cpp +++ b/src/mpl2/src/object.cpp @@ -1352,6 +1352,15 @@ bool SoftMacro::isMixedCluster() const return (cluster_->getClusterType() == MixedCluster); } +bool SoftMacro::isIOCluster() const +{ + if (!cluster_) { + return false; + } + + return cluster_->isIOCluster(); +} + void SoftMacro::setLocationF(float x, float y) { x_ = x; diff --git a/src/mpl2/src/object.h b/src/mpl2/src/object.h index 369f3e3182a..dd3cde12e28 100644 --- a/src/mpl2/src/object.h +++ b/src/mpl2/src/object.h @@ -539,6 +539,7 @@ class SoftMacro bool isMacroCluster() const; bool isStdCellCluster() const; bool isMixedCluster() const; + bool isIOCluster() const; void setLocationF(float x, float y); void setShapeF(float width, float height); int getNumMacro() const; From daf4647c327dfce4aa407c8196c5ecc81a1c859c Mon Sep 17 00:00:00 2001 From: Arthur Koucher Date: Thu, 12 Sep 2024 16:27:38 -0300 Subject: [PATCH 06/38] mpl2: add support to identify if a fixed terminal is an IO during Hard SA Signed-off-by: Arthur Koucher --- src/mpl2/src/object.cpp | 11 +++++++++++ src/mpl2/src/object.h | 1 + 2 files changed, 12 insertions(+) diff --git a/src/mpl2/src/object.cpp b/src/mpl2/src/object.cpp index 82a5c817433..2ec73f9ce5c 100644 --- a/src/mpl2/src/object.cpp +++ b/src/mpl2/src/object.cpp @@ -859,6 +859,17 @@ bool HardMacro::operator==(const HardMacro& macro) const return (width_ == macro.width_) && (height_ == macro.height_); } +// Cluster support to identify if a fixed terminal correponds +// to an IO cluster when running HardMacro SA. +bool HardMacro::isIOCluster() const +{ + if (!cluster_) { + return false; + } + + return cluster_->isIOCluster(); +} + // Get Physical Information // Note that the default X and Y include halo_width void HardMacro::setLocation(const std::pair& location) diff --git a/src/mpl2/src/object.h b/src/mpl2/src/object.h index dd3cde12e28..4d667047a65 100644 --- a/src/mpl2/src/object.h +++ b/src/mpl2/src/object.h @@ -361,6 +361,7 @@ class HardMacro void setCluster(Cluster* cluster) { cluster_ = cluster; } Cluster* getCluster() const { return cluster_; } + bool isIOCluster() const; // Get Physical Information // Note that the default X and Y include halo_width From a3a614a97fc6a99ebaa1bf55c84556dfe27dbfe3 Mon Sep 17 00:00:00 2001 From: Arthur Koucher Date: Thu, 12 Sep 2024 19:58:03 -0300 Subject: [PATCH 07/38] mpl2: getter for constraint boundary Signed-off-by: Arthur Koucher --- src/mpl2/src/object.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/mpl2/src/object.h b/src/mpl2/src/object.h index 4d667047a65..deaf970dc41 100644 --- a/src/mpl2/src/object.h +++ b/src/mpl2/src/object.h @@ -205,6 +205,8 @@ class Cluster float height, Boundary constraint_boundary); bool isIOCluster() const; + Boundary getConstraintBoundary() const { return constraint_boundary_; } + void setAsArrayOfInterconnectedMacros(); bool isArrayOfInterconnectedMacros() const; bool isEmpty() const; From 2f6cbfc56336c5b3c60420693457a37078d90924 Mon Sep 17 00:00:00 2001 From: Arthur Koucher Date: Thu, 12 Sep 2024 20:03:48 -0300 Subject: [PATCH 08/38] mpl2: add constraint boundary dist to WL computation in SA Signed-off-by: Arthur Koucher --- src/mpl2/src/SimulatedAnnealingCore.cpp | 46 +++++++++++++++++++++++++ src/mpl2/src/SimulatedAnnealingCore.h | 3 ++ 2 files changed, 49 insertions(+) diff --git a/src/mpl2/src/SimulatedAnnealingCore.cpp b/src/mpl2/src/SimulatedAnnealingCore.cpp index c112eda826f..6555377f72f 100644 --- a/src/mpl2/src/SimulatedAnnealingCore.cpp +++ b/src/mpl2/src/SimulatedAnnealingCore.cpp @@ -272,6 +272,19 @@ void SimulatedAnnealingCore::calWirelength() } for (const auto& net : nets_) { + T& source = macros_[net.terminals.first]; + T& target = macros_[net.terminals.second]; + + /* + TO DO: See if this can't be a single cal + (ios may be always in first or second) + */ + if (source.isIOCluster()) { + addBoundaryDistToWirelength(target, source, net.weight); + } else if (target.isIOCluster()) { + addBoundaryDistToWirelength(source, target, net.weight); + } + const float x1 = macros_[net.terminals.first].getPinX(); const float y1 = macros_[net.terminals.first].getPinY(); const float x2 = macros_[net.terminals.second].getPinX(); @@ -288,6 +301,39 @@ void SimulatedAnnealingCore::calWirelength() } } +/* + TO DO: test this +*/ +template +void SimulatedAnnealingCore::addBoundaryDistToWirelength( + const T& macro, + const T& io, + const float net_weight) +{ + Cluster* io_cluster = io.getCluster(); + const Boundary constraint_boundary = io_cluster->getConstraintBoundary(); + + const float x1 = macro.getPinX(); + const float y1 = macro.getPinY(); + + if (constraint_boundary == NONE) { + const Rect die = io_cluster->getBBox(); + + const float dist_to_left = std::abs(x1 - die.xMin()); + const float dist_to_right = std::abs(x1 - die.xMax()); + const float dist_to_bottom = std::abs(y1 - die.yMin()); + const float dist_to_top = std::abs(y1 - die.yMax()); + + wirelength_ + += std::min({dist_to_left, dist_to_right, dist_to_bottom, dist_to_top}); + } else { + const float x2 = io.getPinX(); + const float y2 = io.getPinY(); + + wirelength_ += net_weight * std::min(std::abs(y2 - y1), std::abs(x2 - x1)); + } +} + template void SimulatedAnnealingCore::calFencePenalty() { diff --git a/src/mpl2/src/SimulatedAnnealingCore.h b/src/mpl2/src/SimulatedAnnealingCore.h index 825a5a399bf..fd1d0f9107d 100644 --- a/src/mpl2/src/SimulatedAnnealingCore.h +++ b/src/mpl2/src/SimulatedAnnealingCore.h @@ -137,6 +137,9 @@ class SimulatedAnnealingCore virtual void calPenalty() = 0; void calOutlinePenalty(); void calWirelength(); + void addBoundaryDistToWirelength(const T& macro, + const T& io, + float net_weight); void calGuidancePenalty(); void calFencePenalty(); From 8cc4c0f89782df5c961f6f690c0206e29bfff7e2 Mon Sep 17 00:00:00 2001 From: Arthur Koucher Date: Fri, 13 Sep 2024 18:14:37 -0300 Subject: [PATCH 09/38] mpl2: begin debug support for new io clusters Signed-off-by: Arthur Koucher --- src/mpl2/src/graphics.cpp | 142 ++++++++++++++++++++++++++++++++++---- src/mpl2/src/graphics.h | 9 +++ 2 files changed, 138 insertions(+), 13 deletions(-) diff --git a/src/mpl2/src/graphics.cpp b/src/mpl2/src/graphics.cpp index 57d2f4987c3..416b9f86c90 100644 --- a/src/mpl2/src/graphics.cpp +++ b/src/mpl2/src/graphics.cpp @@ -482,27 +482,143 @@ void Graphics::drawBundledNets(gui::Painter& painter, const std::vector& macros) { for (const auto& bundled_net : bundled_nets_) { - const int x1 - = block_->micronsToDbu(macros[bundled_net.terminals.first].getPinX()); - const int y1 - = block_->micronsToDbu(macros[bundled_net.terminals.first].getPinY()); + const T& source = macros[bundled_net.terminals.first]; + const T& target = macros[bundled_net.terminals.second]; + + if (target.isIOCluster()) { + drawDistToIoConstraintBoundary(painter, source, target); + continue; + } + + const int x1 = block_->micronsToDbu(source.getPinX()); + const int y1 = block_->micronsToDbu(source.getPinY()); odb::Point from(x1, y1); - const int x2 - = block_->micronsToDbu(macros[bundled_net.terminals.second].getPinX()); - const int y2 - = block_->micronsToDbu(macros[bundled_net.terminals.second].getPinY()); + const int x2 = block_->micronsToDbu(target.getPinX()); + const int y2 = block_->micronsToDbu(target.getPinY()); odb::Point to(x2, y2); - from.addX(outline_.xMin()); - from.addY(outline_.yMin()); - to.addX(outline_.xMin()); - to.addY(outline_.yMin()); - + addOutlineOffsetToLine(from, to); painter.drawLine(from, to); } } +template +void Graphics::drawDistToIoConstraintBoundary(gui::Painter& painter, + const T& macro, + const T& io) +{ + Cluster* io_cluster = io.getCluster(); + + const int x1 = block_->micronsToDbu(macro.getPinX()); + const int y1 = block_->micronsToDbu(macro.getPinY()); + odb::Point from(x1, y1); + + odb::Point to; + Boundary constraint_boundary = io_cluster->getConstraintBoundary(); + + if (constraint_boundary == Boundary::L + || constraint_boundary == Boundary::R) { + const int x2 = block_->micronsToDbu(io.getPinX()); + const int y2 = block_->micronsToDbu(macro.getPinY()); + to.setX(x2); + to.setY(y2); + } else if (constraint_boundary == Boundary::B + || constraint_boundary == Boundary::T) { + const int x2 = block_->micronsToDbu(macro.getPinX()); + const int y2 = block_->micronsToDbu(io.getPinY()); + to.setX(x2); + to.setY(y2); + } else { + to = getClosestBoundaryPoint(macro, io_cluster); + } + + addOutlineOffsetToLine(from, to); + + painter.drawLine(from, to); + painter.drawString(to.getX(), + to.getY(), + gui::Painter::CENTER, + toString(constraint_boundary)); +} + +template +odb::Point Graphics::getClosestBoundaryPoint(const T& macro, + Cluster* io_cluster) +{ + // For NONE, the shape of the io cluster is the die area. + const Rect die = io_cluster->getBBox(); + Boundary closest_boundary = getClosestBoundary(macro, die); + odb::Point to; + + /* + TO DO: + 1. See if some sort of offset dark magic interferes + with the annealing internals. + 2. Guarantee that when the macros are outside the + outline we'll have no problems. + */ + + // We have to manually decompensate the offset of the coordinate + // that comes from the cluster. + if (closest_boundary == Boundary::L) { + to.setX(block_->micronsToDbu(die.xMin())); + to.setY(block_->micronsToDbu(macro.getPinY())); + to.addX(-outline_.xMin()); + } else if (closest_boundary == Boundary::R) { + to.setX(block_->micronsToDbu(die.xMax())); + to.setY(block_->micronsToDbu(macro.getPinY())); + to.addX(-outline_.xMin()); + } else if (closest_boundary == Boundary::B) { + to.setX(block_->micronsToDbu(macro.getPinX())); + to.setY(block_->micronsToDbu(die.yMin())); + to.addY(-outline_.yMin()); + } else { // Top + to.setX(block_->micronsToDbu(macro.getPinX())); + to.setY(block_->micronsToDbu(die.yMax())); + to.addY(-outline_.yMin()); + } + + return to; +} + +void Graphics::addOutlineOffsetToLine(odb::Point& from, odb::Point& to) +{ + from.addX(outline_.xMin()); + from.addY(outline_.yMin()); + to.addX(outline_.xMin()); + to.addY(outline_.yMin()); +} + +template +Boundary Graphics::getClosestBoundary(const T& macro, const Rect& die) +{ + const float macro_x = macro.getPinX(); + const float macro_y = macro.getPinY(); + + const float dist_to_left = std::abs(macro_x - die.xMin()); + float shortest_distance = dist_to_left; + Boundary closest_boundary = Boundary::L; + + const float dist_to_right = std::abs(macro_x - die.xMax()); + if (dist_to_right < shortest_distance) { + closest_boundary = Boundary::R; + shortest_distance = dist_to_right; + } + + const float dist_to_bottom = std::abs(macro_y - die.yMin()); + if (dist_to_bottom < shortest_distance) { + closest_boundary = Boundary::B; + } + + const float dist_to_top = std::abs(macro_y - die.yMax()); + if (dist_to_top < shortest_distance) { + closest_boundary = Boundary::T; + } + + return closest_boundary; +} + // Give some transparency to mixed and hard so we can see overlap with // macro blockages. void Graphics::setSoftMacroBrush(gui::Painter& painter, diff --git a/src/mpl2/src/graphics.h b/src/mpl2/src/graphics.h index a7f329faabb..f5ea443172e 100644 --- a/src/mpl2/src/graphics.h +++ b/src/mpl2/src/graphics.h @@ -96,6 +96,15 @@ class Graphics : public gui::Renderer, public Mpl2Observer void drawBlockage(const Rect& blockage, gui::Painter& painter); template void drawBundledNets(gui::Painter& painter, const std::vector& macros); + template + void drawDistToIoConstraintBoundary(gui::Painter& painter, + const T& macro, + const T& io); + template + odb::Point getClosestBoundaryPoint(const T& macro, Cluster* io_cluster); + template + Boundary getClosestBoundary(const T& macro, const Rect& die); + void addOutlineOffsetToLine(odb::Point& from, odb::Point& to); void setSoftMacroBrush(gui::Painter& painter, const SoftMacro& soft_macro); void fetchSoftAndHard(Cluster* parent, std::vector& hard, From cf50ff25ee93f74a315d56c3202acd4206c9bb8b Mon Sep 17 00:00:00 2001 From: Arthur Koucher Date: Fri, 13 Sep 2024 18:21:12 -0300 Subject: [PATCH 10/38] mpl2: comment problem Signed-off-by: Arthur Koucher --- src/mpl2/src/SimulatedAnnealingCore.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/mpl2/src/SimulatedAnnealingCore.cpp b/src/mpl2/src/SimulatedAnnealingCore.cpp index 6555377f72f..e20254b6bd1 100644 --- a/src/mpl2/src/SimulatedAnnealingCore.cpp +++ b/src/mpl2/src/SimulatedAnnealingCore.cpp @@ -330,6 +330,9 @@ void SimulatedAnnealingCore::addBoundaryDistToWirelength( const float x2 = io.getPinX(); const float y2 = io.getPinY(); + /* + TO DO: This is just wrong. We need to see X dist for L || R , Y dist for T || B + */ wirelength_ += net_weight * std::min(std::abs(y2 - y1), std::abs(x2 - x1)); } } From bb4b51bff86a16da9f8f3d201d0be6747c74f5c9 Mon Sep 17 00:00:00 2001 From: Arthur Koucher Date: Mon, 16 Sep 2024 17:20:10 -0300 Subject: [PATCH 11/38] mpl2: fix constraints' dist computation Signed-off-by: Arthur Koucher --- src/mpl2/src/SimulatedAnnealingCore.cpp | 14 ++++++++------ src/mpl2/src/hier_rtlmp.cpp | 10 ++++++++++ 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/src/mpl2/src/SimulatedAnnealingCore.cpp b/src/mpl2/src/SimulatedAnnealingCore.cpp index e20254b6bd1..f95ff492750 100644 --- a/src/mpl2/src/SimulatedAnnealingCore.cpp +++ b/src/mpl2/src/SimulatedAnnealingCore.cpp @@ -324,16 +324,18 @@ void SimulatedAnnealingCore::addBoundaryDistToWirelength( const float dist_to_bottom = std::abs(y1 - die.yMin()); const float dist_to_top = std::abs(y1 - die.yMax()); + /* + TO DO: consider net weight + */ wirelength_ += std::min({dist_to_left, dist_to_right, dist_to_bottom, dist_to_top}); - } else { + } else if (constraint_boundary == Boundary::L + || constraint_boundary == Boundary::R) { const float x2 = io.getPinX(); + wirelength_ += net_weight * std::abs(x2 - x1); + } else { // Top or Bottom const float y2 = io.getPinY(); - - /* - TO DO: This is just wrong. We need to see X dist for L || R , Y dist for T || B - */ - wirelength_ += net_weight * std::min(std::abs(y2 - y1), std::abs(x2 - x1)); + wirelength_ += net_weight * std::abs(y2 - y1); } } diff --git a/src/mpl2/src/hier_rtlmp.cpp b/src/mpl2/src/hier_rtlmp.cpp index 9406e74a91c..b735de04264 100644 --- a/src/mpl2/src/hier_rtlmp.cpp +++ b/src/mpl2/src/hier_rtlmp.cpp @@ -219,6 +219,16 @@ void HierRTLMP::setReportDirectory(const char* report_directory) report_directory_ = report_directory; } +/* + TO DO: + 1. Remove all "bundledIO related things" + 2. Add IO count to preamble and display it in the tree for + clustering debug level + 3. See how are we going to make sure that the orientantion + improvement does the right thing, now that we don't have + placed pins? +*/ + // Top Level Function // The flow of our MacroPlacer is divided into 6 stages. // 1) Multilevel Autoclustering: From cea8774c9e049521d2ef4c2744792e0aa73ead66 Mon Sep 17 00:00:00 2001 From: Arthur Koucher Date: Mon, 16 Sep 2024 19:13:50 -0300 Subject: [PATCH 12/38] mpl2: add to do's Signed-off-by: Arthur Koucher --- src/mpl2/src/SimulatedAnnealingCore.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/mpl2/src/SimulatedAnnealingCore.cpp b/src/mpl2/src/SimulatedAnnealingCore.cpp index f95ff492750..5340878be7a 100644 --- a/src/mpl2/src/SimulatedAnnealingCore.cpp +++ b/src/mpl2/src/SimulatedAnnealingCore.cpp @@ -310,6 +310,11 @@ void SimulatedAnnealingCore::addBoundaryDistToWirelength( const T& io, const float net_weight) { + /* + TO DO: check if the macro is inside the outline, if not, + use HPWL of the die are as penalty to guide SA. + */ + Cluster* io_cluster = io.getCluster(); const Boundary constraint_boundary = io_cluster->getConstraintBoundary(); @@ -319,6 +324,11 @@ void SimulatedAnnealingCore::addBoundaryDistToWirelength( if (constraint_boundary == NONE) { const Rect die = io_cluster->getBBox(); + /* + TO DO: Use information of which boundary is forbidden based on + the global exclude constraints for the edges + */ + const float dist_to_left = std::abs(x1 - die.xMin()); const float dist_to_right = std::abs(x1 - die.xMax()); const float dist_to_bottom = std::abs(y1 - die.yMin()); From eb5e3316a7a2efa1956ee591f9e212fb970be4f7 Mon Sep 17 00:00:00 2001 From: Arthur Koucher Date: Tue, 17 Sep 2024 12:05:59 -0300 Subject: [PATCH 13/38] mpl2: 1) avoid computing WL twice for IO cases 2) add fixed penalty for IO connections when the macro is outside the outline 3) don't draw dist to edge in graphics when macro is outside the outline Signed-off-by: Arthur Koucher --- src/mpl2/src/SimulatedAnnealingCore.cpp | 28 +++++++++++++++++++++---- src/mpl2/src/SimulatedAnnealingCore.h | 1 + src/mpl2/src/graphics.cpp | 11 ++++++++++ src/mpl2/src/graphics.h | 2 ++ 4 files changed, 38 insertions(+), 4 deletions(-) diff --git a/src/mpl2/src/SimulatedAnnealingCore.cpp b/src/mpl2/src/SimulatedAnnealingCore.cpp index 5340878be7a..ef4e6c75dd1 100644 --- a/src/mpl2/src/SimulatedAnnealingCore.cpp +++ b/src/mpl2/src/SimulatedAnnealingCore.cpp @@ -281,8 +281,12 @@ void SimulatedAnnealingCore::calWirelength() */ if (source.isIOCluster()) { addBoundaryDistToWirelength(target, source, net.weight); - } else if (target.isIOCluster()) { + continue; + } + + if (target.isIOCluster()) { addBoundaryDistToWirelength(source, target, net.weight); + continue; } const float x1 = macros_[net.terminals.first].getPinX(); @@ -314,16 +318,23 @@ void SimulatedAnnealingCore::addBoundaryDistToWirelength( TO DO: check if the macro is inside the outline, if not, use HPWL of the die are as penalty to guide SA. */ - Cluster* io_cluster = io.getCluster(); + const Rect die = io_cluster->getBBox(); + + if (isOutsideTheOutline(macro)) { + // Add a fixed penalty based on the die dimensions so that we + // can assume the macro is inside the outline when computing + // the distance to the edges. + wirelength_ = net_weight * die.getWidth() * die.getHeight(); + return; + } + const Boundary constraint_boundary = io_cluster->getConstraintBoundary(); const float x1 = macro.getPinX(); const float y1 = macro.getPinY(); if (constraint_boundary == NONE) { - const Rect die = io_cluster->getBBox(); - /* TO DO: Use information of which boundary is forbidden based on the global exclude constraints for the edges @@ -349,6 +360,15 @@ void SimulatedAnnealingCore::addBoundaryDistToWirelength( } } +// We consider the macro outside the outline based on the location of +// the pin to avoid too many checks. +template +bool SimulatedAnnealingCore::isOutsideTheOutline(const T& macro) const +{ + return macro.getPinX() > outline_.getWidth() + || macro.getPinY() > outline_.getHeight(); +} + template void SimulatedAnnealingCore::calFencePenalty() { diff --git a/src/mpl2/src/SimulatedAnnealingCore.h b/src/mpl2/src/SimulatedAnnealingCore.h index fd1d0f9107d..5da1a86c52d 100644 --- a/src/mpl2/src/SimulatedAnnealingCore.h +++ b/src/mpl2/src/SimulatedAnnealingCore.h @@ -140,6 +140,7 @@ class SimulatedAnnealingCore void addBoundaryDistToWirelength(const T& macro, const T& io, float net_weight); + bool isOutsideTheOutline(const T& macro) const; void calGuidancePenalty(); void calFencePenalty(); diff --git a/src/mpl2/src/graphics.cpp b/src/mpl2/src/graphics.cpp index 416b9f86c90..929fc13ce80 100644 --- a/src/mpl2/src/graphics.cpp +++ b/src/mpl2/src/graphics.cpp @@ -508,6 +508,10 @@ void Graphics::drawDistToIoConstraintBoundary(gui::Painter& painter, const T& macro, const T& io) { + if (isOutsideTheOutline(macro)) { + return; + } + Cluster* io_cluster = io.getCluster(); const int x1 = block_->micronsToDbu(macro.getPinX()); @@ -542,6 +546,13 @@ void Graphics::drawDistToIoConstraintBoundary(gui::Painter& painter, toString(constraint_boundary)); } +template +bool Graphics::isOutsideTheOutline(const T& macro) const +{ + return block_->micronsToDbu(macro.getPinX()) > outline_.dx() + || block_->micronsToDbu(macro.getPinY()) > outline_.dy(); +} + template odb::Point Graphics::getClosestBoundaryPoint(const T& macro, Cluster* io_cluster) diff --git a/src/mpl2/src/graphics.h b/src/mpl2/src/graphics.h index f5ea443172e..0a6cc8f3258 100644 --- a/src/mpl2/src/graphics.h +++ b/src/mpl2/src/graphics.h @@ -101,6 +101,8 @@ class Graphics : public gui::Renderer, public Mpl2Observer const T& macro, const T& io); template + bool isOutsideTheOutline(const T& macro) const; + template odb::Point getClosestBoundaryPoint(const T& macro, Cluster* io_cluster); template Boundary getClosestBoundary(const T& macro, const Rect& die); From c29030103a591236a3ebcd1d54c637bd73a6a70a Mon Sep 17 00:00:00 2001 From: Arthur Koucher Date: Tue, 17 Sep 2024 12:06:54 -0300 Subject: [PATCH 14/38] mpl2: consider net weight when computing min dist to closest edge Signed-off-by: Arthur Koucher --- src/mpl2/src/SimulatedAnnealingCore.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/mpl2/src/SimulatedAnnealingCore.cpp b/src/mpl2/src/SimulatedAnnealingCore.cpp index ef4e6c75dd1..95293a33fa9 100644 --- a/src/mpl2/src/SimulatedAnnealingCore.cpp +++ b/src/mpl2/src/SimulatedAnnealingCore.cpp @@ -345,11 +345,10 @@ void SimulatedAnnealingCore::addBoundaryDistToWirelength( const float dist_to_bottom = std::abs(y1 - die.yMin()); const float dist_to_top = std::abs(y1 - die.yMax()); - /* - TO DO: consider net weight - */ wirelength_ - += std::min({dist_to_left, dist_to_right, dist_to_bottom, dist_to_top}); + += net_weight + * std::min( + {dist_to_left, dist_to_right, dist_to_bottom, dist_to_top}); } else if (constraint_boundary == Boundary::L || constraint_boundary == Boundary::R) { const float x2 = io.getPinX(); From b9f124e73dded73205a335aa5bf9435e09c1b0fa Mon Sep 17 00:00:00 2001 From: Arthur Koucher Date: Tue, 17 Sep 2024 12:07:29 -0300 Subject: [PATCH 15/38] mpl2: remove comment Signed-off-by: Arthur Koucher --- src/mpl2/src/SimulatedAnnealingCore.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/mpl2/src/SimulatedAnnealingCore.cpp b/src/mpl2/src/SimulatedAnnealingCore.cpp index 95293a33fa9..53641f65be4 100644 --- a/src/mpl2/src/SimulatedAnnealingCore.cpp +++ b/src/mpl2/src/SimulatedAnnealingCore.cpp @@ -314,10 +314,6 @@ void SimulatedAnnealingCore::addBoundaryDistToWirelength( const T& io, const float net_weight) { - /* - TO DO: check if the macro is inside the outline, if not, - use HPWL of the die are as penalty to guide SA. - */ Cluster* io_cluster = io.getCluster(); const Rect die = io_cluster->getBBox(); From 69b3212c171ea5e91792bf2e0def6fcea9320f9a Mon Sep 17 00:00:00 2001 From: Arthur Koucher Date: Tue, 17 Sep 2024 13:31:22 -0300 Subject: [PATCH 16/38] mpl2: renaming Signed-off-by: Arthur Koucher --- src/mpl2/src/clusterEngine.cpp | 16 +++++++--------- src/mpl2/src/clusterEngine.h | 2 +- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/src/mpl2/src/clusterEngine.cpp b/src/mpl2/src/clusterEngine.cpp index f980eaad61b..adfe2fa24cf 100644 --- a/src/mpl2/src/clusterEngine.cpp +++ b/src/mpl2/src/clusterEngine.cpp @@ -399,8 +399,7 @@ void ClusteringEngine::createIOCluster( int width = die.dx(), height = die.dy(); if (constraint_boundary != NONE) { - setIoConstraintsClustersDimensions( - die, constraint_boundary, x, y, width, height); + setIOClusterDimensions(die, constraint_boundary, x, y, width, height); } cluster->setAsIOCluster( @@ -411,13 +410,12 @@ void ClusteringEngine::createIOCluster( tree_->root->addChild(std::move(cluster)); } -void ClusteringEngine::setIoConstraintsClustersDimensions( - const odb::Rect& die, - const Boundary boundary, - int& x, - int& y, - int& width, - int& height) +void ClusteringEngine::setIOClusterDimensions(const odb::Rect& die, + const Boundary boundary, + int& x, + int& y, + int& width, + int& height) { if (boundary == L) { x = die.xMin(); diff --git a/src/mpl2/src/clusterEngine.h b/src/mpl2/src/clusterEngine.h index c30d87f27f1..9c338e1c9e5 100644 --- a/src/mpl2/src/clusterEngine.h +++ b/src/mpl2/src/clusterEngine.h @@ -187,7 +187,7 @@ class ClusteringEngine const Boundary constraint_boundary, std::map& boundary_to_cluster, odb::dbBTerm* bterm); - void setIoConstraintsClustersDimensions(const odb::Rect& die, + void setIOClusterDimensions(const odb::Rect& die, const Boundary boundary, int& x, int& y, From a4ffc66eb8f3f331708cbf932af7bb1015a3ec64 Mon Sep 17 00:00:00 2001 From: Arthur Koucher Date: Wed, 18 Sep 2024 20:04:52 +0000 Subject: [PATCH 17/38] mpl2: make tree data accessible inside core Signed-off-by: Arthur Koucher --- src/mpl2/src/SACoreHardMacro.cpp | 4 +++- src/mpl2/src/SACoreHardMacro.h | 3 ++- src/mpl2/src/SACoreSoftMacro.cpp | 7 ++++--- src/mpl2/src/SACoreSoftMacro.h | 2 +- src/mpl2/src/SimulatedAnnealingCore.cpp | 1 + src/mpl2/src/SimulatedAnnealingCore.h | 2 ++ src/mpl2/src/hier_rtlmp.cpp | 19 +++++++++++-------- 7 files changed, 24 insertions(+), 14 deletions(-) diff --git a/src/mpl2/src/SACoreHardMacro.cpp b/src/mpl2/src/SACoreHardMacro.cpp index c259fb0789f..7ea1ae4ad5f 100644 --- a/src/mpl2/src/SACoreHardMacro.cpp +++ b/src/mpl2/src/SACoreHardMacro.cpp @@ -43,6 +43,7 @@ using utl::MPL; // Class SACoreHardMacro // constructors SACoreHardMacro::SACoreHardMacro( + PhysicalHierarchy* tree, const Rect& outline, const std::vector& macros, // weight for different penalty @@ -64,7 +65,8 @@ SACoreHardMacro::SACoreHardMacro( unsigned seed, Mpl2Observer* graphics, utl::Logger* logger) - : SimulatedAnnealingCore(outline, + : SimulatedAnnealingCore(tree, + outline, macros, area_weight, outline_weight, diff --git a/src/mpl2/src/SACoreHardMacro.h b/src/mpl2/src/SACoreHardMacro.h index df10be953ff..46d76c964ff 100644 --- a/src/mpl2/src/SACoreHardMacro.h +++ b/src/mpl2/src/SACoreHardMacro.h @@ -49,7 +49,8 @@ namespace mpl2 { class SACoreHardMacro : public SimulatedAnnealingCore { public: - SACoreHardMacro(const Rect& outline, + SACoreHardMacro(PhysicalHierarchy* tree, + const Rect& outline, const std::vector& macros, // weight for different penalty float area_weight, diff --git a/src/mpl2/src/SACoreSoftMacro.cpp b/src/mpl2/src/SACoreSoftMacro.cpp index 23ba1b83070..0b4145f86d8 100644 --- a/src/mpl2/src/SACoreSoftMacro.cpp +++ b/src/mpl2/src/SACoreSoftMacro.cpp @@ -43,7 +43,7 @@ using utl::MPL; // Class SACoreSoftMacro // constructors SACoreSoftMacro::SACoreSoftMacro( - Cluster* root, + PhysicalHierarchy* tree, const Rect& outline, const std::vector& macros, // weight for different penalty @@ -71,7 +71,8 @@ SACoreSoftMacro::SACoreSoftMacro( unsigned seed, Mpl2Observer* graphics, utl::Logger* logger) - : SimulatedAnnealingCore(outline, + : SimulatedAnnealingCore(tree, + outline, macros, area_weight, outline_weight, @@ -88,7 +89,7 @@ SACoreSoftMacro::SACoreSoftMacro( seed, graphics, logger), - root_(root) + root_(tree->root.get()) { boundary_weight_ = boundary_weight; macro_blockage_weight_ = macro_blockage_weight; diff --git a/src/mpl2/src/SACoreSoftMacro.h b/src/mpl2/src/SACoreSoftMacro.h index 1810ec5db5a..de9f4b110c5 100644 --- a/src/mpl2/src/SACoreSoftMacro.h +++ b/src/mpl2/src/SACoreSoftMacro.h @@ -50,7 +50,7 @@ class Graphics; class SACoreSoftMacro : public SimulatedAnnealingCore { public: - SACoreSoftMacro(Cluster* root, + SACoreSoftMacro(PhysicalHierarchy* tree, const Rect& outline, const std::vector& macros, // weight for different penalty diff --git a/src/mpl2/src/SimulatedAnnealingCore.cpp b/src/mpl2/src/SimulatedAnnealingCore.cpp index 53641f65be4..077ee3f8ac4 100644 --- a/src/mpl2/src/SimulatedAnnealingCore.cpp +++ b/src/mpl2/src/SimulatedAnnealingCore.cpp @@ -48,6 +48,7 @@ using std::string; // Class SimulatedAnnealingCore template SimulatedAnnealingCore::SimulatedAnnealingCore( + PhysicalHierarchy* tree, const Rect& outline, // boundary constraints const std::vector& macros, // macros (T = HardMacro or T = SoftMacro) // weight for different penalty diff --git a/src/mpl2/src/SimulatedAnnealingCore.h b/src/mpl2/src/SimulatedAnnealingCore.h index 5da1a86c52d..fda2a58bdef 100644 --- a/src/mpl2/src/SimulatedAnnealingCore.h +++ b/src/mpl2/src/SimulatedAnnealingCore.h @@ -38,6 +38,7 @@ #include #include "Mpl2Observer.h" +#include "clusterEngine.h" namespace utl { class Logger; @@ -68,6 +69,7 @@ class SimulatedAnnealingCore { public: SimulatedAnnealingCore( + PhysicalHierarchy* tree, const Rect& outline, // boundary constraints const std::vector& macros, // macros (T = HardMacro or T = SoftMacro) // weight for different penalty diff --git a/src/mpl2/src/hier_rtlmp.cpp b/src/mpl2/src/hier_rtlmp.cpp index b735de04264..1fa57ed2eb3 100644 --- a/src/mpl2/src/hier_rtlmp.cpp +++ b/src/mpl2/src/hier_rtlmp.cpp @@ -521,7 +521,7 @@ void HierRTLMP::calculateChildrenTilings(Cluster* parent) graphics_->setOutline(micronsToDbu(new_outline)); } std::unique_ptr sa - = std::make_unique(tree_->root.get(), + = std::make_unique(tree_.get(), new_outline, macros, 1.0, // area weight @@ -585,7 +585,7 @@ void HierRTLMP::calculateChildrenTilings(Cluster* parent) graphics_->setOutline(micronsToDbu(new_outline)); } std::unique_ptr sa - = std::make_unique(tree_->root.get(), + = std::make_unique(tree_.get(), new_outline, macros, 1.0, // area weight @@ -756,7 +756,8 @@ void HierRTLMP::calculateMacroTilings(Cluster* cluster) graphics_->setOutline(micronsToDbu(new_outline)); } std::unique_ptr sa - = std::make_unique(new_outline, + = std::make_unique(tree_.get(), + new_outline, macros, 1.0, // area_weight 1000.0, // outline weight @@ -814,7 +815,8 @@ void HierRTLMP::calculateMacroTilings(Cluster* cluster) graphics_->setOutline(micronsToDbu(new_outline)); } std::unique_ptr sa - = std::make_unique(new_outline, + = std::make_unique(tree_.get(), + new_outline, macros, 1.0, // area_weight 1000.0, // outline weight @@ -1667,7 +1669,7 @@ void HierRTLMP::runHierarchicalMacroPlacement(Cluster* parent) // Note that the weight are not necessaries summarized to 1.0, i.e., not // normalized. std::unique_ptr sa - = std::make_unique(tree_->root.get(), + = std::make_unique(tree_.get(), outline, shaped_macros, area_weight_, @@ -1925,7 +1927,7 @@ void HierRTLMP::runHierarchicalMacroPlacement(Cluster* parent) // of 1.0. Note that the weight are not necessaries summarized to 1.0, // i.e., not normalized. std::unique_ptr sa = std::make_unique( - tree_->root.get(), + tree_.get(), outline, shaped_macros, area_weight_, @@ -2497,7 +2499,7 @@ void HierRTLMP::runHierarchicalMacroPlacementWithoutBusPlanning(Cluster* parent) // Note that the weight are not necessaries summarized to 1.0, i.e., not // normalized. std::unique_ptr sa - = std::make_unique(tree_->root.get(), + = std::make_unique(tree_.get(), outline, shaped_macros, area_weight_, @@ -2979,7 +2981,7 @@ void HierRTLMP::runEnhancedHierarchicalMacroPlacement(Cluster* parent) // Note that the weight are not necessaries summarized to 1.0, i.e., not // normalized. std::unique_ptr sa - = std::make_unique(tree_->root.get(), + = std::make_unique(tree_.get(), outline, shaped_macros, area_weight_, @@ -3467,6 +3469,7 @@ void HierRTLMP::placeMacros(Cluster* cluster) } std::unique_ptr sa = std::make_unique( + tree_.get(), outline, sa_macros, area_weight_, From da791bc30af210a898fdc3335e8f852e2aa93bb2 Mon Sep 17 00:00:00 2001 From: Arthur Koucher Date: Thu, 19 Sep 2024 15:41:36 -0300 Subject: [PATCH 18/38] mpl2: set blocked boundaries based on ppl -exclude argument data Signed-off-by: Arthur Koucher --- src/mpl2/src/clusterEngine.cpp | 43 ++++++++++++++++++++++++++++++++++ src/mpl2/src/clusterEngine.h | 15 ++++++++---- 2 files changed, 53 insertions(+), 5 deletions(-) diff --git a/src/mpl2/src/clusterEngine.cpp b/src/mpl2/src/clusterEngine.cpp index adfe2fa24cf..5a76be8cfea 100644 --- a/src/mpl2/src/clusterEngine.cpp +++ b/src/mpl2/src/clusterEngine.cpp @@ -64,6 +64,8 @@ void ClusteringEngine::run() setBaseThresholds(); createIOClusters(); + setBlockedBoundariesForIOs(); + createDataFlow(); if (design_metrics_->getNumStdCell() == 0) { @@ -410,6 +412,47 @@ void ClusteringEngine::createIOCluster( tree_->root->addChild(std::move(cluster)); } +void ClusteringEngine::setBlockedBoundariesForIOs() +{ + const float blocked_boundary_threshold = 0.7; + std::map blockage_extension_map = getBlockageExtensionMap(); + + for (const auto [boundary, blockage_extension] : blockage_extension_map) { + if (blockage_extension >= blocked_boundary_threshold) { + tree_->blocked_boundaries.insert(boundary); + } + } +} + +// Computes how much blocked each boundary is for IOs base on PPL exclude +// contraints. +std::map ClusteringEngine::getBlockageExtensionMap() +{ + std::map blockage_extension_map; + + blockage_extension_map[L] = 0.0; + blockage_extension_map[R] = 0.0; + blockage_extension_map[B] = 0.0; + blockage_extension_map[T] = 0.0; + + const odb::Rect die = block_->getDieArea(); + for (const odb::Rect& blocked_region : block_->getBlockedRegionsForPins()) { + Boundary blocked_region_boundary + = getConstraintBoundary(die, blocked_region); + float blockage_extension = 0.0; + + if (blocked_region_boundary == L || blocked_region_boundary == R) { + blockage_extension = blocked_region.dy() / static_cast(die.dy()); + } else if (blocked_region_boundary == B || blocked_region_boundary == T) { + blockage_extension = blocked_region.dx() / static_cast(die.dx()); + } + + blockage_extension_map[blocked_region_boundary] += blockage_extension; + } + + return blockage_extension_map; +} + void ClusteringEngine::setIOClusterDimensions(const odb::Rect& die, const Boundary boundary, int& x, diff --git a/src/mpl2/src/clusterEngine.h b/src/mpl2/src/clusterEngine.h index 9c338e1c9e5..28e022addab 100644 --- a/src/mpl2/src/clusterEngine.h +++ b/src/mpl2/src/clusterEngine.h @@ -113,6 +113,9 @@ struct PhysicalHierarchy std::unique_ptr root; PhysicalHierarchyMaps maps; + // This is set according to the ppl -exclude constraints + std::set blocked_boundaries; + float halo_width{0.0f}; float halo_height{0.0f}; float macro_with_halo_area{0.0f}; @@ -181,6 +184,8 @@ class ClusteringEngine void createRoot(); void setBaseThresholds(); void createIOClusters(); + void setBlockedBoundariesForIOs(); + std::map getBlockageExtensionMap(); Boundary getConstraintBoundary(const odb::Rect& die, const odb::Rect& constraint_region); void createIOCluster(const odb::Rect& die, @@ -188,11 +193,11 @@ class ClusteringEngine std::map& boundary_to_cluster, odb::dbBTerm* bterm); void setIOClusterDimensions(const odb::Rect& die, - const Boundary boundary, - int& x, - int& y, - int& width, - int& height); + const Boundary boundary, + int& x, + int& y, + int& width, + int& height); void mapIOPads(); void treatEachMacroAsSingleCluster(); void incorporateNewCluster(std::unique_ptr cluster, Cluster* parent); From 9a9cfe4e908291df6c3b925f7c0a43cdce4855a8 Mon Sep 17 00:00:00 2001 From: Arthur Koucher Date: Thu, 19 Sep 2024 17:32:08 -0300 Subject: [PATCH 19/38] mpl2: fix max penalty based on die hpwl and use it when the constraint boundary is blocked Signed-off-by: Arthur Koucher --- src/mpl2/src/SimulatedAnnealingCore.cpp | 55 ++++++++++++++----------- src/mpl2/src/SimulatedAnnealingCore.h | 8 +++- 2 files changed, 37 insertions(+), 26 deletions(-) diff --git a/src/mpl2/src/SimulatedAnnealingCore.cpp b/src/mpl2/src/SimulatedAnnealingCore.cpp index 077ee3f8ac4..51da1d6426f 100644 --- a/src/mpl2/src/SimulatedAnnealingCore.cpp +++ b/src/mpl2/src/SimulatedAnnealingCore.cpp @@ -69,7 +69,9 @@ SimulatedAnnealingCore::SimulatedAnnealingCore( unsigned seed, Mpl2Observer* graphics, utl::Logger* logger) - : outline_(outline), graphics_(graphics) + : outline_(outline), + blocked_boundaries_(tree->blocked_boundaries), + graphics_(graphics) { area_weight_ = area_weight; outline_weight_ = outline_weight; @@ -276,17 +278,29 @@ void SimulatedAnnealingCore::calWirelength() T& source = macros_[net.terminals.first]; T& target = macros_[net.terminals.second]; - /* - TO DO: See if this can't be a single cal - (ios may be always in first or second) - */ - if (source.isIOCluster()) { - addBoundaryDistToWirelength(target, source, net.weight); - continue; - } - if (target.isIOCluster()) { - addBoundaryDistToWirelength(source, target, net.weight); + Cluster* io_cluster = target.getCluster(); + const Rect die = io_cluster->getBBox(); + const float die_hpwl = die.getWidth() + die.getHeight(); + + if (isOutsideTheOutline(source)) { + wirelength_ += net.weight * die_hpwl; + continue; + } + + const Boundary constraint_boundary = io_cluster->getConstraintBoundary(); + const bool constraint_boundary_is_blocked + = blocked_boundaries_.find(constraint_boundary) + != blocked_boundaries_.end(); + + if (constraint_boundary_is_blocked + && constraint_boundary != Boundary::NONE) { + wirelength_ += net.weight * die_hpwl; + continue; + } + + addBoundaryDistToWirelength( + source, target, net.weight, io_cluster, die, constraint_boundary); continue; } @@ -313,25 +327,16 @@ template void SimulatedAnnealingCore::addBoundaryDistToWirelength( const T& macro, const T& io, - const float net_weight) + const float net_weight, + Cluster* io_cluster, + const Rect& die, + Boundary constraint_boundary) { - Cluster* io_cluster = io.getCluster(); - const Rect die = io_cluster->getBBox(); - - if (isOutsideTheOutline(macro)) { - // Add a fixed penalty based on the die dimensions so that we - // can assume the macro is inside the outline when computing - // the distance to the edges. - wirelength_ = net_weight * die.getWidth() * die.getHeight(); - return; - } - - const Boundary constraint_boundary = io_cluster->getConstraintBoundary(); - const float x1 = macro.getPinX(); const float y1 = macro.getPinY(); if (constraint_boundary == NONE) { + /* TO DO: Use information of which boundary is forbidden based on the global exclude constraints for the edges diff --git a/src/mpl2/src/SimulatedAnnealingCore.h b/src/mpl2/src/SimulatedAnnealingCore.h index fda2a58bdef..dfeab2ecf01 100644 --- a/src/mpl2/src/SimulatedAnnealingCore.h +++ b/src/mpl2/src/SimulatedAnnealingCore.h @@ -141,7 +141,10 @@ class SimulatedAnnealingCore void calWirelength(); void addBoundaryDistToWirelength(const T& macro, const T& io, - float net_weight); + const float net_weight, + Cluster* io_cluster, + const Rect& die, + Boundary constraint_boundary); bool isOutsideTheOutline(const T& macro) const; void calGuidancePenalty(); void calFencePenalty(); @@ -167,6 +170,9 @@ class SimulatedAnnealingCore // boundary constraints Rect outline_; + // Boundaries blocked for IO pins + std::set blocked_boundaries_; + // Number of macros that will actually be part of the sequence pair int macros_to_place_ = 0; From e7ef68b3bc401a646cba326d4f1b7cf42bde21f0 Mon Sep 17 00:00:00 2001 From: Arthur Koucher Date: Fri, 20 Sep 2024 11:52:21 -0300 Subject: [PATCH 20/38] mpl2: incorporate blocked boundaries data for when an IO is constrained to NONE Signed-off-by: Arthur Koucher --- src/mpl2/src/SimulatedAnnealingCore.cpp | 53 +++++++++++++++++++++---- src/mpl2/src/SimulatedAnnealingCore.h | 9 +++++ 2 files changed, 54 insertions(+), 8 deletions(-) diff --git a/src/mpl2/src/SimulatedAnnealingCore.cpp b/src/mpl2/src/SimulatedAnnealingCore.cpp index 51da1d6426f..ca8faf09514 100644 --- a/src/mpl2/src/SimulatedAnnealingCore.cpp +++ b/src/mpl2/src/SimulatedAnnealingCore.cpp @@ -98,6 +98,26 @@ SimulatedAnnealingCore::SimulatedAnnealingCore( macros_ = macros; } +template +void SimulatedAnnealingCore::setBlockedBoundariesForIOs() +{ + if (boundaryIsBlocked(Boundary::L)) { + left_is_blocked_ = true; + } + + if (boundaryIsBlocked(Boundary::R)) { + right_is_blocked_ = true; + } + + if (boundaryIsBlocked(Boundary::B)) { + bottom_is_blocked_ = true; + } + + if (boundaryIsBlocked(Boundary::T)) { + top_is_blocked_ = true; + } +} + template void SimulatedAnnealingCore::initSequencePair() { @@ -336,16 +356,27 @@ void SimulatedAnnealingCore::addBoundaryDistToWirelength( const float y1 = macro.getPinY(); if (constraint_boundary == NONE) { + const float die_hpwl = die.getWidth() + die.getHeight(); - /* - TO DO: Use information of which boundary is forbidden based on - the global exclude constraints for the edges - */ + float dist_to_left = die_hpwl; + if (!left_is_blocked_) { + dist_to_left = std::abs(x1 - die.xMin()); + } + + float dist_to_right = die_hpwl; + if (!right_is_blocked_) { + dist_to_right = std::abs(x1 - die.xMax()); + } + + float dist_to_bottom = die_hpwl; + if (!bottom_is_blocked_) { + dist_to_right = std::abs(y1 - die.yMin()); + } - const float dist_to_left = std::abs(x1 - die.xMin()); - const float dist_to_right = std::abs(x1 - die.xMax()); - const float dist_to_bottom = std::abs(y1 - die.yMin()); - const float dist_to_top = std::abs(y1 - die.yMax()); + float dist_to_top = die_hpwl; + if (!top_is_blocked_) { + dist_to_top = std::abs(y1 - die.yMax()); + } wirelength_ += net_weight @@ -361,6 +392,12 @@ void SimulatedAnnealingCore::addBoundaryDistToWirelength( } } +template +bool SimulatedAnnealingCore::boundaryIsBlocked(Boundary boundary) +{ + return blocked_boundaries_.find(boundary) != blocked_boundaries_.end(); +} + // We consider the macro outside the outline based on the location of // the pin to avoid too many checks. template diff --git a/src/mpl2/src/SimulatedAnnealingCore.h b/src/mpl2/src/SimulatedAnnealingCore.h index dfeab2ecf01..cb648f7bf10 100644 --- a/src/mpl2/src/SimulatedAnnealingCore.h +++ b/src/mpl2/src/SimulatedAnnealingCore.h @@ -91,6 +91,7 @@ class SimulatedAnnealingCore Mpl2Observer* graphics, utl::Logger* logger); + void setBlockedBoundariesForIOs(); void setNumberOfMacrosToPlace(int macros_to_place) { macros_to_place_ = macros_to_place; @@ -145,6 +146,7 @@ class SimulatedAnnealingCore Cluster* io_cluster, const Rect& die, Boundary constraint_boundary); + bool boundaryIsBlocked(Boundary boundary); bool isOutsideTheOutline(const T& macro) const; void calGuidancePenalty(); void calFencePenalty(); @@ -257,6 +259,13 @@ class SimulatedAnnealingCore bool has_initial_sequence_pair_ = false; bool centralization_on_ = false; bool centralization_was_reverted_ = false; + + // Blocked boundaries data is kept in bools to avoid overhead + // during SA steps. + bool left_is_blocked_ = false; + bool right_is_blocked_ = false; + bool bottom_is_blocked_ = false; + bool top_is_blocked_ = false; }; // SACore wrapper function From 29b2c57132273573379c18a200ed18184d137554 Mon Sep 17 00:00:00 2001 From: Arthur Koucher Date: Fri, 20 Sep 2024 12:05:38 -0300 Subject: [PATCH 21/38] mpl2: push IOs to constraint boundary even if it that boundary is blocked Signed-off-by: Arthur Koucher --- src/mpl2/src/SimulatedAnnealingCore.cpp | 44 +++++++++---------------- src/mpl2/src/SimulatedAnnealingCore.h | 5 +-- 2 files changed, 16 insertions(+), 33 deletions(-) diff --git a/src/mpl2/src/SimulatedAnnealingCore.cpp b/src/mpl2/src/SimulatedAnnealingCore.cpp index ca8faf09514..e37eab7b72f 100644 --- a/src/mpl2/src/SimulatedAnnealingCore.cpp +++ b/src/mpl2/src/SimulatedAnnealingCore.cpp @@ -299,28 +299,7 @@ void SimulatedAnnealingCore::calWirelength() T& target = macros_[net.terminals.second]; if (target.isIOCluster()) { - Cluster* io_cluster = target.getCluster(); - const Rect die = io_cluster->getBBox(); - const float die_hpwl = die.getWidth() + die.getHeight(); - - if (isOutsideTheOutline(source)) { - wirelength_ += net.weight * die_hpwl; - continue; - } - - const Boundary constraint_boundary = io_cluster->getConstraintBoundary(); - const bool constraint_boundary_is_blocked - = blocked_boundaries_.find(constraint_boundary) - != blocked_boundaries_.end(); - - if (constraint_boundary_is_blocked - && constraint_boundary != Boundary::NONE) { - wirelength_ += net.weight * die_hpwl; - continue; - } - - addBoundaryDistToWirelength( - source, target, net.weight, io_cluster, die, constraint_boundary); + addBoundaryDistToWirelength(source, target, net.weight); continue; } @@ -341,23 +320,30 @@ void SimulatedAnnealingCore::calWirelength() } /* - TO DO: test this + TO DO: 1. Test this + 2. See if graphics has every check that this has. */ template void SimulatedAnnealingCore::addBoundaryDistToWirelength( const T& macro, const T& io, - const float net_weight, - Cluster* io_cluster, - const Rect& die, - Boundary constraint_boundary) + const float net_weight) { + Cluster* io_cluster = io.getCluster(); + const Rect die = io_cluster->getBBox(); + const float die_hpwl = die.getWidth() + die.getHeight(); + + if (isOutsideTheOutline(macro)) { + wirelength_ += net_weight * die_hpwl; + return; + } + const float x1 = macro.getPinX(); const float y1 = macro.getPinY(); - if (constraint_boundary == NONE) { - const float die_hpwl = die.getWidth() + die.getHeight(); + Boundary constraint_boundary = io_cluster->getConstraintBoundary(); + if (constraint_boundary == NONE) { float dist_to_left = die_hpwl; if (!left_is_blocked_) { dist_to_left = std::abs(x1 - die.xMin()); diff --git a/src/mpl2/src/SimulatedAnnealingCore.h b/src/mpl2/src/SimulatedAnnealingCore.h index cb648f7bf10..8065fd26018 100644 --- a/src/mpl2/src/SimulatedAnnealingCore.h +++ b/src/mpl2/src/SimulatedAnnealingCore.h @@ -142,10 +142,7 @@ class SimulatedAnnealingCore void calWirelength(); void addBoundaryDistToWirelength(const T& macro, const T& io, - const float net_weight, - Cluster* io_cluster, - const Rect& die, - Boundary constraint_boundary); + const float net_weight); bool boundaryIsBlocked(Boundary boundary); bool isOutsideTheOutline(const T& macro) const; void calGuidancePenalty(); From 5ef88681bc839b195ca4f342082b364342f7f088 Mon Sep 17 00:00:00 2001 From: Arthur Koucher Date: Fri, 20 Sep 2024 12:50:29 -0300 Subject: [PATCH 22/38] mpl2: don't draw connection when the NONE closest boundary is blocked Signed-off-by: Arthur Koucher --- src/mpl2/src/Mpl2Observer.h | 3 +- src/mpl2/src/graphics.cpp | 55 +++++++++++++++++++++++-------------- src/mpl2/src/graphics.h | 8 ++++-- src/mpl2/src/hier_rtlmp.cpp | 2 +- 4 files changed, 43 insertions(+), 25 deletions(-) diff --git a/src/mpl2/src/Mpl2Observer.h b/src/mpl2/src/Mpl2Observer.h index 1755f649c1c..c5522b9a885 100644 --- a/src/mpl2/src/Mpl2Observer.h +++ b/src/mpl2/src/Mpl2Observer.h @@ -38,6 +38,7 @@ #include #include +#include "clusterEngine.h" #include "object.h" #include "odb/geom.h" #include "utl/Logger.h" @@ -61,7 +62,7 @@ class Mpl2Observer virtual void endSA() {} virtual void drawResult() {} - virtual void finishedClustering(Cluster* root) {} + virtual void finishedClustering(PhysicalHierarchy* tree) {} virtual void setMaxLevel(int max_level) {} virtual void setMacroBlockages(const std::vector& macro_blockages) diff --git a/src/mpl2/src/graphics.cpp b/src/mpl2/src/graphics.cpp index 929fc13ce80..12b89b1fe74 100644 --- a/src/mpl2/src/graphics.cpp +++ b/src/mpl2/src/graphics.cpp @@ -288,9 +288,10 @@ void Graphics::setMaxLevel(const int max_level) max_level_ = max_level; } -void Graphics::finishedClustering(Cluster* root) +void Graphics::finishedClustering(PhysicalHierarchy* tree) { - root_ = root; + root_ = tree->root.get(); + blocked_boundaries_ = tree->blocked_boundaries; } void Graphics::drawCluster(Cluster* cluster, gui::Painter& painter) @@ -534,7 +535,15 @@ void Graphics::drawDistToIoConstraintBoundary(gui::Painter& painter, to.setX(x2); to.setY(y2); } else { - to = getClosestBoundaryPoint(macro, io_cluster); + // For NONE, the shape of the io cluster is the die area. + const Rect die = io_cluster->getBBox(); + Boundary closest_boundary = getClosestBoundary(macro, die); + + if (boundaryIsBlocked(closest_boundary)) { + return; + } + + to = getClosestBoundaryPoint(macro, die, closest_boundary); } addOutlineOffsetToLine(from, to); @@ -553,25 +562,24 @@ bool Graphics::isOutsideTheOutline(const T& macro) const || block_->micronsToDbu(macro.getPinY()) > outline_.dy(); } +/* + TO DO: + 1. See if some sort of offset dark magic interferes + with the annealing internals. + 2. Guarantee that when the macros are outside the + outline we'll have no problems. + 3. Draw Xs in the blocked boundaries +*/ + +// Here, we have to manually decompensate the offset of the +// coordinates that come from the cluster. template odb::Point Graphics::getClosestBoundaryPoint(const T& macro, - Cluster* io_cluster) + const Rect& die, + Boundary closest_boundary) { - // For NONE, the shape of the io cluster is the die area. - const Rect die = io_cluster->getBBox(); - Boundary closest_boundary = getClosestBoundary(macro, die); odb::Point to; - /* - TO DO: - 1. See if some sort of offset dark magic interferes - with the annealing internals. - 2. Guarantee that when the macros are outside the - outline we'll have no problems. - */ - - // We have to manually decompensate the offset of the coordinate - // that comes from the cluster. if (closest_boundary == Boundary::L) { to.setX(block_->micronsToDbu(die.xMin())); to.setY(block_->micronsToDbu(macro.getPinY())); @@ -584,10 +592,10 @@ odb::Point Graphics::getClosestBoundaryPoint(const T& macro, to.setX(block_->micronsToDbu(macro.getPinX())); to.setY(block_->micronsToDbu(die.yMin())); to.addY(-outline_.yMin()); - } else { // Top + } else { // Top to.setX(block_->micronsToDbu(macro.getPinX())); to.setY(block_->micronsToDbu(die.yMax())); - to.addY(-outline_.yMin()); + to.addY(-outline_.yMin()); } return to; @@ -598,7 +606,7 @@ void Graphics::addOutlineOffsetToLine(odb::Point& from, odb::Point& to) from.addX(outline_.xMin()); from.addY(outline_.yMin()); to.addX(outline_.xMin()); - to.addY(outline_.yMin()); + to.addY(outline_.yMin()); } template @@ -606,7 +614,7 @@ Boundary Graphics::getClosestBoundary(const T& macro, const Rect& die) { const float macro_x = macro.getPinX(); const float macro_y = macro.getPinY(); - + const float dist_to_left = std::abs(macro_x - die.xMin()); float shortest_distance = dist_to_left; Boundary closest_boundary = Boundary::L; @@ -630,6 +638,11 @@ Boundary Graphics::getClosestBoundary(const T& macro, const Rect& die) return closest_boundary; } +bool Graphics::boundaryIsBlocked(Boundary boundary) +{ + return blocked_boundaries_.find(boundary) != blocked_boundaries_.end(); +} + // Give some transparency to mixed and hard so we can see overlap with // macro blockages. void Graphics::setSoftMacroBrush(gui::Painter& painter, diff --git a/src/mpl2/src/graphics.h b/src/mpl2/src/graphics.h index 0a6cc8f3258..ac83da848ae 100644 --- a/src/mpl2/src/graphics.h +++ b/src/mpl2/src/graphics.h @@ -60,7 +60,7 @@ class Graphics : public gui::Renderer, public Mpl2Observer void saStep(const std::vector& macros) override; void endSA() override; void drawResult() override; - void finishedClustering(Cluster* root) override; + void finishedClustering(PhysicalHierarchy* tree) override; void setMaxLevel(int max_level) override; void setAreaPenalty(float area) override; @@ -103,9 +103,12 @@ class Graphics : public gui::Renderer, public Mpl2Observer template bool isOutsideTheOutline(const T& macro) const; template - odb::Point getClosestBoundaryPoint(const T& macro, Cluster* io_cluster); + odb::Point getClosestBoundaryPoint(const T& macro, + const Rect& die, + Boundary closest_boundary); template Boundary getClosestBoundary(const T& macro, const Rect& die); + bool boundaryIsBlocked(Boundary boundary); void addOutlineOffsetToLine(odb::Point& from, odb::Point& to); void setSoftMacroBrush(gui::Painter& painter, const SoftMacro& soft_macro); void fetchSoftAndHard(Cluster* parent, @@ -124,6 +127,7 @@ class Graphics : public gui::Renderer, public Mpl2Observer std::vector bundled_nets_; odb::Rect outline_; std::vector> outlines_; + std::set blocked_boundaries_; bool active_ = true; bool coarse_; diff --git a/src/mpl2/src/hier_rtlmp.cpp b/src/mpl2/src/hier_rtlmp.cpp index 1fa57ed2eb3..eebed186060 100644 --- a/src/mpl2/src/hier_rtlmp.cpp +++ b/src/mpl2/src/hier_rtlmp.cpp @@ -303,7 +303,7 @@ void HierRTLMP::runMultilevelAutoclustering() } if (graphics_) { - graphics_->finishedClustering(tree_->root.get()); + graphics_->finishedClustering(tree_.get()); } } From 37b10a00f59e6efac658b3fa0a12d9880c8bfbaa Mon Sep 17 00:00:00 2001 From: Arthur Koucher Date: Fri, 20 Sep 2024 16:26:51 -0300 Subject: [PATCH 23/38] mpl2: adapt io clusters' blockages to be shaped according to std cell area and io clusters' extensions Signed-off-by: Arthur Koucher --- src/mpl2/src/hier_rtlmp.cpp | 187 +++++++++++++++--------------------- src/mpl2/src/hier_rtlmp.h | 7 +- src/mpl2/src/object.h | 4 +- 3 files changed, 85 insertions(+), 113 deletions(-) diff --git a/src/mpl2/src/hier_rtlmp.cpp b/src/mpl2/src/hier_rtlmp.cpp index eebed186060..b542d32fe92 100644 --- a/src/mpl2/src/hier_rtlmp.cpp +++ b/src/mpl2/src/hier_rtlmp.cpp @@ -362,7 +362,7 @@ void HierRTLMP::runCoarseShaping() calculateChildrenTilings(tree_->root.get()); - // setIOClustersBlockages(); + setIOClustersBlockages(); setPlacementBlockages(); } @@ -926,142 +926,105 @@ void HierRTLMP::setTightPackingTilings(Cluster* macro_array) macro_array->setMacroTilings(tight_packing_tilings); } +// The blockages must cover the entire boundary that they represent. void HierRTLMP::setIOClustersBlockages() { if (!tree_->maps.bterm_to_inst.empty()) { return; } - IOSpans io_spans = computeIOSpans(); - const float depth = computeIOBlockagesDepth(io_spans); + std::vector io_clusters = getIOClusters(); + const Rect die = dbuToMicrons(block_->getDieArea()); - const Rect root(tree_->root->getX(), - tree_->root->getY(), - tree_->root->getX() + tree_->root->getWidth(), - tree_->root->getY() + tree_->root->getHeight()); + const float depth = computeIOBlockagesDepth(io_clusters, die); - // 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) { - const 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); + bool design_has_none_constraint = false; + for (Cluster* io_cluster : io_clusters) { + if (io_cluster->getConstraintBoundary() == NONE) { + design_has_none_constraint = true; + break; + } } - 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()); - - boundary_to_io_blockage_[T] = top_io_blockage; - macro_blockages_.push_back(top_io_blockage); - } + /* + TO DO: This should be a combination of both constraint types. + */ + for (Cluster* io_cluster : io_clusters) { + Boundary constraint_boundary = io_cluster->getConstraintBoundary(); - 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); + if (constraint_boundary == L || design_has_none_constraint) { + const Rect left_io_blockage( + die.xMin(), die.yMin(), die.xMin() + depth, die.yMax()); - boundary_to_io_blockage_[R] = right_io_blockage; - macro_blockages_.push_back(right_io_blockage); - } + boundary_to_io_blockage_[L] = left_io_blockage; + macro_blockages_.push_back(left_io_blockage); + } - 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); + if (constraint_boundary == T || design_has_none_constraint) { + const Rect top_io_blockage( + die.xMin(), die.yMax() - depth, die.xMax(), die.yMax()); - boundary_to_io_blockage_[B] = bottom_io_blockage; - macro_blockages_.push_back(bottom_io_blockage); - } -} + boundary_to_io_blockage_[T] = top_io_blockage; + macro_blockages_.push_back(top_io_blockage); + } -// Determine the range of IOs in each boundary of the die. -HierRTLMP::IOSpans HierRTLMP::computeIOSpans() -{ - IOSpans io_spans; + if (constraint_boundary == R || design_has_none_constraint) { + const Rect right_io_blockage( + die.xMax() - depth, die.yMin(), die.xMax(), die.yMax()); - odb::Rect die = block_->getDieArea(); + boundary_to_io_blockage_[R] = right_io_blockage; + macro_blockages_.push_back(right_io_blockage); + } - // Initialize spans based on the dimensions of the die area. - io_spans[L] - = {block_->dbuToMicrons(die.yMax()), block_->dbuToMicrons(die.yMin())}; - io_spans[T] - = {block_->dbuToMicrons(die.xMax()), block_->dbuToMicrons(die.xMin())}; - io_spans[R] = io_spans[L]; - io_spans[B] = io_spans[T]; + if (constraint_boundary == B || design_has_none_constraint) { + const Rect bottom_io_blockage( + die.xMin(), die.yMin(), die.xMax(), die.yMin() + depth); - for (auto term : block_->getBTerms()) { - if (term->getSigType().isSupply()) { - continue; + boundary_to_io_blockage_[B] = bottom_io_blockage; + macro_blockages_.push_back(bottom_io_blockage); } - int lx = std::numeric_limits::max(); - int ly = std::numeric_limits::max(); - int ux = 0; - int uy = 0; - - for (const auto pin : term->getBPins()) { - for (const auto box : pin->getBoxes()) { - lx = std::min(lx, box->xMin()); - ly = std::min(ly, box->yMin()); - ux = std::max(ux, box->xMax()); - uy = std::max(uy, box->yMax()); - } + // Ensure we don't stack blockages. + if (design_has_none_constraint) { + break; } + } +} - // Modify ranges based on the position of the IO pins. - if (lx <= die.xMin()) { - io_spans[L].first = std::min( - io_spans[L].first, static_cast(block_->dbuToMicrons(ly))); - io_spans[L].second = std::max( - io_spans[L].second, static_cast(block_->dbuToMicrons(uy))); - } else if (uy >= die.yMax()) { - io_spans[T].first = std::min( - io_spans[T].first, static_cast(block_->dbuToMicrons(lx))); - io_spans[T].second = std::max( - io_spans[T].second, static_cast(block_->dbuToMicrons(ux))); - } else if (ux >= die.xMax()) { - io_spans[R].first = std::min( - io_spans[R].first, static_cast(block_->dbuToMicrons(ly))); - io_spans[R].second = std::max( - io_spans[R].second, static_cast(block_->dbuToMicrons(uy))); - } else { - io_spans[B].first = std::min( - io_spans[B].first, static_cast(block_->dbuToMicrons(lx))); - io_spans[B].second = std::max( - io_spans[B].second, static_cast(block_->dbuToMicrons(ux))); +std::vector HierRTLMP::getIOClusters() +{ + std::vector io_clusters; + + for (const auto& child : tree_->root->getChildren()) { + if (child->isIOCluster()) { + io_clusters.push_back(child.get()); } } - return io_spans; + return io_clusters; } // The depth of IO clusters' blockages is generated based on: -// 1) How many vertical or horizontal boundaries have signal IO pins. -// 2) The total length of the io spans in all used boundaries. -float HierRTLMP::computeIOBlockagesDepth(const IOSpans& io_spans) +// 1) Amount of std cell area in the design. +// 2) Extension of the IO clusters across the design's boundaries. +float HierRTLMP::computeIOBlockagesDepth(std::vector io_clusters, + const Rect& die) { - float sum_length = 0.0; - int num_hor_access = 0; - int num_ver_access = 0; + float io_clusters_extension = 0.0; + + for (Cluster* io_cluster : io_clusters) { + if (io_cluster->getConstraintBoundary() == NONE) { + const Rect die = io_cluster->getBBox(); + io_clusters_extension = die.getPerimeter(); + break; + } - for (auto& [pin_access, length] : io_spans) { - if (length.second > length.first) { - sum_length += std::abs(length.second - length.first); + Boundary constraint_boundary = io_cluster->getConstraintBoundary(); - if (pin_access == R || pin_access == L) { - num_hor_access++; - } else { - num_ver_access++; - } + if (constraint_boundary == L || constraint_boundary == R) { + io_clusters_extension += die.getWidth(); + } else { // Bottom or Top + io_clusters_extension += die.getHeight(); } } @@ -1075,14 +1038,14 @@ float HierRTLMP::computeIOBlockagesDepth(const IOSpans& io_spans) const float macro_dominance_factor = tree_->macro_with_halo_area / (tree_->root->getWidth() * tree_->root->getHeight()); - const float depth = (std_cell_area / sum_length) + const float depth = (std_cell_area / io_clusters_extension) * std::pow((1 - macro_dominance_factor), 2); debugPrint(logger_, MPL, "coarse_shaping", 1, - "Bundled IO clusters blokaged depth = {}", + "IO clusters blokaged depth = {}", depth); return depth; @@ -4119,6 +4082,14 @@ odb::Rect HierRTLMP::micronsToDbu(const Rect& micron_rect) block_->micronsToDbu(micron_rect.yMax())); } +Rect HierRTLMP::dbuToMicrons(const odb::Rect& dbu_rect) +{ + return Rect(block_->dbuToMicrons(dbu_rect.xMin()), + block_->dbuToMicrons(dbu_rect.yMin()), + block_->dbuToMicrons(dbu_rect.xMax()), + block_->dbuToMicrons(dbu_rect.yMax())); +} + //////// Pusher //////// Pusher::Pusher(utl::Logger* logger, diff --git a/src/mpl2/src/hier_rtlmp.h b/src/mpl2/src/hier_rtlmp.h index c469d0a6254..de87bf58acd 100644 --- a/src/mpl2/src/hier_rtlmp.h +++ b/src/mpl2/src/hier_rtlmp.h @@ -140,7 +140,6 @@ class HierRTLMP private: using SoftSAVector = std::vector>; using HardSAVector = std::vector>; - using IOSpans = std::map>; void runMultilevelAutoclustering(); void runHierarchicalMacroPlacement(); @@ -164,8 +163,9 @@ class HierRTLMP void calculateMacroTilings(Cluster* cluster); void setTightPackingTilings(Cluster* macro_array); void setIOClustersBlockages(); - IOSpans computeIOSpans(); - float computeIOBlockagesDepth(const IOSpans& io_spans); + std::vector getIOClusters(); + float computeIOBlockagesDepth(std::vector io_clusters, + const Rect& die); void setPlacementBlockages(); // Fine Shaping @@ -231,6 +231,7 @@ class HierRTLMP // Aux for conversion odb::Rect micronsToDbu(const Rect& micron_rect); + Rect dbuToMicrons(const odb::Rect& dbu_rect); sta::dbNetwork* network_ = nullptr; odb::dbDatabase* db_ = nullptr; diff --git a/src/mpl2/src/object.h b/src/mpl2/src/object.h index deaf970dc41..5684e98bc7e 100644 --- a/src/mpl2/src/object.h +++ b/src/mpl2/src/object.h @@ -646,13 +646,13 @@ struct Rect float yMax() const { return uy; } float getX() const { return (lx + ux) / 2.0; } - float getY() const { return (ly + uy) / 2.0; } float getWidth() const { return ux - lx; } - float getHeight() const { return uy - ly; } + float getPerimeter() const { return 2 * getWidth() + 2 * getHeight(); } + void setLoc(float x, float y, float core_lx, From fcc3fb925c094cf227c133d475bfce9160ccd601 Mon Sep 17 00:00:00 2001 From: Arthur Koucher Date: Mon, 23 Sep 2024 12:15:39 -0300 Subject: [PATCH 24/38] mpl2: use both -exclude and constraint regions to compute pin access blockages Signed-off-by: Arthur Koucher --- src/mpl2/src/hier_rtlmp.cpp | 96 ++++++++++++++++++++++--------------- src/mpl2/src/hier_rtlmp.h | 3 ++ 2 files changed, 61 insertions(+), 38 deletions(-) diff --git a/src/mpl2/src/hier_rtlmp.cpp b/src/mpl2/src/hier_rtlmp.cpp index b542d32fe92..fc67795a0c7 100644 --- a/src/mpl2/src/hier_rtlmp.cpp +++ b/src/mpl2/src/hier_rtlmp.cpp @@ -926,7 +926,9 @@ void HierRTLMP::setTightPackingTilings(Cluster* macro_array) macro_array->setMacroTilings(tight_packing_tilings); } -// The blockages must cover the entire boundary that they represent. +/* + TO DO: Change name to pin_access blockages +*/ void HierRTLMP::setIOClustersBlockages() { if (!tree_->maps.bterm_to_inst.empty()) { @@ -938,56 +940,74 @@ void HierRTLMP::setIOClustersBlockages() const float depth = computeIOBlockagesDepth(io_clusters, die); - bool design_has_none_constraint = false; - for (Cluster* io_cluster : io_clusters) { - if (io_cluster->getConstraintBoundary() == NONE) { - design_has_none_constraint = true; - break; - } - } - - /* - TO DO: This should be a combination of both constraint types. - */ for (Cluster* io_cluster : io_clusters) { Boundary constraint_boundary = io_cluster->getConstraintBoundary(); + createPinAccessBlockage(constraint_boundary, depth, die); + } - if (constraint_boundary == L || design_has_none_constraint) { - const Rect left_io_blockage( - die.xMin(), die.yMin(), die.xMin() + depth, die.yMax()); - - boundary_to_io_blockage_[L] = left_io_blockage; - macro_blockages_.push_back(left_io_blockage); + if (boundary_to_io_blockage_.empty()) { + // If there are no constraints at all, give freedom to SA so it + // doesn't have to deal with pin access blockages in all boundaries. + // This will help SA not relying on extreme utilizations to + // converge for designs such as sky130hd/uW. + if (tree_->blocked_boundaries.empty()) { + return; } - if (constraint_boundary == T || design_has_none_constraint) { - const Rect top_io_blockage( - die.xMin(), die.yMax() - depth, die.xMax(), die.yMax()); + // There are only -exclude constraints, so we create pin access + // blockages based on the boundaries that are not blocked. + if (tree_->blocked_boundaries.find(L) + == tree_->blocked_boundaries.end()) { + createPinAccessBlockage(L, depth, die); + } - boundary_to_io_blockage_[T] = top_io_blockage; - macro_blockages_.push_back(top_io_blockage); + if (tree_->blocked_boundaries.find(R) + == tree_->blocked_boundaries.end()) { + createPinAccessBlockage(R, depth, die); } - if (constraint_boundary == R || design_has_none_constraint) { - const Rect right_io_blockage( - die.xMax() - depth, die.yMin(), die.xMax(), die.yMax()); + if (tree_->blocked_boundaries.find(B) + == tree_->blocked_boundaries.end()) { + createPinAccessBlockage(B, depth, die); + } - boundary_to_io_blockage_[R] = right_io_blockage; - macro_blockages_.push_back(right_io_blockage); + if (tree_->blocked_boundaries.find(T) + == tree_->blocked_boundaries.end()) { + createPinAccessBlockage(T, depth, die); } + } +} - if (constraint_boundary == B || design_has_none_constraint) { - const Rect bottom_io_blockage( - die.xMin(), die.yMin(), die.xMax(), die.yMin() + depth); +void HierRTLMP::createPinAccessBlockage(Boundary constraint_boundary, + const float depth, + const Rect& die) +{ + if (constraint_boundary == L) { + const Rect left_io_blockage( + die.xMin(), die.yMin(), die.xMin() + depth, die.yMax()); + boundary_to_io_blockage_[L] = left_io_blockage; + macro_blockages_.push_back(left_io_blockage); + } - boundary_to_io_blockage_[B] = bottom_io_blockage; - macro_blockages_.push_back(bottom_io_blockage); - } + if (constraint_boundary == T) { + const Rect top_io_blockage( + die.xMin(), die.yMax() - depth, die.xMax(), die.yMax()); + boundary_to_io_blockage_[T] = top_io_blockage; + macro_blockages_.push_back(top_io_blockage); + } - // Ensure we don't stack blockages. - if (design_has_none_constraint) { - break; - } + if (constraint_boundary == R) { + const Rect right_io_blockage( + die.xMax() - depth, die.yMin(), die.xMax(), die.yMax()); + boundary_to_io_blockage_[R] = right_io_blockage; + macro_blockages_.push_back(right_io_blockage); + } + + if (constraint_boundary == B) { + const Rect bottom_io_blockage( + die.xMin(), die.yMin(), die.xMax(), die.yMin() + depth); + boundary_to_io_blockage_[B] = bottom_io_blockage; + macro_blockages_.push_back(bottom_io_blockage); } } diff --git a/src/mpl2/src/hier_rtlmp.h b/src/mpl2/src/hier_rtlmp.h index de87bf58acd..734915a5747 100644 --- a/src/mpl2/src/hier_rtlmp.h +++ b/src/mpl2/src/hier_rtlmp.h @@ -166,6 +166,9 @@ class HierRTLMP std::vector getIOClusters(); float computeIOBlockagesDepth(std::vector io_clusters, const Rect& die); + void createPinAccessBlockage(Boundary constraint_boundary, + float depth, + const Rect& die); void setPlacementBlockages(); // Fine Shaping From e061b576e8c3a4fa710ee9d0ca9dc112f1a6ac9c Mon Sep 17 00:00:00 2001 From: Arthur Koucher Date: Mon, 23 Sep 2024 12:22:35 -0300 Subject: [PATCH 25/38] mpl2: remove duplicated overkill function Signed-off-by: Arthur Koucher --- src/mpl2/src/SimulatedAnnealingCore.cpp | 14 ++++---------- src/mpl2/src/SimulatedAnnealingCore.h | 1 - src/mpl2/src/graphics.cpp | 8 ++------ src/mpl2/src/graphics.h | 1 - 4 files changed, 6 insertions(+), 18 deletions(-) diff --git a/src/mpl2/src/SimulatedAnnealingCore.cpp b/src/mpl2/src/SimulatedAnnealingCore.cpp index e37eab7b72f..e34b490ff15 100644 --- a/src/mpl2/src/SimulatedAnnealingCore.cpp +++ b/src/mpl2/src/SimulatedAnnealingCore.cpp @@ -101,19 +101,19 @@ SimulatedAnnealingCore::SimulatedAnnealingCore( template void SimulatedAnnealingCore::setBlockedBoundariesForIOs() { - if (boundaryIsBlocked(Boundary::L)) { + if (blocked_boundaries_.find(Boundary::L) != blocked_boundaries_.end()) { left_is_blocked_ = true; } - if (boundaryIsBlocked(Boundary::R)) { + if (blocked_boundaries_.find(Boundary::R) != blocked_boundaries_.end()) { right_is_blocked_ = true; } - if (boundaryIsBlocked(Boundary::B)) { + if (blocked_boundaries_.find(Boundary::B) != blocked_boundaries_.end()) { bottom_is_blocked_ = true; } - if (boundaryIsBlocked(Boundary::T)) { + if (blocked_boundaries_.find(Boundary::T) != blocked_boundaries_.end()) { top_is_blocked_ = true; } } @@ -378,12 +378,6 @@ void SimulatedAnnealingCore::addBoundaryDistToWirelength( } } -template -bool SimulatedAnnealingCore::boundaryIsBlocked(Boundary boundary) -{ - return blocked_boundaries_.find(boundary) != blocked_boundaries_.end(); -} - // We consider the macro outside the outline based on the location of // the pin to avoid too many checks. template diff --git a/src/mpl2/src/SimulatedAnnealingCore.h b/src/mpl2/src/SimulatedAnnealingCore.h index 8065fd26018..0967d772eb4 100644 --- a/src/mpl2/src/SimulatedAnnealingCore.h +++ b/src/mpl2/src/SimulatedAnnealingCore.h @@ -143,7 +143,6 @@ class SimulatedAnnealingCore void addBoundaryDistToWirelength(const T& macro, const T& io, const float net_weight); - bool boundaryIsBlocked(Boundary boundary); bool isOutsideTheOutline(const T& macro) const; void calGuidancePenalty(); void calFencePenalty(); diff --git a/src/mpl2/src/graphics.cpp b/src/mpl2/src/graphics.cpp index 12b89b1fe74..cea43b941bc 100644 --- a/src/mpl2/src/graphics.cpp +++ b/src/mpl2/src/graphics.cpp @@ -539,7 +539,8 @@ void Graphics::drawDistToIoConstraintBoundary(gui::Painter& painter, const Rect die = io_cluster->getBBox(); Boundary closest_boundary = getClosestBoundary(macro, die); - if (boundaryIsBlocked(closest_boundary)) { + if (blocked_boundaries_.find(closest_boundary) + != blocked_boundaries_.end()) { return; } @@ -638,11 +639,6 @@ Boundary Graphics::getClosestBoundary(const T& macro, const Rect& die) return closest_boundary; } -bool Graphics::boundaryIsBlocked(Boundary boundary) -{ - return blocked_boundaries_.find(boundary) != blocked_boundaries_.end(); -} - // Give some transparency to mixed and hard so we can see overlap with // macro blockages. void Graphics::setSoftMacroBrush(gui::Painter& painter, diff --git a/src/mpl2/src/graphics.h b/src/mpl2/src/graphics.h index ac83da848ae..bdf3bad790e 100644 --- a/src/mpl2/src/graphics.h +++ b/src/mpl2/src/graphics.h @@ -108,7 +108,6 @@ class Graphics : public gui::Renderer, public Mpl2Observer Boundary closest_boundary); template Boundary getClosestBoundary(const T& macro, const Rect& die); - bool boundaryIsBlocked(Boundary boundary); void addOutlineOffsetToLine(odb::Point& from, odb::Point& to); void setSoftMacroBrush(gui::Painter& painter, const SoftMacro& soft_macro); void fetchSoftAndHard(Cluster* parent, From f13cbe448f8f16cc27fc95f6755e83c3e6ce5c8f Mon Sep 17 00:00:00 2001 From: Arthur Koucher Date: Mon, 23 Sep 2024 16:05:56 -0300 Subject: [PATCH 26/38] mpl2: use references Signed-off-by: Arthur Koucher --- src/mpl2/src/SimulatedAnnealingCore.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/mpl2/src/SimulatedAnnealingCore.cpp b/src/mpl2/src/SimulatedAnnealingCore.cpp index e34b490ff15..30b9cbe5a37 100644 --- a/src/mpl2/src/SimulatedAnnealingCore.cpp +++ b/src/mpl2/src/SimulatedAnnealingCore.cpp @@ -303,10 +303,10 @@ void SimulatedAnnealingCore::calWirelength() continue; } - const float x1 = macros_[net.terminals.first].getPinX(); - const float y1 = macros_[net.terminals.first].getPinY(); - const float x2 = macros_[net.terminals.second].getPinX(); - const float y2 = macros_[net.terminals.second].getPinY(); + const float x1 = source.getPinX(); + const float y1 = source.getPinY(); + const float x2 = target.getPinX(); + const float y2 = target.getPinY(); wirelength_ += net.weight * (std::abs(x2 - x1) + std::abs(y2 - y1)); } From de728b6c36cae222295e33bcfa11706fa45f16a9 Mon Sep 17 00:00:00 2001 From: Arthur Koucher Date: Mon, 23 Sep 2024 17:13:48 -0300 Subject: [PATCH 27/38] mpl2: add indication when boundary is block in debug mode Signed-off-by: Arthur Koucher --- src/mpl2/src/SimulatedAnnealingCore.cpp | 4 -- src/mpl2/src/graphics.cpp | 65 ++++++++++++++++++++----- src/mpl2/src/graphics.h | 6 ++- 3 files changed, 59 insertions(+), 16 deletions(-) diff --git a/src/mpl2/src/SimulatedAnnealingCore.cpp b/src/mpl2/src/SimulatedAnnealingCore.cpp index 30b9cbe5a37..a80a0906352 100644 --- a/src/mpl2/src/SimulatedAnnealingCore.cpp +++ b/src/mpl2/src/SimulatedAnnealingCore.cpp @@ -319,10 +319,6 @@ void SimulatedAnnealingCore::calWirelength() } } -/* - TO DO: 1. Test this - 2. See if graphics has every check that this has. -*/ template void SimulatedAnnealingCore::addBoundaryDistToWirelength( const T& macro, diff --git a/src/mpl2/src/graphics.cpp b/src/mpl2/src/graphics.cpp index cea43b941bc..0ee609e63fa 100644 --- a/src/mpl2/src/graphics.cpp +++ b/src/mpl2/src/graphics.cpp @@ -291,7 +291,45 @@ void Graphics::setMaxLevel(const int max_level) void Graphics::finishedClustering(PhysicalHierarchy* tree) { root_ = tree->root.get(); - blocked_boundaries_ = tree->blocked_boundaries; + setXMarksSizeAndPosition(tree->blocked_boundaries); +} + +void Graphics::setXMarksSizeAndPosition( + const std::set& blocked_boundaries) +{ + const odb::Rect die = block_->getDieArea(); + + // Not too big/small + x_mark_size_ = (die.dx() + die.dy()) * 0.03; + + for (Boundary boundary : blocked_boundaries) { + logger_->report("{} is blocked", toString(boundary)); + + odb::Point x_mark_point; + + switch (boundary) { + case L: { + x_mark_point = odb::Point(die.xMin(), die.yCenter()); + break; + } + case R: { + x_mark_point = odb::Point(die.xMax(), die.yCenter()); + break; + } + case B: { + x_mark_point = odb::Point(die.xCenter(), die.yMin()); + break; + } + case T: { + x_mark_point = odb::Point(die.xCenter(), die.yMax()); + break; + } + case NONE: + break; + } + + blocked_boundary_to_mark_[boundary] = x_mark_point; + } } void Graphics::drawCluster(Cluster* cluster, gui::Painter& painter) @@ -353,6 +391,8 @@ void Graphics::drawObjects(gui::Painter& painter) drawCluster(root_, painter); } + drawBlockedBoundariesIndication(painter); + // Draw blockages only during SA for SoftMacros if (!soft_macros_.empty()) { drawAllBlockages(painter); @@ -364,7 +404,7 @@ void Graphics::drawObjects(gui::Painter& painter) for (const auto& macro : soft_macros_) { Cluster* cluster = macro.getCluster(); - if (!cluster) { + if (!cluster) { // fixed terminals continue; } @@ -478,6 +518,16 @@ void Graphics::drawObjects(gui::Painter& painter) } } +void Graphics::drawBlockedBoundariesIndication(gui::Painter& painter) +{ + painter.setPen(gui::Painter::red, true); + painter.setBrush(gui::Painter::transparent); + + for (const auto [boundary, x_mark_point] : blocked_boundary_to_mark_) { + painter.drawX(x_mark_point.getX(), x_mark_point.getY(), x_mark_size_); + } +} + template void Graphics::drawBundledNets(gui::Painter& painter, const std::vector& macros) @@ -539,8 +589,8 @@ void Graphics::drawDistToIoConstraintBoundary(gui::Painter& painter, const Rect die = io_cluster->getBBox(); Boundary closest_boundary = getClosestBoundary(macro, die); - if (blocked_boundaries_.find(closest_boundary) - != blocked_boundaries_.end()) { + if (blocked_boundary_to_mark_.find(closest_boundary) + != blocked_boundary_to_mark_.end()) { return; } @@ -567,9 +617,6 @@ bool Graphics::isOutsideTheOutline(const T& macro) const TO DO: 1. See if some sort of offset dark magic interferes with the annealing internals. - 2. Guarantee that when the macros are outside the - outline we'll have no problems. - 3. Draw Xs in the blocked boundaries */ // Here, we have to manually decompensate the offset of the @@ -644,10 +691,6 @@ Boundary Graphics::getClosestBoundary(const T& macro, const Rect& die) void Graphics::setSoftMacroBrush(gui::Painter& painter, const SoftMacro& soft_macro) { - if (soft_macro.getCluster() == nullptr) { // fixed terminals - return; - } - if (soft_macro.getCluster()->getClusterType() == StdCellCluster) { painter.setBrush(gui::Painter::dark_blue); } else if (soft_macro.getCluster()->getClusterType() == HardMacroCluster) { diff --git a/src/mpl2/src/graphics.h b/src/mpl2/src/graphics.h index bdf3bad790e..b823a96a8a1 100644 --- a/src/mpl2/src/graphics.h +++ b/src/mpl2/src/graphics.h @@ -90,8 +90,10 @@ class Graphics : public gui::Renderer, public Mpl2Observer void eraseDrawing() override; private: + void setXMarksSizeAndPosition(const std::set& blocked_boundaries); void resetPenalties(); void drawCluster(Cluster* cluster, gui::Painter& painter); + void drawBlockedBoundariesIndication(gui::Painter& painter); void drawAllBlockages(gui::Painter& painter); void drawBlockage(const Rect& blockage, gui::Painter& painter); template @@ -126,7 +128,9 @@ class Graphics : public gui::Renderer, public Mpl2Observer std::vector bundled_nets_; odb::Rect outline_; std::vector> outlines_; - std::set blocked_boundaries_; + std::map blocked_boundary_to_mark_; + + int x_mark_size_ = 0; bool active_ = true; bool coarse_; From d995e90cabf9820ad7f81bf675995ee7c9a40310 Mon Sep 17 00:00:00 2001 From: Arthur Koucher Date: Mon, 23 Sep 2024 17:36:39 -0300 Subject: [PATCH 28/38] mpl2: remove bundledIO related things / clean up Signed-off-by: Arthur Koucher --- src/mpl2/README.md | 2 -- src/mpl2/include/mpl2/rtl_mp.h | 1 - src/mpl2/src/bus_synthesis.h | 9 +++++++ src/mpl2/src/clusterEngine.h | 1 - src/mpl2/src/hier_rtlmp.cpp | 48 ++++++++++++++-------------------- src/mpl2/src/hier_rtlmp.h | 7 +++-- src/mpl2/src/mpl.i | 2 -- src/mpl2/src/mpl.tcl | 8 +----- src/mpl2/src/object.cpp | 2 +- src/mpl2/src/object.h | 6 ++++- src/mpl2/src/rtl_mp.cpp | 2 -- 11 files changed, 38 insertions(+), 50 deletions(-) diff --git a/src/mpl2/README.md b/src/mpl2/README.md index 0d84aa6a7a7..cb7dc9abb93 100644 --- a/src/mpl2/README.md +++ b/src/mpl2/README.md @@ -25,7 +25,6 @@ rtl_macro_placer [-tolerance tolerance] [-max_num_level max_num_level] [-coarsening_ratio coarsening_ratio] - [-num_bundled_ios num_bundled_ios] [-large_net_threshold large_net_threshold] [-signature_net_threshold signature_net_threshold] [-halo_width halo_width] @@ -61,7 +60,6 @@ rtl_macro_placer | `-tolerance` | Add a margin to the minimum and maximum number of macros/std cells in a cluster. For min, we multiply by (1 - `tol`), and for the max (1 + `tol`). This is to improve the robustness of hierarchical clustering. The allowed values are floats `[0, 1)`, and the default value is `0.1`. | | `-max_num_level` | Maximum depth of physical hierarchical tree. The default value is `2`, and the allowed values are integers `[0, MAX_INT]`. | | `-coarsening_ratio` | The larger the coarsening_ratio, the faster the convergence process. The allowed values are floats, and the default value is `10.0`. | -| `-num_bundled_ios` | Specifies the number of bundled pins for the left, right, top, and bottom boundaries. The default value is `3`, and the allowed values are integers `[0, MAX_INT]`. | | `-large_net_threshold` | Ignore nets with many connections during clustering, such as global nets. The default value is `50`, and the allowed values are integers `[0, MAX_INT]`. | | `-signature_net_threshold` | Minimum number of connections between two clusters to be identified as connected. The default value is `50`, and the allowed values are integers `[0, MAX_INT]`. | | `-halo_width` | Horizontal/vertical halo around macros (microns). The allowed values are floats, and the default value is `0.0`. | diff --git a/src/mpl2/include/mpl2/rtl_mp.h b/src/mpl2/include/mpl2/rtl_mp.h index 17dc94a3b99..c6676f77656 100644 --- a/src/mpl2/include/mpl2/rtl_mp.h +++ b/src/mpl2/include/mpl2/rtl_mp.h @@ -77,7 +77,6 @@ class MacroPlacer2 float tolerance, int max_num_level, float coarsening_ratio, - int num_bundled_ios, int large_net_threshold, int signature_net_threshold, float halo_width, diff --git a/src/mpl2/src/bus_synthesis.h b/src/mpl2/src/bus_synthesis.h index 97e7146026c..1915d933ca3 100644 --- a/src/mpl2/src/bus_synthesis.h +++ b/src/mpl2/src/bus_synthesis.h @@ -46,6 +46,11 @@ namespace mpl2 { using Point = std::pair; +/* + TO DO: What can be done here now that bundled IOs are gone? (Perhaps, + there's no problem, because the vertex idea is still the same) +*/ + // Each point in the hanan grid is represented by a vertex (with no size) // And each bundled IO pin is represented by a vertex struct Vertex @@ -67,6 +72,10 @@ struct Vertex // position of the vertex Point pos; + /* + TO DO: Ditto + */ + // The weight of the vertex : macro utilization of the SoftMacro // which the vertex belongs to. For bundled IO pin, we set the // macro utilization to be zero diff --git a/src/mpl2/src/clusterEngine.h b/src/mpl2/src/clusterEngine.h index 28e022addab..5adbc3815a6 100644 --- a/src/mpl2/src/clusterEngine.h +++ b/src/mpl2/src/clusterEngine.h @@ -131,7 +131,6 @@ struct PhysicalHierarchy int base_min_std_cell{0}; int max_level{0}; - int bundled_ios_per_edge{0}; int large_net_threshold{0}; // used to ignore global nets int min_net_count_for_connection{0}; float cluster_size_ratio{0.0f}; diff --git a/src/mpl2/src/hier_rtlmp.cpp b/src/mpl2/src/hier_rtlmp.cpp index fc67795a0c7..459ade253fa 100644 --- a/src/mpl2/src/hier_rtlmp.cpp +++ b/src/mpl2/src/hier_rtlmp.cpp @@ -147,10 +147,6 @@ void HierRTLMP::setHaloHeight(float halo_height) } // Options related to clustering -void HierRTLMP::setNumBundledIOsPerBoundary(int num_bundled_ios) -{ - tree_->bundled_ios_per_edge = num_bundled_ios; -} void HierRTLMP::setClusterSize(int max_num_macro, int min_num_macro, @@ -244,7 +240,7 @@ void HierRTLMP::setReportDirectory(const char* report_directory) // b) Placement of Macros (one macro cluster at a time). // 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. +// overlap with either pin access blockages or other macros. // 6) Orientation Improvement // Attempts macro flipping to improve WR. void HierRTLMP::run() @@ -362,7 +358,7 @@ void HierRTLMP::runCoarseShaping() calculateChildrenTilings(tree_->root.get()); - setIOClustersBlockages(); + setPinAccessBlockages(); setPlacementBlockages(); } @@ -926,10 +922,7 @@ void HierRTLMP::setTightPackingTilings(Cluster* macro_array) macro_array->setMacroTilings(tight_packing_tilings); } -/* - TO DO: Change name to pin_access blockages -*/ -void HierRTLMP::setIOClustersBlockages() +void HierRTLMP::setPinAccessBlockages() { if (!tree_->maps.bterm_to_inst.empty()) { return; @@ -938,7 +931,7 @@ void HierRTLMP::setIOClustersBlockages() std::vector io_clusters = getIOClusters(); const Rect die = dbuToMicrons(block_->getDieArea()); - const float depth = computeIOBlockagesDepth(io_clusters, die); + const float depth = computePinAccessBlockagesDepth(io_clusters, die); for (Cluster* io_cluster : io_clusters) { Boundary constraint_boundary = io_cluster->getConstraintBoundary(); @@ -946,7 +939,7 @@ void HierRTLMP::setIOClustersBlockages() } if (boundary_to_io_blockage_.empty()) { - // If there are no constraints at all, give freedom to SA so it + // If there are no constraints at all, give freedom to SA so it // doesn't have to deal with pin access blockages in all boundaries. // This will help SA not relying on extreme utilizations to // converge for designs such as sky130hd/uW. @@ -956,31 +949,27 @@ void HierRTLMP::setIOClustersBlockages() // There are only -exclude constraints, so we create pin access // blockages based on the boundaries that are not blocked. - if (tree_->blocked_boundaries.find(L) - == tree_->blocked_boundaries.end()) { + if (tree_->blocked_boundaries.find(L) == tree_->blocked_boundaries.end()) { createPinAccessBlockage(L, depth, die); } - if (tree_->blocked_boundaries.find(R) - == tree_->blocked_boundaries.end()) { + if (tree_->blocked_boundaries.find(R) == tree_->blocked_boundaries.end()) { createPinAccessBlockage(R, depth, die); } - if (tree_->blocked_boundaries.find(B) - == tree_->blocked_boundaries.end()) { + if (tree_->blocked_boundaries.find(B) == tree_->blocked_boundaries.end()) { createPinAccessBlockage(B, depth, die); } - if (tree_->blocked_boundaries.find(T) - == tree_->blocked_boundaries.end()) { + if (tree_->blocked_boundaries.find(T) == tree_->blocked_boundaries.end()) { createPinAccessBlockage(T, depth, die); } } } void HierRTLMP::createPinAccessBlockage(Boundary constraint_boundary, - const float depth, - const Rect& die) + const float depth, + const Rect& die) { if (constraint_boundary == L) { const Rect left_io_blockage( @@ -1024,11 +1013,12 @@ std::vector HierRTLMP::getIOClusters() return io_clusters; } -// The depth of IO clusters' blockages is generated based on: +// The depth of pin access blockages is computed based on: // 1) Amount of std cell area in the design. // 2) Extension of the IO clusters across the design's boundaries. -float HierRTLMP::computeIOBlockagesDepth(std::vector io_clusters, - const Rect& die) +float HierRTLMP::computePinAccessBlockagesDepth( + std::vector io_clusters, + const Rect& die) { float io_clusters_extension = 0.0; @@ -1065,7 +1055,7 @@ float HierRTLMP::computeIOBlockagesDepth(std::vector io_clusters, MPL, "coarse_shaping", 1, - "IO clusters blokaged depth = {}", + "Pin access blockages depth = {}", depth); return depth; @@ -1213,7 +1203,7 @@ void HierRTLMP::runHierarchicalMacroPlacement(Cluster* parent) findOverlappingBlockages(macro_blockages, placement_blockages, outline); - // We store the bundled io clusters to push them into the macros' vector + // We store the io clusters to push them into the macros' vector // only after it is already populated with the clusters we're trying to // place. This will facilitate how we deal with fixed terminals in SA moves. std::vector io_clusters; @@ -2197,7 +2187,7 @@ void HierRTLMP::runHierarchicalMacroPlacementWithoutBusPlanning(Cluster* parent) findOverlappingBlockages(macro_blockages, placement_blockages, outline); - // We store the bundled io clusters to push them into the macros' vector + // We store the io clusters to push them into the macros' vector // only after it is already populated with the clusters we're trying to // place. This will facilitate how we deal with fixed terminals in SA moves. std::vector io_clusters; @@ -2695,7 +2685,7 @@ void HierRTLMP::runEnhancedHierarchicalMacroPlacement(Cluster* parent) findOverlappingBlockages(macro_blockages, placement_blockages, outline); - // We store the bundled io clusters to push them into the macros' vector + // We store the io clusters to push them into the macros' vector // only after it is already populated with the clusters we're trying to // place. This will facilitate how we deal with fixed terminals in SA moves. std::vector io_clusters; diff --git a/src/mpl2/src/hier_rtlmp.h b/src/mpl2/src/hier_rtlmp.h index 734915a5747..f4b96a28ee8 100644 --- a/src/mpl2/src/hier_rtlmp.h +++ b/src/mpl2/src/hier_rtlmp.h @@ -103,7 +103,6 @@ class HierRTLMP void setHaloHeight(float halo_height); // Hierarchical Clustering Related Options - void setNumBundledIOsPerBoundary(int num_bundled_ios); void setClusterSize(int max_num_macro, int min_num_macro, int max_num_inst, @@ -162,10 +161,10 @@ class HierRTLMP void calculateChildrenTilings(Cluster* parent); void calculateMacroTilings(Cluster* cluster); void setTightPackingTilings(Cluster* macro_array); - void setIOClustersBlockages(); + void setPinAccessBlockages(); std::vector getIOClusters(); - float computeIOBlockagesDepth(std::vector io_clusters, - const Rect& die); + float computePinAccessBlockagesDepth(std::vector io_clusters, + const Rect& die); void createPinAccessBlockage(Boundary constraint_boundary, float depth, const Rect& die); diff --git a/src/mpl2/src/mpl.i b/src/mpl2/src/mpl.i index 2604f2960b0..8df547c6817 100644 --- a/src/mpl2/src/mpl.i +++ b/src/mpl2/src/mpl.i @@ -63,7 +63,6 @@ bool rtl_macro_placer_cmd(const int max_num_macro, const float tolerance, const int max_num_level, const float coarsening_ratio, - const int num_bundled_ios, const int large_net_threshold, const int signature_net_threshold, const float halo_width, @@ -98,7 +97,6 @@ bool rtl_macro_placer_cmd(const int max_num_macro, tolerance, max_num_level, coarsening_ratio, - num_bundled_ios, large_net_threshold, signature_net_threshold, halo_width, diff --git a/src/mpl2/src/mpl.tcl b/src/mpl2/src/mpl.tcl index 81196eaf296..18260e40864 100644 --- a/src/mpl2/src/mpl.tcl +++ b/src/mpl2/src/mpl.tcl @@ -38,7 +38,6 @@ sta::define_cmd_args "rtl_macro_placer" { -max_num_macro max_num_macro \ -tolerance tolerance \ -max_num_level max_num_level \ -coarsening_ratio coarsening_ratio \ - -num_bundled_ios num_bundled_ios \ -large_net_threshold large_net_threshold \ -signature_net_threshold signature_net_threshold \ -halo_width halo_width \ @@ -67,7 +66,7 @@ sta::define_cmd_args "rtl_macro_placer" { -max_num_macro max_num_macro \ proc rtl_macro_placer { args } { sta::parse_key_args "rtl_macro_placer" args \ keys {-max_num_macro -min_num_macro -max_num_inst -min_num_inst -tolerance \ - -max_num_level -coarsening_ratio -num_bundled_ios -large_net_threshold \ + -max_num_level -coarsening_ratio -large_net_threshold \ -signature_net_threshold -halo_width -halo_height \ -fence_lx -fence_ly -fence_ux -fence_uy \ -area_weight -outline_weight -wirelength_weight -guidance_weight -fence_weight \ @@ -95,7 +94,6 @@ proc rtl_macro_placer { args } { set tolerance 0.1 set max_num_level 2 set coarsening_ratio 10.0 - set num_bundled_ios 3 set large_net_threshold 50 set signature_net_threshold 50 set halo_width 0.0 @@ -143,9 +141,6 @@ proc rtl_macro_placer { args } { if { [info exists keys(-coarsening_ratio)] } { set coarsening_ratio $keys(-coarsening_ratio) } - if { [info exists keys(-num_bundled_ios)] } { - set num_bundled_ios $keys(-num_bundled_ios) - } if { [info exists keys(-large_net_threshold)] } { set large_net_threshold $keys(-large_net_threshold) } @@ -232,7 +227,6 @@ proc rtl_macro_placer { args } { $tolerance \ $max_num_level \ $coarsening_ratio \ - $num_bundled_ios \ $large_net_threshold \ $signature_net_threshold \ $halo_width \ diff --git a/src/mpl2/src/object.cpp b/src/mpl2/src/object.cpp index 2ec73f9ce5c..6d217c32482 100644 --- a/src/mpl2/src/object.cpp +++ b/src/mpl2/src/object.cpp @@ -263,7 +263,7 @@ std::string Cluster::getClusterTypeString() const std::string cluster_type; if (is_io_cluster_) { - return "BundledIO"; + return "IO"; } switch (type_) { diff --git a/src/mpl2/src/object.h b/src/mpl2/src/object.h index 5684e98bc7e..b618be9ff66 100644 --- a/src/mpl2/src/object.h +++ b/src/mpl2/src/object.h @@ -300,7 +300,11 @@ class Cluster // all the macros in the cluster std::vector hard_macros_; - // We model bundled IOS (Pads) as a cluster with no area + /* + TO DO: CHECK THIS COMMENT BELOW + */ + + // We model pads as clusters with no area // The position be the center of IOs bool is_io_cluster_ = false; Boundary constraint_boundary_ = NONE; diff --git a/src/mpl2/src/rtl_mp.cpp b/src/mpl2/src/rtl_mp.cpp index 1f5c50ad333..44a82e5fbb7 100644 --- a/src/mpl2/src/rtl_mp.cpp +++ b/src/mpl2/src/rtl_mp.cpp @@ -69,7 +69,6 @@ bool MacroPlacer2::place(const int num_threads, const float tolerance, const int max_num_level, const float coarsening_ratio, - const int num_bundled_ios, const int large_net_threshold, const int signature_net_threshold, const float halo_width, @@ -99,7 +98,6 @@ bool MacroPlacer2::place(const int num_threads, hier_rtlmp_->setClusterSizeTolerance(tolerance); hier_rtlmp_->setMaxNumLevel(max_num_level); hier_rtlmp_->setClusterSizeRatioPerLevel(coarsening_ratio); - hier_rtlmp_->setNumBundledIOsPerBoundary(num_bundled_ios); hier_rtlmp_->setLargeNetThreshold(large_net_threshold); hier_rtlmp_->setSignatureNetThreshold(signature_net_threshold); hier_rtlmp_->setHaloWidth(halo_width); From 6fe6636b15cb8c86dd99a1b009eeff81d62db06f Mon Sep 17 00:00:00 2001 From: Arthur Koucher Date: Wed, 25 Sep 2024 12:41:11 -0300 Subject: [PATCH 29/38] mpl2: use constraint region instead of pin location in orient improvement Signed-off-by: Arthur Koucher --- src/mpl2/src/hier_rtlmp.cpp | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/src/mpl2/src/hier_rtlmp.cpp b/src/mpl2/src/hier_rtlmp.cpp index 459ade253fa..22434a7bb29 100644 --- a/src/mpl2/src/hier_rtlmp.cpp +++ b/src/mpl2/src/hier_rtlmp.cpp @@ -3927,8 +3927,30 @@ float HierRTLMP::calculateRealMacroWirelength(odb::dbInst* macro) odb::dbNet* net = iterm->getNet(); if (net != nullptr) { - const odb::Rect bbox = net->getTermBBox(); - wirelength += block_->dbuToMicrons(bbox.dx() + bbox.dy()); + // Mimic dbNet::getTermBBox() behavior, but considering + // the pin constraint region instead of its position. + odb::Rect net_box; + net_box.mergeInit(); + + for (odb::dbITerm* iterm : net->getITerms()) { + int x, y; + if (iterm->getAvgXY(&x, &y)) { + odb::Rect iterm_rect(x, y, x , y); + net_box.merge(iterm_rect); + } + } + + for (odb::dbBTerm* bterm : net->getBTerms()) { + auto constraint_region = bterm->getConstraintRegion(); + if (constraint_region) { + int x = constraint_region->xCenter(); + int y = constraint_region->yCenter(); + odb::Rect region_rect(x, y, x, y); + net_box.merge(region_rect); + } + } + + wirelength += block_->dbuToMicrons(net_box.dx() + net_box.dy()); } } From d5281b8d0dde795c20b3c0b1525cf512777823f8 Mon Sep 17 00:00:00 2001 From: Arthur Koucher Date: Wed, 25 Sep 2024 17:09:10 -0300 Subject: [PATCH 30/38] mpl2: clean TO DOs and adjust tree log Signed-off-by: Arthur Koucher --- src/mpl2/src/bus_synthesis.h | 9 --------- src/mpl2/src/clusterEngine.cpp | 37 +++++++++++++++++++++++----------- src/mpl2/src/graphics.cpp | 6 ------ src/mpl2/src/hier_rtlmp.cpp | 10 --------- src/mpl2/src/object.h | 4 ---- 5 files changed, 25 insertions(+), 41 deletions(-) diff --git a/src/mpl2/src/bus_synthesis.h b/src/mpl2/src/bus_synthesis.h index 1915d933ca3..97e7146026c 100644 --- a/src/mpl2/src/bus_synthesis.h +++ b/src/mpl2/src/bus_synthesis.h @@ -46,11 +46,6 @@ namespace mpl2 { using Point = std::pair; -/* - TO DO: What can be done here now that bundled IOs are gone? (Perhaps, - there's no problem, because the vertex idea is still the same) -*/ - // Each point in the hanan grid is represented by a vertex (with no size) // And each bundled IO pin is represented by a vertex struct Vertex @@ -72,10 +67,6 @@ struct Vertex // position of the vertex Point pos; - /* - TO DO: Ditto - */ - // The weight of the vertex : macro utilization of the SoftMacro // which the vertex belongs to. For bundled IO pin, we set the // macro utilization to be zero diff --git a/src/mpl2/src/clusterEngine.cpp b/src/mpl2/src/clusterEngine.cpp index 5a76be8cfea..993be5d335a 100644 --- a/src/mpl2/src/clusterEngine.cpp +++ b/src/mpl2/src/clusterEngine.cpp @@ -2086,18 +2086,31 @@ void ClusteringEngine::printPhysicalHierarchyTree(Cluster* parent, int level) for (int i = 0; i < level; i++) { line += "+---"; } - line += fmt::format( - "{} ({}) num_macro : {} num_std_cell : {}" - " macro_area : {} std_cell_area : {} cluster type: {} {}", - parent->getName(), - parent->getId(), - parent->getNumMacro(), - parent->getNumStdCell(), - parent->getMacroArea(), - parent->getStdCellArea(), - parent->getIsLeafString(), - parent->getClusterTypeString()); - logger_->report("{}", line); + + line += fmt::format("{} ({}) Type: {}", + parent->getName(), + parent->getId(), + parent->getClusterTypeString()); + + if (parent->isIOCluster()) { + int number_of_pins = 0; + for (const auto [pin, cluster_id] : tree_->maps.bterm_to_cluster_id) { + if (cluster_id == parent->getId()) { + ++number_of_pins; + } + } + + line += fmt::format(" Pins: {}", number_of_pins); + } else { + line += fmt::format(" {}, StdCells: {} ({} μ²), Macros: {} ({} μ²)", + parent->getIsLeafString(), + parent->getNumStdCell(), + parent->getStdCellArea(), + parent->getNumMacro(), + parent->getMacroArea()); + } + + logger_->report("{}", line); for (auto& cluster : parent->getChildren()) { printPhysicalHierarchyTree(cluster.get(), level + 1); diff --git a/src/mpl2/src/graphics.cpp b/src/mpl2/src/graphics.cpp index 0ee609e63fa..7dd80b702ae 100644 --- a/src/mpl2/src/graphics.cpp +++ b/src/mpl2/src/graphics.cpp @@ -613,12 +613,6 @@ bool Graphics::isOutsideTheOutline(const T& macro) const || block_->micronsToDbu(macro.getPinY()) > outline_.dy(); } -/* - TO DO: - 1. See if some sort of offset dark magic interferes - with the annealing internals. -*/ - // Here, we have to manually decompensate the offset of the // coordinates that come from the cluster. template diff --git a/src/mpl2/src/hier_rtlmp.cpp b/src/mpl2/src/hier_rtlmp.cpp index 22434a7bb29..fef152e692a 100644 --- a/src/mpl2/src/hier_rtlmp.cpp +++ b/src/mpl2/src/hier_rtlmp.cpp @@ -215,16 +215,6 @@ void HierRTLMP::setReportDirectory(const char* report_directory) report_directory_ = report_directory; } -/* - TO DO: - 1. Remove all "bundledIO related things" - 2. Add IO count to preamble and display it in the tree for - clustering debug level - 3. See how are we going to make sure that the orientantion - improvement does the right thing, now that we don't have - placed pins? -*/ - // Top Level Function // The flow of our MacroPlacer is divided into 6 stages. // 1) Multilevel Autoclustering: diff --git a/src/mpl2/src/object.h b/src/mpl2/src/object.h index b618be9ff66..a29f4c84e4b 100644 --- a/src/mpl2/src/object.h +++ b/src/mpl2/src/object.h @@ -300,10 +300,6 @@ class Cluster // all the macros in the cluster std::vector hard_macros_; - /* - TO DO: CHECK THIS COMMENT BELOW - */ - // We model pads as clusters with no area // The position be the center of IOs bool is_io_cluster_ = false; From ede06cd7d041d0509b11d1bb88bb55481d85bedc Mon Sep 17 00:00:00 2001 From: Arthur Koucher Date: Thu, 26 Sep 2024 11:22:18 -0300 Subject: [PATCH 31/38] mpl2: address clang-tidy and format Signed-off-by: Arthur Koucher --- src/mpl2/src/SimulatedAnnealingCore.h | 2 +- src/mpl2/src/clusterEngine.cpp | 12 +++++++----- src/mpl2/src/clusterEngine.h | 4 ++-- src/mpl2/src/hier_rtlmp.cpp | 4 ++-- src/mpl2/src/hier_rtlmp.h | 2 +- 5 files changed, 13 insertions(+), 11 deletions(-) diff --git a/src/mpl2/src/SimulatedAnnealingCore.h b/src/mpl2/src/SimulatedAnnealingCore.h index 0967d772eb4..a08e6d94fb8 100644 --- a/src/mpl2/src/SimulatedAnnealingCore.h +++ b/src/mpl2/src/SimulatedAnnealingCore.h @@ -142,7 +142,7 @@ class SimulatedAnnealingCore void calWirelength(); void addBoundaryDistToWirelength(const T& macro, const T& io, - const float net_weight); + float net_weight); bool isOutsideTheOutline(const T& macro) const; void calGuidancePenalty(); void calFencePenalty(); diff --git a/src/mpl2/src/clusterEngine.cpp b/src/mpl2/src/clusterEngine.cpp index 993be5d335a..1258a4627ff 100644 --- a/src/mpl2/src/clusterEngine.cpp +++ b/src/mpl2/src/clusterEngine.cpp @@ -369,19 +369,21 @@ Boundary ClusteringEngine::getConstraintBoundary( const odb::Rect& die, const odb::Rect& constraint_region) { + Boundary constraint_boundary = NONE; if (constraint_region.xMin() == constraint_region.xMax()) { if (constraint_region.xMin() == die.xMin()) { - return L; + constraint_boundary = L; } else { - return R; + constraint_boundary = R; } } else { if (constraint_region.yMin() == die.yMin()) { - return B; + constraint_boundary = B; } else { - return T; + constraint_boundary = T; } } + return constraint_boundary; } void ClusteringEngine::createIOCluster( @@ -2110,7 +2112,7 @@ void ClusteringEngine::printPhysicalHierarchyTree(Cluster* parent, int level) parent->getMacroArea()); } - logger_->report("{}", line); + logger_->report("{}", line); for (auto& cluster : parent->getChildren()) { printPhysicalHierarchyTree(cluster.get(), level + 1); diff --git a/src/mpl2/src/clusterEngine.h b/src/mpl2/src/clusterEngine.h index 5adbc3815a6..29122bbd386 100644 --- a/src/mpl2/src/clusterEngine.h +++ b/src/mpl2/src/clusterEngine.h @@ -188,11 +188,11 @@ class ClusteringEngine Boundary getConstraintBoundary(const odb::Rect& die, const odb::Rect& constraint_region); void createIOCluster(const odb::Rect& die, - const Boundary constraint_boundary, + Boundary constraint_boundary, std::map& boundary_to_cluster, odb::dbBTerm* bterm); void setIOClusterDimensions(const odb::Rect& die, - const Boundary boundary, + Boundary boundary, int& x, int& y, int& width, diff --git a/src/mpl2/src/hier_rtlmp.cpp b/src/mpl2/src/hier_rtlmp.cpp index fef152e692a..20af20b0f9a 100644 --- a/src/mpl2/src/hier_rtlmp.cpp +++ b/src/mpl2/src/hier_rtlmp.cpp @@ -1007,7 +1007,7 @@ std::vector HierRTLMP::getIOClusters() // 1) Amount of std cell area in the design. // 2) Extension of the IO clusters across the design's boundaries. float HierRTLMP::computePinAccessBlockagesDepth( - std::vector io_clusters, + const std::vector& io_clusters, const Rect& die) { float io_clusters_extension = 0.0; @@ -3925,7 +3925,7 @@ float HierRTLMP::calculateRealMacroWirelength(odb::dbInst* macro) for (odb::dbITerm* iterm : net->getITerms()) { int x, y; if (iterm->getAvgXY(&x, &y)) { - odb::Rect iterm_rect(x, y, x , y); + odb::Rect iterm_rect(x, y, x, y); net_box.merge(iterm_rect); } } diff --git a/src/mpl2/src/hier_rtlmp.h b/src/mpl2/src/hier_rtlmp.h index f4b96a28ee8..0fa2a16010c 100644 --- a/src/mpl2/src/hier_rtlmp.h +++ b/src/mpl2/src/hier_rtlmp.h @@ -163,7 +163,7 @@ class HierRTLMP void setTightPackingTilings(Cluster* macro_array); void setPinAccessBlockages(); std::vector getIOClusters(); - float computePinAccessBlockagesDepth(std::vector io_clusters, + float computePinAccessBlockagesDepth(const std::vector& io_clusters, const Rect& die); void createPinAccessBlockage(Boundary constraint_boundary, float depth, From 85434877dee2acf72f6a3a74aea305a95a770c31 Mon Sep 17 00:00:00 2001 From: Arthur Koucher Date: Fri, 27 Sep 2024 15:07:05 -0300 Subject: [PATCH 32/38] mpl2: improve name and avoid clusters to be pushed toward blocked boundaries Signed-off-by: Arthur Koucher --- src/mpl2/src/SimulatedAnnealingCore.cpp | 7 ++++--- src/mpl2/src/clusterEngine.cpp | 5 +++-- src/mpl2/src/clusterEngine.h | 2 +- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/mpl2/src/SimulatedAnnealingCore.cpp b/src/mpl2/src/SimulatedAnnealingCore.cpp index a80a0906352..e100111a685 100644 --- a/src/mpl2/src/SimulatedAnnealingCore.cpp +++ b/src/mpl2/src/SimulatedAnnealingCore.cpp @@ -364,11 +364,12 @@ void SimulatedAnnealingCore::addBoundaryDistToWirelength( += net_weight * std::min( {dist_to_left, dist_to_right, dist_to_bottom, dist_to_top}); - } else if (constraint_boundary == Boundary::L - || constraint_boundary == Boundary::R) { + } else if (constraint_boundary == Boundary::L && !left_is_blocked_ + || constraint_boundary == Boundary::R && !right_is_blocked_) { const float x2 = io.getPinX(); wirelength_ += net_weight * std::abs(x2 - x1); - } else { // Top or Bottom + } else if (constraint_boundary == Boundary::T && !top_is_blocked_ + || constraint_boundary == Boundary::B && !bottom_is_blocked_) { const float y2 = io.getPinY(); wirelength_ += net_weight * std::abs(y2 - y1); } diff --git a/src/mpl2/src/clusterEngine.cpp b/src/mpl2/src/clusterEngine.cpp index 1258a4627ff..3fe836af16f 100644 --- a/src/mpl2/src/clusterEngine.cpp +++ b/src/mpl2/src/clusterEngine.cpp @@ -417,7 +417,8 @@ void ClusteringEngine::createIOCluster( void ClusteringEngine::setBlockedBoundariesForIOs() { const float blocked_boundary_threshold = 0.7; - std::map blockage_extension_map = getBlockageExtensionMap(); + std::map blockage_extension_map + = computeBlockageExtensionMap(); for (const auto [boundary, blockage_extension] : blockage_extension_map) { if (blockage_extension >= blocked_boundary_threshold) { @@ -428,7 +429,7 @@ void ClusteringEngine::setBlockedBoundariesForIOs() // Computes how much blocked each boundary is for IOs base on PPL exclude // contraints. -std::map ClusteringEngine::getBlockageExtensionMap() +std::map ClusteringEngine::computeBlockageExtensionMap() { std::map blockage_extension_map; diff --git a/src/mpl2/src/clusterEngine.h b/src/mpl2/src/clusterEngine.h index 29122bbd386..803b757f167 100644 --- a/src/mpl2/src/clusterEngine.h +++ b/src/mpl2/src/clusterEngine.h @@ -184,7 +184,7 @@ class ClusteringEngine void setBaseThresholds(); void createIOClusters(); void setBlockedBoundariesForIOs(); - std::map getBlockageExtensionMap(); + std::map computeBlockageExtensionMap(); Boundary getConstraintBoundary(const odb::Rect& die, const odb::Rect& constraint_region); void createIOCluster(const odb::Rect& die, From baf2d13b9aea9fd1e951d4423c274a94fb6179d2 Mon Sep 17 00:00:00 2001 From: Arthur Koucher Date: Fri, 27 Sep 2024 15:16:55 -0300 Subject: [PATCH 33/38] mpl2: separate logical operations with parenthesis (clang-tidy) Signed-off-by: Arthur Koucher --- src/mpl2/src/SimulatedAnnealingCore.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/mpl2/src/SimulatedAnnealingCore.cpp b/src/mpl2/src/SimulatedAnnealingCore.cpp index e100111a685..0133bf51993 100644 --- a/src/mpl2/src/SimulatedAnnealingCore.cpp +++ b/src/mpl2/src/SimulatedAnnealingCore.cpp @@ -364,12 +364,12 @@ void SimulatedAnnealingCore::addBoundaryDistToWirelength( += net_weight * std::min( {dist_to_left, dist_to_right, dist_to_bottom, dist_to_top}); - } else if (constraint_boundary == Boundary::L && !left_is_blocked_ - || constraint_boundary == Boundary::R && !right_is_blocked_) { + } else if ((constraint_boundary == Boundary::L && !left_is_blocked_) + || (constraint_boundary == Boundary::R && !right_is_blocked_)) { const float x2 = io.getPinX(); wirelength_ += net_weight * std::abs(x2 - x1); - } else if (constraint_boundary == Boundary::T && !top_is_blocked_ - || constraint_boundary == Boundary::B && !bottom_is_blocked_) { + } else if ((constraint_boundary == Boundary::T && !top_is_blocked_) + || (constraint_boundary == Boundary::B && !bottom_is_blocked_)) { const float y2 = io.getPinY(); wirelength_ += net_weight * std::abs(y2 - y1); } From fa767e1fcd395dee6738083aeee2e6232776b015 Mon Sep 17 00:00:00 2001 From: Arthur Koucher Date: Tue, 1 Oct 2024 11:44:12 -0300 Subject: [PATCH 34/38] mpl2: add regression test && avoid zero depth blockages when root has no std cell children Signed-off-by: Arthur Koucher --- src/mpl2/src/hier_rtlmp.cpp | 8 + src/mpl2/test/io_constraints1.defok | 538 ++++++++++++++++++++ src/mpl2/test/io_constraints1.ok | 30 ++ src/mpl2/test/io_constraints1.tcl | 26 + src/mpl2/test/regression_tests.tcl | 1 + src/mpl2/test/testcases/io_constraints1.def | 526 +++++++++++++++++++ src/mpl2/test/testcases/io_constraints1.v | 409 +++++++++++++++ 7 files changed, 1538 insertions(+) create mode 100644 src/mpl2/test/io_constraints1.defok create mode 100644 src/mpl2/test/io_constraints1.ok create mode 100644 src/mpl2/test/io_constraints1.tcl create mode 100644 src/mpl2/test/testcases/io_constraints1.def create mode 100644 src/mpl2/test/testcases/io_constraints1.v diff --git a/src/mpl2/src/hier_rtlmp.cpp b/src/mpl2/src/hier_rtlmp.cpp index 20af20b0f9a..fad7584d958 100644 --- a/src/mpl2/src/hier_rtlmp.cpp +++ b/src/mpl2/src/hier_rtlmp.cpp @@ -1035,6 +1035,14 @@ float HierRTLMP::computePinAccessBlockagesDepth( } } + if (std_cell_area == 0.0) { + for (auto& cluster : tree_->root->getChildren()) { + if (cluster->getClusterType() == MixedCluster) { + std_cell_area += cluster->getArea(); + } + } + } + const float macro_dominance_factor = tree_->macro_with_halo_area / (tree_->root->getWidth() * tree_->root->getHeight()); diff --git a/src/mpl2/test/io_constraints1.defok b/src/mpl2/test/io_constraints1.defok new file mode 100644 index 00000000000..1cd34ff791b --- /dev/null +++ b/src/mpl2/test/io_constraints1.defok @@ -0,0 +1,538 @@ +VERSION 5.8 ; +DIVIDERCHAR "/" ; +BUSBITCHARS "[]" ; +DESIGN io_constraints1 ; +UNITS DISTANCE MICRONS 2000 ; +DIEAREA ( 0 0 ) ( 300000 250000 ) ; +ROW ROW_0 FreePDK45_38x28_10R_NP_162NW_34O 0 0 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_1 FreePDK45_38x28_10R_NP_162NW_34O 0 2800 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_2 FreePDK45_38x28_10R_NP_162NW_34O 0 5600 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_3 FreePDK45_38x28_10R_NP_162NW_34O 0 8400 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_4 FreePDK45_38x28_10R_NP_162NW_34O 0 11200 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_5 FreePDK45_38x28_10R_NP_162NW_34O 0 14000 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_6 FreePDK45_38x28_10R_NP_162NW_34O 0 16800 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_7 FreePDK45_38x28_10R_NP_162NW_34O 0 19600 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_8 FreePDK45_38x28_10R_NP_162NW_34O 0 22400 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_9 FreePDK45_38x28_10R_NP_162NW_34O 0 25200 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_10 FreePDK45_38x28_10R_NP_162NW_34O 0 28000 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_11 FreePDK45_38x28_10R_NP_162NW_34O 0 30800 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_12 FreePDK45_38x28_10R_NP_162NW_34O 0 33600 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_13 FreePDK45_38x28_10R_NP_162NW_34O 0 36400 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_14 FreePDK45_38x28_10R_NP_162NW_34O 0 39200 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_15 FreePDK45_38x28_10R_NP_162NW_34O 0 42000 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_16 FreePDK45_38x28_10R_NP_162NW_34O 0 44800 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_17 FreePDK45_38x28_10R_NP_162NW_34O 0 47600 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_18 FreePDK45_38x28_10R_NP_162NW_34O 0 50400 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_19 FreePDK45_38x28_10R_NP_162NW_34O 0 53200 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_20 FreePDK45_38x28_10R_NP_162NW_34O 0 56000 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_21 FreePDK45_38x28_10R_NP_162NW_34O 0 58800 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_22 FreePDK45_38x28_10R_NP_162NW_34O 0 61600 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_23 FreePDK45_38x28_10R_NP_162NW_34O 0 64400 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_24 FreePDK45_38x28_10R_NP_162NW_34O 0 67200 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_25 FreePDK45_38x28_10R_NP_162NW_34O 0 70000 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_26 FreePDK45_38x28_10R_NP_162NW_34O 0 72800 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_27 FreePDK45_38x28_10R_NP_162NW_34O 0 75600 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_28 FreePDK45_38x28_10R_NP_162NW_34O 0 78400 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_29 FreePDK45_38x28_10R_NP_162NW_34O 0 81200 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_30 FreePDK45_38x28_10R_NP_162NW_34O 0 84000 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_31 FreePDK45_38x28_10R_NP_162NW_34O 0 86800 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_32 FreePDK45_38x28_10R_NP_162NW_34O 0 89600 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_33 FreePDK45_38x28_10R_NP_162NW_34O 0 92400 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_34 FreePDK45_38x28_10R_NP_162NW_34O 0 95200 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_35 FreePDK45_38x28_10R_NP_162NW_34O 0 98000 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_36 FreePDK45_38x28_10R_NP_162NW_34O 0 100800 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_37 FreePDK45_38x28_10R_NP_162NW_34O 0 103600 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_38 FreePDK45_38x28_10R_NP_162NW_34O 0 106400 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_39 FreePDK45_38x28_10R_NP_162NW_34O 0 109200 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_40 FreePDK45_38x28_10R_NP_162NW_34O 0 112000 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_41 FreePDK45_38x28_10R_NP_162NW_34O 0 114800 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_42 FreePDK45_38x28_10R_NP_162NW_34O 0 117600 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_43 FreePDK45_38x28_10R_NP_162NW_34O 0 120400 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_44 FreePDK45_38x28_10R_NP_162NW_34O 0 123200 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_45 FreePDK45_38x28_10R_NP_162NW_34O 0 126000 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_46 FreePDK45_38x28_10R_NP_162NW_34O 0 128800 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_47 FreePDK45_38x28_10R_NP_162NW_34O 0 131600 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_48 FreePDK45_38x28_10R_NP_162NW_34O 0 134400 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_49 FreePDK45_38x28_10R_NP_162NW_34O 0 137200 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_50 FreePDK45_38x28_10R_NP_162NW_34O 0 140000 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_51 FreePDK45_38x28_10R_NP_162NW_34O 0 142800 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_52 FreePDK45_38x28_10R_NP_162NW_34O 0 145600 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_53 FreePDK45_38x28_10R_NP_162NW_34O 0 148400 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_54 FreePDK45_38x28_10R_NP_162NW_34O 0 151200 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_55 FreePDK45_38x28_10R_NP_162NW_34O 0 154000 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_56 FreePDK45_38x28_10R_NP_162NW_34O 0 156800 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_57 FreePDK45_38x28_10R_NP_162NW_34O 0 159600 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_58 FreePDK45_38x28_10R_NP_162NW_34O 0 162400 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_59 FreePDK45_38x28_10R_NP_162NW_34O 0 165200 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_60 FreePDK45_38x28_10R_NP_162NW_34O 0 168000 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_61 FreePDK45_38x28_10R_NP_162NW_34O 0 170800 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_62 FreePDK45_38x28_10R_NP_162NW_34O 0 173600 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_63 FreePDK45_38x28_10R_NP_162NW_34O 0 176400 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_64 FreePDK45_38x28_10R_NP_162NW_34O 0 179200 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_65 FreePDK45_38x28_10R_NP_162NW_34O 0 182000 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_66 FreePDK45_38x28_10R_NP_162NW_34O 0 184800 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_67 FreePDK45_38x28_10R_NP_162NW_34O 0 187600 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_68 FreePDK45_38x28_10R_NP_162NW_34O 0 190400 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_69 FreePDK45_38x28_10R_NP_162NW_34O 0 193200 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_70 FreePDK45_38x28_10R_NP_162NW_34O 0 196000 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_71 FreePDK45_38x28_10R_NP_162NW_34O 0 198800 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_72 FreePDK45_38x28_10R_NP_162NW_34O 0 201600 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_73 FreePDK45_38x28_10R_NP_162NW_34O 0 204400 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_74 FreePDK45_38x28_10R_NP_162NW_34O 0 207200 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_75 FreePDK45_38x28_10R_NP_162NW_34O 0 210000 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_76 FreePDK45_38x28_10R_NP_162NW_34O 0 212800 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_77 FreePDK45_38x28_10R_NP_162NW_34O 0 215600 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_78 FreePDK45_38x28_10R_NP_162NW_34O 0 218400 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_79 FreePDK45_38x28_10R_NP_162NW_34O 0 221200 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_80 FreePDK45_38x28_10R_NP_162NW_34O 0 224000 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_81 FreePDK45_38x28_10R_NP_162NW_34O 0 226800 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_82 FreePDK45_38x28_10R_NP_162NW_34O 0 229600 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_83 FreePDK45_38x28_10R_NP_162NW_34O 0 232400 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_84 FreePDK45_38x28_10R_NP_162NW_34O 0 235200 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_85 FreePDK45_38x28_10R_NP_162NW_34O 0 238000 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_86 FreePDK45_38x28_10R_NP_162NW_34O 0 240800 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_87 FreePDK45_38x28_10R_NP_162NW_34O 0 243600 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_88 FreePDK45_38x28_10R_NP_162NW_34O 0 246400 N DO 789 BY 1 STEP 380 0 ; +TRACKS X 190 DO 2368 STEP 380 LAYER metal1 ; +TRACKS Y 140 DO 3214 STEP 280 LAYER metal1 ; +TRACKS X 190 DO 2368 STEP 380 LAYER metal2 ; +TRACKS Y 140 DO 3214 STEP 280 LAYER metal2 ; +TRACKS X 190 DO 2368 STEP 380 LAYER metal3 ; +TRACKS Y 140 DO 3214 STEP 280 LAYER metal3 ; +TRACKS X 190 DO 1607 STEP 560 LAYER metal4 ; +TRACKS Y 140 DO 1607 STEP 560 LAYER metal4 ; +TRACKS X 190 DO 1607 STEP 560 LAYER metal5 ; +TRACKS Y 140 DO 1607 STEP 560 LAYER metal5 ; +TRACKS X 190 DO 1607 STEP 560 LAYER metal6 ; +TRACKS Y 140 DO 1607 STEP 560 LAYER metal6 ; +TRACKS X 190 DO 563 STEP 1600 LAYER metal7 ; +TRACKS Y 140 DO 563 STEP 1600 LAYER metal7 ; +TRACKS X 190 DO 563 STEP 1600 LAYER metal8 ; +TRACKS Y 140 DO 563 STEP 1600 LAYER metal8 ; +TRACKS X 190 DO 282 STEP 3200 LAYER metal9 ; +TRACKS Y 140 DO 282 STEP 3200 LAYER metal9 ; +TRACKS X 190 DO 282 STEP 3200 LAYER metal10 ; +TRACKS Y 140 DO 282 STEP 3200 LAYER metal10 ; +COMPONENTS 401 ; + - MACRO_1 HM_100x100_1x1 + FIXED ( 91820 8010 ) S ; + - _001_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _002_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _003_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _004_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _005_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _006_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _007_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _008_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _009_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _010_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _011_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _012_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _013_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _014_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _015_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _016_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _017_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _018_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _019_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _020_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _021_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _022_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _023_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _024_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _025_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _026_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _027_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _028_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _029_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _030_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _031_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _032_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _033_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _034_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _035_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _036_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _037_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _038_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _039_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _040_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _041_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _042_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _043_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _044_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _045_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _046_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _047_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _048_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _049_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _050_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _051_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _052_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _053_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _054_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _055_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _056_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _057_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _058_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _059_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _060_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _061_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _062_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _063_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _064_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _065_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _066_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _067_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _068_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _069_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _070_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _071_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _072_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _073_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _074_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _075_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _076_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _077_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _078_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _079_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _080_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _081_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _082_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _083_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _084_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _085_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _086_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _087_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _088_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _089_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _090_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _091_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _092_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _093_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _094_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _095_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _096_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _097_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _098_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _099_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _100_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _101_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _102_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _103_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _104_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _105_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _106_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _107_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _108_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _109_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _110_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _111_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _112_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _113_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _114_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _115_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _116_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _117_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _118_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _119_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _120_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _121_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _122_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _123_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _124_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _125_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _126_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _127_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _128_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _129_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _130_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _131_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _132_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _133_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _134_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _135_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _136_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _137_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _138_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _139_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _140_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _141_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _142_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _143_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _144_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _145_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _146_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _147_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _148_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _149_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _150_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _151_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _152_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _153_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _154_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _155_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _156_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _157_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _158_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _159_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _160_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _161_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _162_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _163_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _164_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _165_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _166_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _167_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _168_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _169_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _170_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _171_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _172_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _173_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _174_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _175_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _176_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _177_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _178_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _179_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _180_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _181_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _182_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _183_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _184_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _185_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _186_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _187_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _188_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _189_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _190_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _191_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _192_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _193_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _194_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _195_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _196_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _197_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _198_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _199_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _200_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _201_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _202_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _203_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _204_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _205_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _206_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _207_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _208_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _209_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _210_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _211_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _212_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _213_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _214_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _215_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _216_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _217_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _218_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _219_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _220_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _221_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _222_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _223_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _224_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _225_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _226_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _227_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _228_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _229_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _230_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _231_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _232_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _233_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _234_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _235_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _236_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _237_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _238_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _239_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _240_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _241_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _242_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _243_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _244_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _245_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _246_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _247_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _248_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _249_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _250_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _251_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _252_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _253_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _254_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _255_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _256_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _257_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _258_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _259_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _260_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _261_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _262_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _263_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _264_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _265_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _266_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _267_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _268_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _269_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _270_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _271_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _272_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _273_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _274_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _275_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _276_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _277_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _278_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _279_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _280_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _281_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _282_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _283_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _284_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _285_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _286_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _287_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _288_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _289_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _290_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _291_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _292_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _293_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _294_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _295_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _296_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _297_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _298_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _299_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _300_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _301_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _302_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _303_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _304_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _305_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _306_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _307_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _308_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _309_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _310_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _311_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _312_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _313_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _314_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _315_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _316_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _317_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _318_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _319_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _320_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _321_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _322_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _323_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _324_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _325_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _326_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _327_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _328_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _329_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _330_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _331_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _332_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _333_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _334_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _335_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _336_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _337_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _338_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _339_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _340_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _341_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _342_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _343_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _344_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _345_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _346_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _347_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _348_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _349_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _350_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _351_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _352_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _353_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _354_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _355_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _356_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _357_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _358_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _359_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _360_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _361_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _362_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _363_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _364_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _365_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _366_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _367_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _368_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _369_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _370_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _371_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _372_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _373_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _374_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _375_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _376_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _377_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _378_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _379_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _380_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _381_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _382_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _383_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _384_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _385_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _386_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _387_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _388_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _389_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _390_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _391_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _392_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _393_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _394_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _395_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _396_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _397_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _398_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _399_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _400_ DFF_X1 + PLACED ( 38680 123234 ) N ; +END COMPONENTS +PINS 3 ; + - io_1 + NET io_1 + DIRECTION INPUT + USE SIGNAL + + PORT + + LAYER metal5 ( -140 -140 ) ( 140 140 ) + + PLACED ( 140 155820 ) N ; + - io_2 + NET io_2 + DIRECTION INPUT + USE SIGNAL + + PORT + + LAYER metal5 ( -140 -140 ) ( 140 140 ) + + PLACED ( 140 50540 ) N ; + - io_3 + NET io_3 + DIRECTION INPUT + USE SIGNAL + + PORT + + LAYER metal5 ( -140 -140 ) ( 140 140 ) + + PLACED ( 140 12460 ) N ; +END PINS +NETS 3 ; + - io_1 ( PIN io_1 ) + USE SIGNAL ; + - io_2 ( PIN io_2 ) + USE SIGNAL ; + - io_3 ( PIN io_3 ) + USE SIGNAL ; +END NETS +END DESIGN diff --git a/src/mpl2/test/io_constraints1.ok b/src/mpl2/test/io_constraints1.ok new file mode 100644 index 00000000000..9891520858b --- /dev/null +++ b/src/mpl2/test/io_constraints1.ok @@ -0,0 +1,30 @@ +[INFO ODB-0227] LEF file: ./Nangate45/Nangate45.lef, created 22 layers, 27 vias, 135 library cells +[INFO ODB-0227] LEF file: ./testcases/macro_only.lef, created 9 library cells +[WARNING STA-1171] ./testcases/macro_only.lib line 32, default_max_transition is 0.0. +[WARNING ORD-2011] LEF master DFF_X1 has no liberty cell. +[INFO ODB-0128] Design: io_constraints1 +[INFO ODB-0252] Updated 3 pins. +[INFO ODB-0253] Updated 401 components. +Found 1 macro blocks. +Using 2 tracks default min distance between IO pins. +[INFO PPL-0001] Number of slots 974 +[INFO PPL-0002] Number of I/O 3 +[INFO PPL-0003] Number of I/O w/sink 0 +[INFO PPL-0004] Number of I/O w/o sink 3 +[INFO PPL-0012] I/O nets HPWL: 0.00 um. +Floorplan Outline: (0.0, 0.0) (150.0, 125.0), Core Outline: (0.0, 0.0) (149.91, 124.6) + Number of std cell instances: 400 + Area of std cell instances: 1808.79 + Number of macros: 1 + Area of macros: 10000.00 + Halo width: 4.00 + Halo height: 4.00 + Area of macros with halos: 11664.00 + Area of std cell instances + Area of macros: 11808.79 + Core area: 18678.79 + Design Utilization: 0.63 + Core Utilization: 0.21 + Manufacturing Grid: 10 + +[WARNING MPL-0014] No Liberty data found for std cells. Continuing without dataflow. +No differences found. diff --git a/src/mpl2/test/io_constraints1.tcl b/src/mpl2/test/io_constraints1.tcl new file mode 100644 index 00000000000..d032e4a01e3 --- /dev/null +++ b/src/mpl2/test/io_constraints1.tcl @@ -0,0 +1,26 @@ +# Test if pin access blockage is generated correctly for a case +# with pins in a single boundary. +source "helpers.tcl" + +# We're not interested in the connections, so don't include the lib. +read_lef "./Nangate45/Nangate45.lef" + +read_lef "./testcases/macro_only.lef" +read_liberty "./testcases/macro_only.lib" + +read_verilog "./testcases/io_constraints1.v" +link_design "io_constraints1" + +read_def "./testcases/io_constraints1.def" -floorplan_initialize + +# Run random PPL to incorporate the constraints into ODB +set_io_pin_constraint -direction INPUT -region left:* +place_pins -annealing -random -hor_layers metal5 -ver_layer metal6 + +set_thread_count 0 +rtl_macro_placer -report_directory results/io_constraints1 -halo_width 4.0 + +set def_file [make_result_file io_constraints1.def] +write_def $def_file + +diff_files io_constraints1.defok $def_file \ No newline at end of file diff --git a/src/mpl2/test/regression_tests.tcl b/src/mpl2/test/regression_tests.tcl index 16585a3f170..6f18ef9bf88 100644 --- a/src/mpl2/test/regression_tests.tcl +++ b/src/mpl2/test/regression_tests.tcl @@ -1,6 +1,7 @@ record_tests { macro_only no_unfixed_macros + io_constraints1 #mpl2_man_tcl_check #mpl2_readme_msgs_check } diff --git a/src/mpl2/test/testcases/io_constraints1.def b/src/mpl2/test/testcases/io_constraints1.def new file mode 100644 index 00000000000..53b434d551d --- /dev/null +++ b/src/mpl2/test/testcases/io_constraints1.def @@ -0,0 +1,526 @@ +VERSION 5.8 ; +DIVIDERCHAR "/" ; +BUSBITCHARS "[]" ; +DESIGN io_constraints1 ; +UNITS DISTANCE MICRONS 2000 ; +DIEAREA ( 0 0 ) ( 300000 250000 ) ; +ROW ROW_0 FreePDK45_38x28_10R_NP_162NW_34O 0 0 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_1 FreePDK45_38x28_10R_NP_162NW_34O 0 2800 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_2 FreePDK45_38x28_10R_NP_162NW_34O 0 5600 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_3 FreePDK45_38x28_10R_NP_162NW_34O 0 8400 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_4 FreePDK45_38x28_10R_NP_162NW_34O 0 11200 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_5 FreePDK45_38x28_10R_NP_162NW_34O 0 14000 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_6 FreePDK45_38x28_10R_NP_162NW_34O 0 16800 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_7 FreePDK45_38x28_10R_NP_162NW_34O 0 19600 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_8 FreePDK45_38x28_10R_NP_162NW_34O 0 22400 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_9 FreePDK45_38x28_10R_NP_162NW_34O 0 25200 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_10 FreePDK45_38x28_10R_NP_162NW_34O 0 28000 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_11 FreePDK45_38x28_10R_NP_162NW_34O 0 30800 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_12 FreePDK45_38x28_10R_NP_162NW_34O 0 33600 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_13 FreePDK45_38x28_10R_NP_162NW_34O 0 36400 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_14 FreePDK45_38x28_10R_NP_162NW_34O 0 39200 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_15 FreePDK45_38x28_10R_NP_162NW_34O 0 42000 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_16 FreePDK45_38x28_10R_NP_162NW_34O 0 44800 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_17 FreePDK45_38x28_10R_NP_162NW_34O 0 47600 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_18 FreePDK45_38x28_10R_NP_162NW_34O 0 50400 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_19 FreePDK45_38x28_10R_NP_162NW_34O 0 53200 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_20 FreePDK45_38x28_10R_NP_162NW_34O 0 56000 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_21 FreePDK45_38x28_10R_NP_162NW_34O 0 58800 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_22 FreePDK45_38x28_10R_NP_162NW_34O 0 61600 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_23 FreePDK45_38x28_10R_NP_162NW_34O 0 64400 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_24 FreePDK45_38x28_10R_NP_162NW_34O 0 67200 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_25 FreePDK45_38x28_10R_NP_162NW_34O 0 70000 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_26 FreePDK45_38x28_10R_NP_162NW_34O 0 72800 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_27 FreePDK45_38x28_10R_NP_162NW_34O 0 75600 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_28 FreePDK45_38x28_10R_NP_162NW_34O 0 78400 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_29 FreePDK45_38x28_10R_NP_162NW_34O 0 81200 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_30 FreePDK45_38x28_10R_NP_162NW_34O 0 84000 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_31 FreePDK45_38x28_10R_NP_162NW_34O 0 86800 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_32 FreePDK45_38x28_10R_NP_162NW_34O 0 89600 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_33 FreePDK45_38x28_10R_NP_162NW_34O 0 92400 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_34 FreePDK45_38x28_10R_NP_162NW_34O 0 95200 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_35 FreePDK45_38x28_10R_NP_162NW_34O 0 98000 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_36 FreePDK45_38x28_10R_NP_162NW_34O 0 100800 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_37 FreePDK45_38x28_10R_NP_162NW_34O 0 103600 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_38 FreePDK45_38x28_10R_NP_162NW_34O 0 106400 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_39 FreePDK45_38x28_10R_NP_162NW_34O 0 109200 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_40 FreePDK45_38x28_10R_NP_162NW_34O 0 112000 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_41 FreePDK45_38x28_10R_NP_162NW_34O 0 114800 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_42 FreePDK45_38x28_10R_NP_162NW_34O 0 117600 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_43 FreePDK45_38x28_10R_NP_162NW_34O 0 120400 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_44 FreePDK45_38x28_10R_NP_162NW_34O 0 123200 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_45 FreePDK45_38x28_10R_NP_162NW_34O 0 126000 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_46 FreePDK45_38x28_10R_NP_162NW_34O 0 128800 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_47 FreePDK45_38x28_10R_NP_162NW_34O 0 131600 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_48 FreePDK45_38x28_10R_NP_162NW_34O 0 134400 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_49 FreePDK45_38x28_10R_NP_162NW_34O 0 137200 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_50 FreePDK45_38x28_10R_NP_162NW_34O 0 140000 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_51 FreePDK45_38x28_10R_NP_162NW_34O 0 142800 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_52 FreePDK45_38x28_10R_NP_162NW_34O 0 145600 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_53 FreePDK45_38x28_10R_NP_162NW_34O 0 148400 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_54 FreePDK45_38x28_10R_NP_162NW_34O 0 151200 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_55 FreePDK45_38x28_10R_NP_162NW_34O 0 154000 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_56 FreePDK45_38x28_10R_NP_162NW_34O 0 156800 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_57 FreePDK45_38x28_10R_NP_162NW_34O 0 159600 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_58 FreePDK45_38x28_10R_NP_162NW_34O 0 162400 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_59 FreePDK45_38x28_10R_NP_162NW_34O 0 165200 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_60 FreePDK45_38x28_10R_NP_162NW_34O 0 168000 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_61 FreePDK45_38x28_10R_NP_162NW_34O 0 170800 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_62 FreePDK45_38x28_10R_NP_162NW_34O 0 173600 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_63 FreePDK45_38x28_10R_NP_162NW_34O 0 176400 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_64 FreePDK45_38x28_10R_NP_162NW_34O 0 179200 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_65 FreePDK45_38x28_10R_NP_162NW_34O 0 182000 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_66 FreePDK45_38x28_10R_NP_162NW_34O 0 184800 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_67 FreePDK45_38x28_10R_NP_162NW_34O 0 187600 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_68 FreePDK45_38x28_10R_NP_162NW_34O 0 190400 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_69 FreePDK45_38x28_10R_NP_162NW_34O 0 193200 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_70 FreePDK45_38x28_10R_NP_162NW_34O 0 196000 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_71 FreePDK45_38x28_10R_NP_162NW_34O 0 198800 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_72 FreePDK45_38x28_10R_NP_162NW_34O 0 201600 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_73 FreePDK45_38x28_10R_NP_162NW_34O 0 204400 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_74 FreePDK45_38x28_10R_NP_162NW_34O 0 207200 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_75 FreePDK45_38x28_10R_NP_162NW_34O 0 210000 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_76 FreePDK45_38x28_10R_NP_162NW_34O 0 212800 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_77 FreePDK45_38x28_10R_NP_162NW_34O 0 215600 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_78 FreePDK45_38x28_10R_NP_162NW_34O 0 218400 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_79 FreePDK45_38x28_10R_NP_162NW_34O 0 221200 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_80 FreePDK45_38x28_10R_NP_162NW_34O 0 224000 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_81 FreePDK45_38x28_10R_NP_162NW_34O 0 226800 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_82 FreePDK45_38x28_10R_NP_162NW_34O 0 229600 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_83 FreePDK45_38x28_10R_NP_162NW_34O 0 232400 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_84 FreePDK45_38x28_10R_NP_162NW_34O 0 235200 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_85 FreePDK45_38x28_10R_NP_162NW_34O 0 238000 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_86 FreePDK45_38x28_10R_NP_162NW_34O 0 240800 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_87 FreePDK45_38x28_10R_NP_162NW_34O 0 243600 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_88 FreePDK45_38x28_10R_NP_162NW_34O 0 246400 N DO 789 BY 1 STEP 380 0 ; +TRACKS X 190 DO 2368 STEP 380 LAYER metal1 ; +TRACKS Y 140 DO 3214 STEP 280 LAYER metal1 ; +TRACKS X 190 DO 2368 STEP 380 LAYER metal2 ; +TRACKS Y 140 DO 3214 STEP 280 LAYER metal2 ; +TRACKS X 190 DO 2368 STEP 380 LAYER metal3 ; +TRACKS Y 140 DO 3214 STEP 280 LAYER metal3 ; +TRACKS X 190 DO 1607 STEP 560 LAYER metal4 ; +TRACKS Y 140 DO 1607 STEP 560 LAYER metal4 ; +TRACKS X 190 DO 1607 STEP 560 LAYER metal5 ; +TRACKS Y 140 DO 1607 STEP 560 LAYER metal5 ; +TRACKS X 190 DO 1607 STEP 560 LAYER metal6 ; +TRACKS Y 140 DO 1607 STEP 560 LAYER metal6 ; +TRACKS X 190 DO 563 STEP 1600 LAYER metal7 ; +TRACKS Y 140 DO 563 STEP 1600 LAYER metal7 ; +TRACKS X 190 DO 563 STEP 1600 LAYER metal8 ; +TRACKS Y 140 DO 563 STEP 1600 LAYER metal8 ; +TRACKS X 190 DO 282 STEP 3200 LAYER metal9 ; +TRACKS Y 140 DO 282 STEP 3200 LAYER metal9 ; +TRACKS X 190 DO 282 STEP 3200 LAYER metal10 ; +TRACKS Y 140 DO 282 STEP 3200 LAYER metal10 ; +COMPONENTS 401 ; + - MACRO_1 HM_100x100_1x1 ; + - _001_ DFF_X1 ; + - _002_ DFF_X1 ; + - _003_ DFF_X1 ; + - _004_ DFF_X1 ; + - _005_ DFF_X1 ; + - _006_ DFF_X1 ; + - _007_ DFF_X1 ; + - _008_ DFF_X1 ; + - _009_ DFF_X1 ; + - _010_ DFF_X1 ; + - _011_ DFF_X1 ; + - _012_ DFF_X1 ; + - _013_ DFF_X1 ; + - _014_ DFF_X1 ; + - _015_ DFF_X1 ; + - _016_ DFF_X1 ; + - _017_ DFF_X1 ; + - _018_ DFF_X1 ; + - _019_ DFF_X1 ; + - _020_ DFF_X1 ; + - _021_ DFF_X1 ; + - _022_ DFF_X1 ; + - _023_ DFF_X1 ; + - _024_ DFF_X1 ; + - _025_ DFF_X1 ; + - _026_ DFF_X1 ; + - _027_ DFF_X1 ; + - _028_ DFF_X1 ; + - _029_ DFF_X1 ; + - _030_ DFF_X1 ; + - _031_ DFF_X1 ; + - _032_ DFF_X1 ; + - _033_ DFF_X1 ; + - _034_ DFF_X1 ; + - _035_ DFF_X1 ; + - _036_ DFF_X1 ; + - _037_ DFF_X1 ; + - _038_ DFF_X1 ; + - _039_ DFF_X1 ; + - _040_ DFF_X1 ; + - _041_ DFF_X1 ; + - _042_ DFF_X1 ; + - _043_ DFF_X1 ; + - _044_ DFF_X1 ; + - _045_ DFF_X1 ; + - _046_ DFF_X1 ; + - _047_ DFF_X1 ; + - _048_ DFF_X1 ; + - _049_ DFF_X1 ; + - _050_ DFF_X1 ; + - _051_ DFF_X1 ; + - _052_ DFF_X1 ; + - _053_ DFF_X1 ; + - _054_ DFF_X1 ; + - _055_ DFF_X1 ; + - _056_ DFF_X1 ; + - _057_ DFF_X1 ; + - _058_ DFF_X1 ; + - _059_ DFF_X1 ; + - _060_ DFF_X1 ; + - _061_ DFF_X1 ; + - _062_ DFF_X1 ; + - _063_ DFF_X1 ; + - _064_ DFF_X1 ; + - _065_ DFF_X1 ; + - _066_ DFF_X1 ; + - _067_ DFF_X1 ; + - _068_ DFF_X1 ; + - _069_ DFF_X1 ; + - _070_ DFF_X1 ; + - _071_ DFF_X1 ; + - _072_ DFF_X1 ; + - _073_ DFF_X1 ; + - _074_ DFF_X1 ; + - _075_ DFF_X1 ; + - _076_ DFF_X1 ; + - _077_ DFF_X1 ; + - _078_ DFF_X1 ; + - _079_ DFF_X1 ; + - _080_ DFF_X1 ; + - _081_ DFF_X1 ; + - _082_ DFF_X1 ; + - _083_ DFF_X1 ; + - _084_ DFF_X1 ; + - _085_ DFF_X1 ; + - _086_ DFF_X1 ; + - _087_ DFF_X1 ; + - _088_ DFF_X1 ; + - _089_ DFF_X1 ; + - _090_ DFF_X1 ; + - _091_ DFF_X1 ; + - _092_ DFF_X1 ; + - _093_ DFF_X1 ; + - _094_ DFF_X1 ; + - _095_ DFF_X1 ; + - _096_ DFF_X1 ; + - _097_ DFF_X1 ; + - _098_ DFF_X1 ; + - _099_ DFF_X1 ; + - _100_ DFF_X1 ; + - _101_ DFF_X1 ; + - _102_ DFF_X1 ; + - _103_ DFF_X1 ; + - _104_ DFF_X1 ; + - _105_ DFF_X1 ; + - _106_ DFF_X1 ; + - _107_ DFF_X1 ; + - _108_ DFF_X1 ; + - _109_ DFF_X1 ; + - _110_ DFF_X1 ; + - _111_ DFF_X1 ; + - _112_ DFF_X1 ; + - _113_ DFF_X1 ; + - _114_ DFF_X1 ; + - _115_ DFF_X1 ; + - _116_ DFF_X1 ; + - _117_ DFF_X1 ; + - _118_ DFF_X1 ; + - _119_ DFF_X1 ; + - _120_ DFF_X1 ; + - _121_ DFF_X1 ; + - _122_ DFF_X1 ; + - _123_ DFF_X1 ; + - _124_ DFF_X1 ; + - _125_ DFF_X1 ; + - _126_ DFF_X1 ; + - _127_ DFF_X1 ; + - _128_ DFF_X1 ; + - _129_ DFF_X1 ; + - _130_ DFF_X1 ; + - _131_ DFF_X1 ; + - _132_ DFF_X1 ; + - _133_ DFF_X1 ; + - _134_ DFF_X1 ; + - _135_ DFF_X1 ; + - _136_ DFF_X1 ; + - _137_ DFF_X1 ; + - _138_ DFF_X1 ; + - _139_ DFF_X1 ; + - _140_ DFF_X1 ; + - _141_ DFF_X1 ; + - _142_ DFF_X1 ; + - _143_ DFF_X1 ; + - _144_ DFF_X1 ; + - _145_ DFF_X1 ; + - _146_ DFF_X1 ; + - _147_ DFF_X1 ; + - _148_ DFF_X1 ; + - _149_ DFF_X1 ; + - _150_ DFF_X1 ; + - _151_ DFF_X1 ; + - _152_ DFF_X1 ; + - _153_ DFF_X1 ; + - _154_ DFF_X1 ; + - _155_ DFF_X1 ; + - _156_ DFF_X1 ; + - _157_ DFF_X1 ; + - _158_ DFF_X1 ; + - _159_ DFF_X1 ; + - _160_ DFF_X1 ; + - _161_ DFF_X1 ; + - _162_ DFF_X1 ; + - _163_ DFF_X1 ; + - _164_ DFF_X1 ; + - _165_ DFF_X1 ; + - _166_ DFF_X1 ; + - _167_ DFF_X1 ; + - _168_ DFF_X1 ; + - _169_ DFF_X1 ; + - _170_ DFF_X1 ; + - _171_ DFF_X1 ; + - _172_ DFF_X1 ; + - _173_ DFF_X1 ; + - _174_ DFF_X1 ; + - _175_ DFF_X1 ; + - _176_ DFF_X1 ; + - _177_ DFF_X1 ; + - _178_ DFF_X1 ; + - _179_ DFF_X1 ; + - _180_ DFF_X1 ; + - _181_ DFF_X1 ; + - _182_ DFF_X1 ; + - _183_ DFF_X1 ; + - _184_ DFF_X1 ; + - _185_ DFF_X1 ; + - _186_ DFF_X1 ; + - _187_ DFF_X1 ; + - _188_ DFF_X1 ; + - _189_ DFF_X1 ; + - _190_ DFF_X1 ; + - _191_ DFF_X1 ; + - _192_ DFF_X1 ; + - _193_ DFF_X1 ; + - _194_ DFF_X1 ; + - _195_ DFF_X1 ; + - _196_ DFF_X1 ; + - _197_ DFF_X1 ; + - _198_ DFF_X1 ; + - _199_ DFF_X1 ; + - _200_ DFF_X1 ; + - _201_ DFF_X1 ; + - _202_ DFF_X1 ; + - _203_ DFF_X1 ; + - _204_ DFF_X1 ; + - _205_ DFF_X1 ; + - _206_ DFF_X1 ; + - _207_ DFF_X1 ; + - _208_ DFF_X1 ; + - _209_ DFF_X1 ; + - _210_ DFF_X1 ; + - _211_ DFF_X1 ; + - _212_ DFF_X1 ; + - _213_ DFF_X1 ; + - _214_ DFF_X1 ; + - _215_ DFF_X1 ; + - _216_ DFF_X1 ; + - _217_ DFF_X1 ; + - _218_ DFF_X1 ; + - _219_ DFF_X1 ; + - _220_ DFF_X1 ; + - _221_ DFF_X1 ; + - _222_ DFF_X1 ; + - _223_ DFF_X1 ; + - _224_ DFF_X1 ; + - _225_ DFF_X1 ; + - _226_ DFF_X1 ; + - _227_ DFF_X1 ; + - _228_ DFF_X1 ; + - _229_ DFF_X1 ; + - _230_ DFF_X1 ; + - _231_ DFF_X1 ; + - _232_ DFF_X1 ; + - _233_ DFF_X1 ; + - _234_ DFF_X1 ; + - _235_ DFF_X1 ; + - _236_ DFF_X1 ; + - _237_ DFF_X1 ; + - _238_ DFF_X1 ; + - _239_ DFF_X1 ; + - _240_ DFF_X1 ; + - _241_ DFF_X1 ; + - _242_ DFF_X1 ; + - _243_ DFF_X1 ; + - _244_ DFF_X1 ; + - _245_ DFF_X1 ; + - _246_ DFF_X1 ; + - _247_ DFF_X1 ; + - _248_ DFF_X1 ; + - _249_ DFF_X1 ; + - _250_ DFF_X1 ; + - _251_ DFF_X1 ; + - _252_ DFF_X1 ; + - _253_ DFF_X1 ; + - _254_ DFF_X1 ; + - _255_ DFF_X1 ; + - _256_ DFF_X1 ; + - _257_ DFF_X1 ; + - _258_ DFF_X1 ; + - _259_ DFF_X1 ; + - _260_ DFF_X1 ; + - _261_ DFF_X1 ; + - _262_ DFF_X1 ; + - _263_ DFF_X1 ; + - _264_ DFF_X1 ; + - _265_ DFF_X1 ; + - _266_ DFF_X1 ; + - _267_ DFF_X1 ; + - _268_ DFF_X1 ; + - _269_ DFF_X1 ; + - _270_ DFF_X1 ; + - _271_ DFF_X1 ; + - _272_ DFF_X1 ; + - _273_ DFF_X1 ; + - _274_ DFF_X1 ; + - _275_ DFF_X1 ; + - _276_ DFF_X1 ; + - _277_ DFF_X1 ; + - _278_ DFF_X1 ; + - _279_ DFF_X1 ; + - _280_ DFF_X1 ; + - _281_ DFF_X1 ; + - _282_ DFF_X1 ; + - _283_ DFF_X1 ; + - _284_ DFF_X1 ; + - _285_ DFF_X1 ; + - _286_ DFF_X1 ; + - _287_ DFF_X1 ; + - _288_ DFF_X1 ; + - _289_ DFF_X1 ; + - _290_ DFF_X1 ; + - _291_ DFF_X1 ; + - _292_ DFF_X1 ; + - _293_ DFF_X1 ; + - _294_ DFF_X1 ; + - _295_ DFF_X1 ; + - _296_ DFF_X1 ; + - _297_ DFF_X1 ; + - _298_ DFF_X1 ; + - _299_ DFF_X1 ; + - _300_ DFF_X1 ; + - _301_ DFF_X1 ; + - _302_ DFF_X1 ; + - _303_ DFF_X1 ; + - _304_ DFF_X1 ; + - _305_ DFF_X1 ; + - _306_ DFF_X1 ; + - _307_ DFF_X1 ; + - _308_ DFF_X1 ; + - _309_ DFF_X1 ; + - _310_ DFF_X1 ; + - _311_ DFF_X1 ; + - _312_ DFF_X1 ; + - _313_ DFF_X1 ; + - _314_ DFF_X1 ; + - _315_ DFF_X1 ; + - _316_ DFF_X1 ; + - _317_ DFF_X1 ; + - _318_ DFF_X1 ; + - _319_ DFF_X1 ; + - _320_ DFF_X1 ; + - _321_ DFF_X1 ; + - _322_ DFF_X1 ; + - _323_ DFF_X1 ; + - _324_ DFF_X1 ; + - _325_ DFF_X1 ; + - _326_ DFF_X1 ; + - _327_ DFF_X1 ; + - _328_ DFF_X1 ; + - _329_ DFF_X1 ; + - _330_ DFF_X1 ; + - _331_ DFF_X1 ; + - _332_ DFF_X1 ; + - _333_ DFF_X1 ; + - _334_ DFF_X1 ; + - _335_ DFF_X1 ; + - _336_ DFF_X1 ; + - _337_ DFF_X1 ; + - _338_ DFF_X1 ; + - _339_ DFF_X1 ; + - _340_ DFF_X1 ; + - _341_ DFF_X1 ; + - _342_ DFF_X1 ; + - _343_ DFF_X1 ; + - _344_ DFF_X1 ; + - _345_ DFF_X1 ; + - _346_ DFF_X1 ; + - _347_ DFF_X1 ; + - _348_ DFF_X1 ; + - _349_ DFF_X1 ; + - _350_ DFF_X1 ; + - _351_ DFF_X1 ; + - _352_ DFF_X1 ; + - _353_ DFF_X1 ; + - _354_ DFF_X1 ; + - _355_ DFF_X1 ; + - _356_ DFF_X1 ; + - _357_ DFF_X1 ; + - _358_ DFF_X1 ; + - _359_ DFF_X1 ; + - _360_ DFF_X1 ; + - _361_ DFF_X1 ; + - _362_ DFF_X1 ; + - _363_ DFF_X1 ; + - _364_ DFF_X1 ; + - _365_ DFF_X1 ; + - _366_ DFF_X1 ; + - _367_ DFF_X1 ; + - _368_ DFF_X1 ; + - _369_ DFF_X1 ; + - _370_ DFF_X1 ; + - _371_ DFF_X1 ; + - _372_ DFF_X1 ; + - _373_ DFF_X1 ; + - _374_ DFF_X1 ; + - _375_ DFF_X1 ; + - _376_ DFF_X1 ; + - _377_ DFF_X1 ; + - _378_ DFF_X1 ; + - _379_ DFF_X1 ; + - _380_ DFF_X1 ; + - _381_ DFF_X1 ; + - _382_ DFF_X1 ; + - _383_ DFF_X1 ; + - _384_ DFF_X1 ; + - _385_ DFF_X1 ; + - _386_ DFF_X1 ; + - _387_ DFF_X1 ; + - _388_ DFF_X1 ; + - _389_ DFF_X1 ; + - _390_ DFF_X1 ; + - _391_ DFF_X1 ; + - _392_ DFF_X1 ; + - _393_ DFF_X1 ; + - _394_ DFF_X1 ; + - _395_ DFF_X1 ; + - _396_ DFF_X1 ; + - _397_ DFF_X1 ; + - _398_ DFF_X1 ; + - _399_ DFF_X1 ; + - _400_ DFF_X1 ; +END COMPONENTS + +PINS 1 ; + - io_1 + NET io_1 ; + - io_2 + NET io_2 ; + - io_3 + NET io_3 ; +END PINS + +END DESIGN \ No newline at end of file diff --git a/src/mpl2/test/testcases/io_constraints1.v b/src/mpl2/test/testcases/io_constraints1.v new file mode 100644 index 00000000000..4fa7267b58c --- /dev/null +++ b/src/mpl2/test/testcases/io_constraints1.v @@ -0,0 +1,409 @@ +module io_constraints1 ( \io_1 , \io_2 , \io_3 ); + HM_100x100_1x1 MACRO_1 ( ) ; + + DFF_X1 _001_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _002_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _003_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _004_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _005_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _006_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _007_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _008_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _009_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _010_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _011_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _012_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _013_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _014_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _015_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _016_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _017_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _018_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _019_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _020_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _021_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _022_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _023_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _024_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _025_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _026_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _027_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _028_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _029_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _030_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _031_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _032_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _033_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _034_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _035_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _036_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _037_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _038_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _039_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _040_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _041_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _042_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _043_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _044_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _045_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _046_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _047_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _048_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _049_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _050_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _051_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _052_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _053_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _054_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _055_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _056_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _057_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _058_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _059_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _060_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _061_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _062_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _063_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _064_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _065_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _066_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _067_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _068_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _069_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _070_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _071_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _072_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _073_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _074_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _075_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _076_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _077_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _078_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _079_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _080_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _081_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _082_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _083_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _084_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _085_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _086_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _087_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _088_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _089_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _090_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _091_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _092_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _093_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _094_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _095_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _096_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _097_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _098_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _099_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _100_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _101_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _102_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _103_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _104_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _105_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _106_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _107_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _108_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _109_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _110_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _111_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _112_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _113_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _114_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _115_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _116_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _117_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _118_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _119_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _120_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _121_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _122_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _123_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _124_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _125_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _126_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _127_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _128_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _129_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _130_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _131_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _132_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _133_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _134_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _135_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _136_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _137_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _138_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _139_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _140_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _141_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _142_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _143_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _144_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _145_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _146_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _147_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _148_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _149_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _150_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _151_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _152_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _153_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _154_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _155_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _156_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _157_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _158_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _159_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _160_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _161_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _162_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _163_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _164_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _165_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _166_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _167_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _168_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _169_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _170_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _171_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _172_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _173_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _174_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _175_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _176_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _177_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _178_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _179_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _180_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _181_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _182_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _183_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _184_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _185_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _186_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _187_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _188_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _189_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _190_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _191_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _192_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _193_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _194_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _195_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _196_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _197_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _198_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _199_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _200_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _201_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _202_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _203_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _204_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _205_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _206_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _207_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _208_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _209_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _210_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _211_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _212_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _213_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _214_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _215_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _216_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _217_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _218_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _219_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _220_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _221_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _222_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _223_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _224_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _225_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _226_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _227_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _228_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _229_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _230_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _231_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _232_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _233_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _234_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _235_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _236_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _237_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _238_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _239_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _240_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _241_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _242_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _243_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _244_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _245_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _246_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _247_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _248_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _249_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _250_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _251_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _252_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _253_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _254_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _255_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _256_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _257_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _258_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _259_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _260_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _261_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _262_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _263_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _264_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _265_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _266_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _267_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _268_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _269_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _270_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _271_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _272_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _273_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _274_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _275_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _276_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _277_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _278_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _279_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _280_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _281_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _282_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _283_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _284_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _285_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _286_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _287_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _288_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _289_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _290_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _291_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _292_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _293_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _294_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _295_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _296_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _297_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _298_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _299_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _300_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _301_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _302_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _303_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _304_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _305_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _306_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _307_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _308_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _309_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _310_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _311_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _312_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _313_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _314_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _315_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _316_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _317_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _318_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _319_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _320_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _321_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _322_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _323_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _324_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _325_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _326_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _327_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _328_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _329_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _330_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _331_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _332_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _333_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _334_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _335_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _336_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _337_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _338_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _339_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _340_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _341_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _342_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _343_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _344_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _345_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _346_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _347_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _348_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _349_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _350_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _351_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _352_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _353_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _354_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _355_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _356_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _357_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _358_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _359_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _360_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _361_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _362_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _363_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _364_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _365_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _366_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _367_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _368_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _369_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _370_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _371_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _372_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _373_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _374_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _375_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _376_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _377_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _378_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _379_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _380_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _381_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _382_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _383_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _384_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _385_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _386_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _387_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _388_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _389_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _390_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _391_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _392_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _393_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _394_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _395_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _396_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _397_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _398_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _399_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _400_ ( .CK(), .D(), .Q(), .QN() ); + + input io_1; + input io_2; + input io_3; +endmodule + From 1204f5765298c0bc7258de3f5ee7ec040e0f6296 Mon Sep 17 00:00:00 2001 From: Arthur Koucher Date: Fri, 11 Oct 2024 15:01:39 -0300 Subject: [PATCH 35/38] mpl2: ensure that io clusters data is visible for levels deeper than the root Signed-off-by: Arthur Koucher --- src/mpl2/src/hier_rtlmp.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/mpl2/src/hier_rtlmp.cpp b/src/mpl2/src/hier_rtlmp.cpp index 7b73aad5242..9710adc7e3b 100644 --- a/src/mpl2/src/hier_rtlmp.cpp +++ b/src/mpl2/src/hier_rtlmp.cpp @@ -2270,7 +2270,10 @@ void HierRTLMP::runHierarchicalMacroPlacementWithoutBusPlanning(Cluster* parent) cluster->getName(), 0.0, 0.0, - nullptr); + // The information of whether or not a cluster is an IO cluster is + // needed inside the SA Core, so if a fixed terminal corresponds + // to an IO Cluster it needs to contains that cluster data. + cluster->isIOCluster() ? cluster.get() : nullptr); debugPrint( logger_, MPL, @@ -2767,7 +2770,10 @@ void HierRTLMP::runEnhancedHierarchicalMacroPlacement(Cluster* parent) cluster->getName(), 0.0, 0.0, - nullptr); + // The information of whether or not a cluster is an IO cluster is + // needed inside the SA Core, so if a fixed terminal corresponds + // to an IO Cluster it needs to contains that cluster data. + cluster->isIOCluster() ? cluster.get() : nullptr); debugPrint( logger_, MPL, From e1451069649549f713b4981fbb1d23d253d15343 Mon Sep 17 00:00:00 2001 From: Arthur Koucher Date: Fri, 11 Oct 2024 15:09:21 -0300 Subject: [PATCH 36/38] mpl2: add test for blocked boundaries' pin access Signed-off-by: Arthur Koucher --- src/mpl2/test/io_constraints1.tcl | 1 - src/mpl2/test/io_constraints2.defok | 538 ++++++++++++++++++++++++++++ src/mpl2/test/io_constraints2.ok | 30 ++ src/mpl2/test/io_constraints2.tcl | 25 ++ src/mpl2/test/regression_tests.tcl | 1 + 5 files changed, 594 insertions(+), 1 deletion(-) create mode 100644 src/mpl2/test/io_constraints2.defok create mode 100644 src/mpl2/test/io_constraints2.ok create mode 100644 src/mpl2/test/io_constraints2.tcl diff --git a/src/mpl2/test/io_constraints1.tcl b/src/mpl2/test/io_constraints1.tcl index d032e4a01e3..b5f31c91ba0 100644 --- a/src/mpl2/test/io_constraints1.tcl +++ b/src/mpl2/test/io_constraints1.tcl @@ -10,7 +10,6 @@ read_liberty "./testcases/macro_only.lib" read_verilog "./testcases/io_constraints1.v" link_design "io_constraints1" - read_def "./testcases/io_constraints1.def" -floorplan_initialize # Run random PPL to incorporate the constraints into ODB diff --git a/src/mpl2/test/io_constraints2.defok b/src/mpl2/test/io_constraints2.defok new file mode 100644 index 00000000000..827dcf1eaec --- /dev/null +++ b/src/mpl2/test/io_constraints2.defok @@ -0,0 +1,538 @@ +VERSION 5.8 ; +DIVIDERCHAR "/" ; +BUSBITCHARS "[]" ; +DESIGN io_constraints1 ; +UNITS DISTANCE MICRONS 2000 ; +DIEAREA ( 0 0 ) ( 300000 250000 ) ; +ROW ROW_0 FreePDK45_38x28_10R_NP_162NW_34O 0 0 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_1 FreePDK45_38x28_10R_NP_162NW_34O 0 2800 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_2 FreePDK45_38x28_10R_NP_162NW_34O 0 5600 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_3 FreePDK45_38x28_10R_NP_162NW_34O 0 8400 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_4 FreePDK45_38x28_10R_NP_162NW_34O 0 11200 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_5 FreePDK45_38x28_10R_NP_162NW_34O 0 14000 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_6 FreePDK45_38x28_10R_NP_162NW_34O 0 16800 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_7 FreePDK45_38x28_10R_NP_162NW_34O 0 19600 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_8 FreePDK45_38x28_10R_NP_162NW_34O 0 22400 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_9 FreePDK45_38x28_10R_NP_162NW_34O 0 25200 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_10 FreePDK45_38x28_10R_NP_162NW_34O 0 28000 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_11 FreePDK45_38x28_10R_NP_162NW_34O 0 30800 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_12 FreePDK45_38x28_10R_NP_162NW_34O 0 33600 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_13 FreePDK45_38x28_10R_NP_162NW_34O 0 36400 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_14 FreePDK45_38x28_10R_NP_162NW_34O 0 39200 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_15 FreePDK45_38x28_10R_NP_162NW_34O 0 42000 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_16 FreePDK45_38x28_10R_NP_162NW_34O 0 44800 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_17 FreePDK45_38x28_10R_NP_162NW_34O 0 47600 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_18 FreePDK45_38x28_10R_NP_162NW_34O 0 50400 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_19 FreePDK45_38x28_10R_NP_162NW_34O 0 53200 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_20 FreePDK45_38x28_10R_NP_162NW_34O 0 56000 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_21 FreePDK45_38x28_10R_NP_162NW_34O 0 58800 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_22 FreePDK45_38x28_10R_NP_162NW_34O 0 61600 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_23 FreePDK45_38x28_10R_NP_162NW_34O 0 64400 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_24 FreePDK45_38x28_10R_NP_162NW_34O 0 67200 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_25 FreePDK45_38x28_10R_NP_162NW_34O 0 70000 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_26 FreePDK45_38x28_10R_NP_162NW_34O 0 72800 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_27 FreePDK45_38x28_10R_NP_162NW_34O 0 75600 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_28 FreePDK45_38x28_10R_NP_162NW_34O 0 78400 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_29 FreePDK45_38x28_10R_NP_162NW_34O 0 81200 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_30 FreePDK45_38x28_10R_NP_162NW_34O 0 84000 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_31 FreePDK45_38x28_10R_NP_162NW_34O 0 86800 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_32 FreePDK45_38x28_10R_NP_162NW_34O 0 89600 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_33 FreePDK45_38x28_10R_NP_162NW_34O 0 92400 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_34 FreePDK45_38x28_10R_NP_162NW_34O 0 95200 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_35 FreePDK45_38x28_10R_NP_162NW_34O 0 98000 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_36 FreePDK45_38x28_10R_NP_162NW_34O 0 100800 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_37 FreePDK45_38x28_10R_NP_162NW_34O 0 103600 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_38 FreePDK45_38x28_10R_NP_162NW_34O 0 106400 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_39 FreePDK45_38x28_10R_NP_162NW_34O 0 109200 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_40 FreePDK45_38x28_10R_NP_162NW_34O 0 112000 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_41 FreePDK45_38x28_10R_NP_162NW_34O 0 114800 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_42 FreePDK45_38x28_10R_NP_162NW_34O 0 117600 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_43 FreePDK45_38x28_10R_NP_162NW_34O 0 120400 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_44 FreePDK45_38x28_10R_NP_162NW_34O 0 123200 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_45 FreePDK45_38x28_10R_NP_162NW_34O 0 126000 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_46 FreePDK45_38x28_10R_NP_162NW_34O 0 128800 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_47 FreePDK45_38x28_10R_NP_162NW_34O 0 131600 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_48 FreePDK45_38x28_10R_NP_162NW_34O 0 134400 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_49 FreePDK45_38x28_10R_NP_162NW_34O 0 137200 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_50 FreePDK45_38x28_10R_NP_162NW_34O 0 140000 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_51 FreePDK45_38x28_10R_NP_162NW_34O 0 142800 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_52 FreePDK45_38x28_10R_NP_162NW_34O 0 145600 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_53 FreePDK45_38x28_10R_NP_162NW_34O 0 148400 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_54 FreePDK45_38x28_10R_NP_162NW_34O 0 151200 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_55 FreePDK45_38x28_10R_NP_162NW_34O 0 154000 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_56 FreePDK45_38x28_10R_NP_162NW_34O 0 156800 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_57 FreePDK45_38x28_10R_NP_162NW_34O 0 159600 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_58 FreePDK45_38x28_10R_NP_162NW_34O 0 162400 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_59 FreePDK45_38x28_10R_NP_162NW_34O 0 165200 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_60 FreePDK45_38x28_10R_NP_162NW_34O 0 168000 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_61 FreePDK45_38x28_10R_NP_162NW_34O 0 170800 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_62 FreePDK45_38x28_10R_NP_162NW_34O 0 173600 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_63 FreePDK45_38x28_10R_NP_162NW_34O 0 176400 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_64 FreePDK45_38x28_10R_NP_162NW_34O 0 179200 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_65 FreePDK45_38x28_10R_NP_162NW_34O 0 182000 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_66 FreePDK45_38x28_10R_NP_162NW_34O 0 184800 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_67 FreePDK45_38x28_10R_NP_162NW_34O 0 187600 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_68 FreePDK45_38x28_10R_NP_162NW_34O 0 190400 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_69 FreePDK45_38x28_10R_NP_162NW_34O 0 193200 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_70 FreePDK45_38x28_10R_NP_162NW_34O 0 196000 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_71 FreePDK45_38x28_10R_NP_162NW_34O 0 198800 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_72 FreePDK45_38x28_10R_NP_162NW_34O 0 201600 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_73 FreePDK45_38x28_10R_NP_162NW_34O 0 204400 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_74 FreePDK45_38x28_10R_NP_162NW_34O 0 207200 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_75 FreePDK45_38x28_10R_NP_162NW_34O 0 210000 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_76 FreePDK45_38x28_10R_NP_162NW_34O 0 212800 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_77 FreePDK45_38x28_10R_NP_162NW_34O 0 215600 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_78 FreePDK45_38x28_10R_NP_162NW_34O 0 218400 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_79 FreePDK45_38x28_10R_NP_162NW_34O 0 221200 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_80 FreePDK45_38x28_10R_NP_162NW_34O 0 224000 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_81 FreePDK45_38x28_10R_NP_162NW_34O 0 226800 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_82 FreePDK45_38x28_10R_NP_162NW_34O 0 229600 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_83 FreePDK45_38x28_10R_NP_162NW_34O 0 232400 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_84 FreePDK45_38x28_10R_NP_162NW_34O 0 235200 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_85 FreePDK45_38x28_10R_NP_162NW_34O 0 238000 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_86 FreePDK45_38x28_10R_NP_162NW_34O 0 240800 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_87 FreePDK45_38x28_10R_NP_162NW_34O 0 243600 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_88 FreePDK45_38x28_10R_NP_162NW_34O 0 246400 N DO 789 BY 1 STEP 380 0 ; +TRACKS X 190 DO 2368 STEP 380 LAYER metal1 ; +TRACKS Y 140 DO 3214 STEP 280 LAYER metal1 ; +TRACKS X 190 DO 2368 STEP 380 LAYER metal2 ; +TRACKS Y 140 DO 3214 STEP 280 LAYER metal2 ; +TRACKS X 190 DO 2368 STEP 380 LAYER metal3 ; +TRACKS Y 140 DO 3214 STEP 280 LAYER metal3 ; +TRACKS X 190 DO 1607 STEP 560 LAYER metal4 ; +TRACKS Y 140 DO 1607 STEP 560 LAYER metal4 ; +TRACKS X 190 DO 1607 STEP 560 LAYER metal5 ; +TRACKS Y 140 DO 1607 STEP 560 LAYER metal5 ; +TRACKS X 190 DO 1607 STEP 560 LAYER metal6 ; +TRACKS Y 140 DO 1607 STEP 560 LAYER metal6 ; +TRACKS X 190 DO 563 STEP 1600 LAYER metal7 ; +TRACKS Y 140 DO 563 STEP 1600 LAYER metal7 ; +TRACKS X 190 DO 563 STEP 1600 LAYER metal8 ; +TRACKS Y 140 DO 563 STEP 1600 LAYER metal8 ; +TRACKS X 190 DO 282 STEP 3200 LAYER metal9 ; +TRACKS Y 140 DO 282 STEP 3200 LAYER metal9 ; +TRACKS X 190 DO 282 STEP 3200 LAYER metal10 ; +TRACKS Y 140 DO 282 STEP 3200 LAYER metal10 ; +COMPONENTS 401 ; + - MACRO_1 HM_100x100_1x1 + FIXED ( 8000 41330 ) S ; + - _001_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _002_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _003_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _004_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _005_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _006_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _007_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _008_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _009_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _010_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _011_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _012_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _013_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _014_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _015_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _016_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _017_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _018_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _019_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _020_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _021_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _022_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _023_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _024_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _025_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _026_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _027_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _028_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _029_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _030_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _031_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _032_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _033_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _034_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _035_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _036_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _037_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _038_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _039_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _040_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _041_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _042_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _043_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _044_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _045_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _046_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _047_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _048_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _049_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _050_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _051_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _052_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _053_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _054_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _055_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _056_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _057_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _058_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _059_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _060_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _061_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _062_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _063_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _064_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _065_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _066_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _067_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _068_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _069_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _070_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _071_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _072_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _073_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _074_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _075_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _076_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _077_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _078_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _079_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _080_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _081_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _082_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _083_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _084_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _085_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _086_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _087_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _088_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _089_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _090_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _091_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _092_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _093_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _094_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _095_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _096_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _097_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _098_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _099_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _100_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _101_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _102_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _103_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _104_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _105_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _106_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _107_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _108_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _109_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _110_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _111_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _112_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _113_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _114_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _115_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _116_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _117_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _118_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _119_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _120_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _121_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _122_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _123_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _124_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _125_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _126_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _127_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _128_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _129_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _130_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _131_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _132_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _133_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _134_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _135_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _136_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _137_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _138_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _139_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _140_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _141_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _142_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _143_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _144_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _145_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _146_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _147_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _148_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _149_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _150_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _151_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _152_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _153_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _154_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _155_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _156_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _157_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _158_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _159_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _160_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _161_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _162_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _163_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _164_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _165_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _166_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _167_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _168_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _169_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _170_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _171_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _172_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _173_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _174_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _175_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _176_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _177_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _178_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _179_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _180_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _181_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _182_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _183_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _184_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _185_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _186_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _187_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _188_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _189_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _190_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _191_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _192_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _193_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _194_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _195_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _196_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _197_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _198_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _199_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _200_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _201_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _202_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _203_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _204_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _205_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _206_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _207_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _208_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _209_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _210_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _211_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _212_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _213_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _214_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _215_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _216_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _217_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _218_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _219_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _220_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _221_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _222_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _223_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _224_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _225_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _226_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _227_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _228_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _229_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _230_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _231_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _232_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _233_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _234_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _235_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _236_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _237_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _238_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _239_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _240_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _241_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _242_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _243_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _244_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _245_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _246_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _247_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _248_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _249_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _250_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _251_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _252_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _253_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _254_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _255_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _256_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _257_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _258_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _259_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _260_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _261_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _262_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _263_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _264_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _265_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _266_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _267_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _268_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _269_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _270_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _271_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _272_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _273_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _274_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _275_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _276_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _277_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _278_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _279_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _280_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _281_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _282_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _283_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _284_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _285_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _286_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _287_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _288_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _289_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _290_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _291_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _292_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _293_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _294_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _295_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _296_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _297_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _298_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _299_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _300_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _301_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _302_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _303_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _304_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _305_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _306_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _307_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _308_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _309_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _310_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _311_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _312_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _313_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _314_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _315_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _316_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _317_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _318_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _319_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _320_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _321_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _322_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _323_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _324_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _325_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _326_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _327_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _328_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _329_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _330_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _331_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _332_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _333_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _334_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _335_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _336_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _337_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _338_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _339_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _340_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _341_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _342_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _343_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _344_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _345_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _346_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _347_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _348_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _349_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _350_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _351_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _352_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _353_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _354_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _355_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _356_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _357_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _358_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _359_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _360_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _361_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _362_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _363_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _364_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _365_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _366_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _367_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _368_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _369_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _370_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _371_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _372_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _373_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _374_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _375_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _376_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _377_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _378_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _379_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _380_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _381_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _382_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _383_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _384_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _385_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _386_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _387_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _388_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _389_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _390_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _391_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _392_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _393_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _394_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _395_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _396_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _397_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _398_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _399_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _400_ DFF_X1 + PLACED ( 146680 15234 ) N ; +END COMPONENTS +PINS 3 ; + - io_1 + NET io_1 + DIRECTION INPUT + USE SIGNAL + + PORT + + LAYER metal5 ( -140 -140 ) ( 140 140 ) + + PLACED ( 299860 55020 ) N ; + - io_2 + NET io_2 + DIRECTION INPUT + USE SIGNAL + + PORT + + LAYER metal6 ( -140 -140 ) ( 140 140 ) + + PLACED ( 283550 249860 ) N ; + - io_3 + NET io_3 + DIRECTION INPUT + USE SIGNAL + + PORT + + LAYER metal5 ( -140 -140 ) ( 140 140 ) + + PLACED ( 299860 238700 ) N ; +END PINS +NETS 3 ; + - io_1 ( PIN io_1 ) + USE SIGNAL ; + - io_2 ( PIN io_2 ) + USE SIGNAL ; + - io_3 ( PIN io_3 ) + USE SIGNAL ; +END NETS +END DESIGN diff --git a/src/mpl2/test/io_constraints2.ok b/src/mpl2/test/io_constraints2.ok new file mode 100644 index 00000000000..9891520858b --- /dev/null +++ b/src/mpl2/test/io_constraints2.ok @@ -0,0 +1,30 @@ +[INFO ODB-0227] LEF file: ./Nangate45/Nangate45.lef, created 22 layers, 27 vias, 135 library cells +[INFO ODB-0227] LEF file: ./testcases/macro_only.lef, created 9 library cells +[WARNING STA-1171] ./testcases/macro_only.lib line 32, default_max_transition is 0.0. +[WARNING ORD-2011] LEF master DFF_X1 has no liberty cell. +[INFO ODB-0128] Design: io_constraints1 +[INFO ODB-0252] Updated 3 pins. +[INFO ODB-0253] Updated 401 components. +Found 1 macro blocks. +Using 2 tracks default min distance between IO pins. +[INFO PPL-0001] Number of slots 974 +[INFO PPL-0002] Number of I/O 3 +[INFO PPL-0003] Number of I/O w/sink 0 +[INFO PPL-0004] Number of I/O w/o sink 3 +[INFO PPL-0012] I/O nets HPWL: 0.00 um. +Floorplan Outline: (0.0, 0.0) (150.0, 125.0), Core Outline: (0.0, 0.0) (149.91, 124.6) + Number of std cell instances: 400 + Area of std cell instances: 1808.79 + Number of macros: 1 + Area of macros: 10000.00 + Halo width: 4.00 + Halo height: 4.00 + Area of macros with halos: 11664.00 + Area of std cell instances + Area of macros: 11808.79 + Core area: 18678.79 + Design Utilization: 0.63 + Core Utilization: 0.21 + Manufacturing Grid: 10 + +[WARNING MPL-0014] No Liberty data found for std cells. Continuing without dataflow. +No differences found. diff --git a/src/mpl2/test/io_constraints2.tcl b/src/mpl2/test/io_constraints2.tcl new file mode 100644 index 00000000000..17e7fbe7cb5 --- /dev/null +++ b/src/mpl2/test/io_constraints2.tcl @@ -0,0 +1,25 @@ +# Test if pin access blockage is generated correctly for a case +# with all boundaries blocked except one. +source "helpers.tcl" + +# We're not interested in the connections, so don't include the lib. +read_lef "./Nangate45/Nangate45.lef" + +read_lef "./testcases/macro_only.lef" +read_liberty "./testcases/macro_only.lib" + +read_verilog "./testcases/io_constraints1.v" +link_design "io_constraints1" +read_def "./testcases/io_constraints1.def" -floorplan_initialize + +# Run random PPL to incorporate the -exclude constraints into ODB +place_pins -annealing -random -hor_layers metal5 -ver_layer metal6 \ + -exclude left:* -exclude right:* -exclude top:* + +set_thread_count 0 +rtl_macro_placer -report_directory results/io_constraints2 -halo_width 4.0 + +set def_file [make_result_file io_constraints2.def] +write_def $def_file + +diff_files io_constraints2.defok $def_file \ No newline at end of file diff --git a/src/mpl2/test/regression_tests.tcl b/src/mpl2/test/regression_tests.tcl index 6f18ef9bf88..82d5c473aed 100644 --- a/src/mpl2/test/regression_tests.tcl +++ b/src/mpl2/test/regression_tests.tcl @@ -2,6 +2,7 @@ record_tests { macro_only no_unfixed_macros io_constraints1 + io_constraints2 #mpl2_man_tcl_check #mpl2_readme_msgs_check } From 85016382cbd0d4c806cfd7a83178ab3018d5f154 Mon Sep 17 00:00:00 2001 From: Arthur Koucher Date: Mon, 14 Oct 2024 10:05:00 -0300 Subject: [PATCH 37/38] mpl2: make io clusters fixed terminals data visible inside HardSA Signed-off-by: Arthur Koucher --- src/mpl2/src/hier_rtlmp.cpp | 6 +++++- src/mpl2/src/object.cpp | 5 ++++- src/mpl2/src/object.h | 4 +++- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/mpl2/src/hier_rtlmp.cpp b/src/mpl2/src/hier_rtlmp.cpp index 9710adc7e3b..cb006b95f59 100644 --- a/src/mpl2/src/hier_rtlmp.cpp +++ b/src/mpl2/src/hier_rtlmp.cpp @@ -3626,7 +3626,11 @@ void HierRTLMP::createFixedTerminals(const Rect& outline, - outline.xMin(), temp_cluster->getY() + temp_cluster->getHeight() / 2.0 - outline.yMin()), - temp_cluster->getName()); + temp_cluster->getName(), + // The information of whether or not a cluster is an IO cluster is + // needed inside the SA Core, so if a fixed terminal corresponds + // to an IO Cluster it needs to contains that cluster data. + temp_cluster->isIOCluster() ? temp_cluster : nullptr); } } diff --git a/src/mpl2/src/object.cpp b/src/mpl2/src/object.cpp index 6d217c32482..98e2f8b103c 100644 --- a/src/mpl2/src/object.cpp +++ b/src/mpl2/src/object.cpp @@ -788,7 +788,9 @@ void Cluster::addVirtualConnection(int src, int target) /////////////////////////////////////////////////////////////////////// // HardMacro -HardMacro::HardMacro(std::pair loc, const std::string& name) +HardMacro::HardMacro(std::pair loc, + const std::string& name, + Cluster* cluster) { width_ = 0.0; height_ = 0.0; @@ -797,6 +799,7 @@ HardMacro::HardMacro(std::pair loc, const std::string& name) pin_y_ = 0.0; x_ = loc.first; y_ = loc.second; + cluster_ = cluster; } HardMacro::HardMacro(float width, float height, const std::string& name) diff --git a/src/mpl2/src/object.h b/src/mpl2/src/object.h index a29f4c84e4b..7b4f71639fe 100644 --- a/src/mpl2/src/object.h +++ b/src/mpl2/src/object.h @@ -348,7 +348,9 @@ class HardMacro public: // Create a macro with specified size // Model fixed terminals - HardMacro(std::pair loc, const std::string& name); + HardMacro(std::pair loc, + const std::string& name, + Cluster* cluster = nullptr); // In this case, we model the pin position at the center of the macro HardMacro(float width, float height, const std::string& name); From a4a5841d5a287becdb925f405a020fd38c85a4c9 Mon Sep 17 00:00:00 2001 From: Arthur Koucher Date: Tue, 15 Oct 2024 20:20:59 -0300 Subject: [PATCH 38/38] mpl2: clusters connected to an IO cluster of a specific edge will be pushed to it even if the edge is blocked Signed-off-by: Arthur Koucher --- src/mpl2/src/SimulatedAnnealingCore.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/mpl2/src/SimulatedAnnealingCore.cpp b/src/mpl2/src/SimulatedAnnealingCore.cpp index 0d24a28ceaa..f36cd6bdffb 100644 --- a/src/mpl2/src/SimulatedAnnealingCore.cpp +++ b/src/mpl2/src/SimulatedAnnealingCore.cpp @@ -368,12 +368,12 @@ void SimulatedAnnealingCore::addBoundaryDistToWirelength( += net_weight * std::min( {dist_to_left, dist_to_right, dist_to_bottom, dist_to_top}); - } else if ((constraint_boundary == Boundary::L && !left_is_blocked_) - || (constraint_boundary == Boundary::R && !right_is_blocked_)) { + } else if (constraint_boundary == Boundary::L + || constraint_boundary == Boundary::R) { const float x2 = io.getPinX(); wirelength_ += net_weight * std::abs(x2 - x1); - } else if ((constraint_boundary == Boundary::T && !top_is_blocked_) - || (constraint_boundary == Boundary::B && !bottom_is_blocked_)) { + } else if (constraint_boundary == Boundary::T + || constraint_boundary == Boundary::B) { const float y2 = io.getPinY(); wirelength_ += net_weight * std::abs(y2 - y1); }