-
Notifications
You must be signed in to change notification settings - Fork 727
mpl: blockages as fixed macros #8438
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 7 commits
b50a9e0
49961c0
9ddbaaa
b215fe7
afe7aa4
719e326
507c379
d082005
40c1818
84caee9
89e81a2
d0f97f6
13b56b3
da1006e
116aca0
22cf64b
dd38f2b
051f2cd
b173d4c
cd0dc9e
6650dda
82b488b
d754e9e
58bd700
2cb77c5
bb6c011
af4219e
2b24960
b953cc8
94d3e38
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -553,9 +553,8 @@ void Graphics::drawObjects(gui::Painter& painter) | |
| template <typename T> | ||
| bool Graphics::isSkippable(const T& macro) | ||
| { | ||
| Cluster* cluster = macro.getCluster(); | ||
|
|
||
| return !cluster /*fixed terminal*/ || cluster->isClusterOfUnplacedIOPins(); | ||
| return macro.getCluster() != nullptr | ||
| && macro.getCluster()->isClusterOfUnplacedIOPins(); | ||
| } | ||
|
|
||
| // Draw guidance regions for macros. | ||
|
|
@@ -662,6 +661,11 @@ void Graphics::addOutlineOffsetToLine(odb::Point& from, odb::Point& to) | |
| void Graphics::setSoftMacroBrush(gui::Painter& painter, | ||
| const SoftMacro& soft_macro) | ||
| { | ||
| if (soft_macro.getCluster() == nullptr) { | ||
|
||
| painter.setBrush(gui::Painter::kDarkGreen); | ||
| return; | ||
| } | ||
|
|
||
| if (soft_macro.getCluster()->getClusterType() == StdCellCluster) { | ||
| painter.setBrush(gui::Painter::kDarkBlue); | ||
| } else if (soft_macro.getCluster()->getClusterType() == HardMacroCluster) { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -4,6 +4,7 @@ | |
| #include "hier_rtlmp.h" | ||
|
|
||
| #include <algorithm> | ||
| #include <boost/polygon/polygon.hpp> | ||
| #include <cmath> | ||
| #include <fstream> | ||
| #include <iostream> | ||
|
|
@@ -29,7 +30,7 @@ | |
| #include "mpl-util.h" | ||
| #include "object.h" | ||
| #include "odb/db.h" | ||
| #include "odb/geom.h" | ||
| #include "odb/geom_boost.h" | ||
| #include "odb/util.h" | ||
| #include "par/PartitionMgr.h" | ||
| #include "utl/Logger.h" | ||
|
|
@@ -847,22 +848,26 @@ void HierRTLMP::setTightPackingTilings(Cluster* macro_array) | |
| { | ||
| TilingList tight_packing_tilings; | ||
|
|
||
| int divider = 1; | ||
| int columns = 0, rows = 0; | ||
| int num_macro = static_cast<int>(macro_array->getNumMacro()); | ||
| float macro_width = macro_array->getHardMacros().front()->getWidth(); | ||
| float macro_height = macro_array->getHardMacros().front()->getHeight(); | ||
|
|
||
| while (divider <= macro_array->getNumMacro()) { | ||
| if (macro_array->getNumMacro() % divider == 0) { | ||
| columns = macro_array->getNumMacro() / divider; | ||
| rows = divider; | ||
| const auto outline = tree_->root->getBBox(); | ||
|
||
|
|
||
| int columns = 0; | ||
| for (int rows = 1; rows < std::sqrt(num_macro) + 1; rows++) { | ||
| if (num_macro % rows == 0) { | ||
| columns = num_macro / rows; | ||
|
|
||
| // We don't consider tilings for right angle rotation orientations, | ||
| // because they're not allowed in our macro placer. | ||
| tight_packing_tilings.emplace_back( | ||
| columns * macro_array->getHardMacros().front()->getWidth(), | ||
| rows * macro_array->getHardMacros().front()->getHeight()); | ||
| // Tiling needs to fit inside outline | ||
| if (columns * macro_width <= outline.getWidth() | ||
| && rows * macro_height <= outline.getHeight()) { | ||
| tight_packing_tilings.emplace_back(columns * macro_width, | ||
| rows * macro_height); | ||
| } | ||
maliberty marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| } | ||
|
|
||
| ++divider; | ||
| } | ||
|
|
||
| macro_array->setTilings(tight_packing_tilings); | ||
|
|
@@ -929,8 +934,17 @@ void HierRTLMP::computePinAccessDepthLimits() | |
| pin_access_depth_limits_.y.max = max_depth_proportion * die.getHeight(); | ||
|
|
||
| constexpr float min_depth_proportion = 0.04; | ||
| pin_access_depth_limits_.x.min = min_depth_proportion * die.getWidth(); | ||
| pin_access_depth_limits_.y.min = min_depth_proportion * die.getHeight(); | ||
| const float proportional_min_width = min_depth_proportion * die.getWidth(); | ||
| const float proportional_min_height = min_depth_proportion * die.getHeight(); | ||
|
|
||
| const auto tiling = tree_->root->getTilings().front(); | ||
|
||
| const float tiling_min_width = (die.getWidth() - tiling.width()) / 2; | ||
| const float tiling_min_height = (die.getHeight() - tiling.height()) / 2; | ||
|
|
||
| pin_access_depth_limits_.x.min | ||
| = std::min(proportional_min_width, tiling_min_width); | ||
| pin_access_depth_limits_.y.min | ||
| = std::min(proportional_min_height, tiling_min_height); | ||
|
|
||
| if (logger_->debugCheck(MPL, "coarse_shaping", 1)) { | ||
| logger_->report("\n Pin Access Depth (μm) | Min | Max"); | ||
|
|
@@ -1382,10 +1396,9 @@ void HierRTLMP::placeChildren(Cluster* parent, bool ignore_std_cell_area) | |
| std::vector<SoftMacro> macros; | ||
| std::vector<BundledNet> nets; | ||
|
|
||
| std::vector<Rect> placement_blockages; | ||
| std::vector<Rect> macro_blockages; | ||
|
|
||
| findBlockagesWithinOutline(macro_blockages, placement_blockages, outline); | ||
| std::vector<Rect> blockages = findBlockagesWithinOutline(outline); | ||
| eliminateOverlaps(blockages); | ||
| blockagesAsFixedSoftMacros(blockages, soft_macro_id_map, macros); | ||
|
|
||
| // 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 | ||
|
|
@@ -1656,8 +1669,6 @@ void HierRTLMP::placeChildren(Cluster* parent, bool ignore_std_cell_area) | |
| sa->setFences(fences); | ||
| sa->setGuides(guides); | ||
| sa->setNets(nets); | ||
| sa->addBlockages(placement_blockages); | ||
| sa->addBlockages(macro_blockages); | ||
| sa_batch.push_back(std::move(sa)); | ||
| } | ||
|
|
||
|
|
@@ -1734,23 +1745,20 @@ void HierRTLMP::placeChildren(Cluster* parent, bool ignore_std_cell_area) | |
| } | ||
|
|
||
| // Find the area of blockages that are inside the outline. | ||
| void HierRTLMP::findBlockagesWithinOutline( | ||
| std::vector<Rect>& macro_blockages, | ||
| std::vector<Rect>& placement_blockages, | ||
| std::vector<Rect> HierRTLMP::findBlockagesWithinOutline( | ||
| const Rect& outline) const | ||
| { | ||
| std::vector<Rect> blockages_within_outline; | ||
|
|
||
| for (auto& blockage : placement_blockages_) { | ||
| getBlockageRegionWithinOutline(placement_blockages, blockage, outline); | ||
| getBlockageRegionWithinOutline(blockages_within_outline, blockage, outline); | ||
| } | ||
|
|
||
| for (auto& blockage : io_blockages_) { | ||
| getBlockageRegionWithinOutline(macro_blockages, blockage, outline); | ||
| getBlockageRegionWithinOutline(blockages_within_outline, blockage, outline); | ||
| } | ||
|
|
||
| if (graphics_) { | ||
| graphics_->setMacroBlockages(macro_blockages); | ||
| graphics_->setPlacementBlockages(placement_blockages); | ||
| } | ||
| return blockages_within_outline; | ||
| } | ||
|
|
||
| void HierRTLMP::getBlockageRegionWithinOutline( | ||
|
|
@@ -1771,6 +1779,45 @@ void HierRTLMP::getBlockageRegionWithinOutline( | |
| } | ||
| } | ||
|
|
||
| void HierRTLMP::eliminateOverlaps(std::vector<Rect>& blockages) const | ||
| { | ||
| namespace gtl = boost::polygon; | ||
| using gtl::operators::operator+=; | ||
| using PolygonSet = gtl::polygon_90_set_data<int>; | ||
|
|
||
| PolygonSet polygons; | ||
| for (const Rect& blockage : blockages) { | ||
| const odb::Rect dbu_blockage = micronsToDbu(block_, blockage); | ||
| polygons += dbu_blockage; | ||
| } | ||
|
|
||
| blockages.clear(); | ||
|
|
||
| std::vector<odb::Rect> new_blockages; | ||
| polygons.get_rectangles(new_blockages); | ||
|
|
||
| for (const odb::Rect& new_blockage : new_blockages) { | ||
| blockages.push_back(dbuToMicrons(block_, new_blockage)); | ||
| } | ||
| } | ||
|
|
||
| // We model blockages as macro clusters (SoftMacros) constrained to fences. | ||
| // The rationale of this model comes from the fact that the area occupied | ||
| // by blockages should be empty, i.e., with neither macros or std cells. | ||
|
||
| void HierRTLMP::blockagesAsFixedSoftMacros( | ||
| const std::vector<Rect>& blockages, | ||
| std::map<std::string, int>& soft_macro_id_map, | ||
| std::vector<SoftMacro>& macros) | ||
| { | ||
| for (const Rect& blockage : blockages) { | ||
| const int macro_id = static_cast<int>(macros.size()); | ||
| std::string macro_name = fmt::format("blockage_{}", macro_id); | ||
| soft_macro_id_map[macro_name] = macro_id; | ||
|
|
||
| macros.emplace_back(blockage, macro_name); | ||
| } | ||
| } | ||
|
|
||
|
||
| // Create terminals for cluster placement (Soft) annealing. | ||
| void HierRTLMP::createFixedTerminals( | ||
| Cluster* parent, | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -402,7 +402,7 @@ class SoftMacro | |
| { | ||
| public: | ||
| SoftMacro(Cluster* cluster); | ||
| SoftMacro(float width, float height, const std::string& name); | ||
| SoftMacro(const Rect& blockage, const std::string& name); | ||
| SoftMacro(const std::pair<float, float>& location, | ||
| const std::string& name, | ||
| float width, | ||
|
|
@@ -482,6 +482,7 @@ class SoftMacro | |
| // Interfaces with hard macro | ||
| Cluster* cluster_ = nullptr; | ||
| bool fixed_ = false; // if the macro is fixed | ||
| bool is_blockage_ = false; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is useful for debugging. See other comments. |
||
|
|
||
| // Alignment support | ||
| // if the cluster has been aligned related to other macro_cluster or | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This way we're not skipping fixed terminals.
I think we should use the is_blockage_ flag and have something like: