Repository navigation
MPL: add a read-only macro placement feasibility check #11896
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
base: master
Are you sure you want to change the base?
Changes from all commits
4eef219
b81498d
834c73f
c48ec91
1b1a409
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 |
|---|---|---|
|
|
@@ -15,6 +15,7 @@ | |
| #include <map> | ||
| #include <memory> | ||
| #include <numeric> | ||
| #include <optional> | ||
| #include <queue> | ||
| #include <regex> | ||
| #include <set> | ||
|
|
@@ -243,6 +244,29 @@ void HierRTLMP::init() | |
| clustering_engine_->setTree(tree_.get()); | ||
| } | ||
|
|
||
| void HierRTLMP::checkMacroPlacement(std::optional<odb::Rect> global_fence, | ||
| int min_channel_width, | ||
| int min_channel_height, | ||
| bool pin_aware_channels) const | ||
| { | ||
| odb::dbBlock* block = db_->getChip()->getBlock(); | ||
|
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. If no design is loaded, odb::dbChip* chip = db_->getChip();
if (chip == nullptr || chip->getBlock() == nullptr) {
logger_->error(MPL, 1, "No block found for Macro Placement.");
}
odb::dbBlock* block = chip->getBlock(); |
||
| if (global_fence | ||
| && (global_fence->xMin() >= global_fence->xMax() | ||
| || global_fence->yMin() >= global_fence->yMax())) { | ||
| logger_->error(MPL, | ||
| 82, | ||
| "Invalid global fence: lower coordinates must be strictly " | ||
| "less than upper coordinates."); | ||
| } | ||
| PhysicalHierarchy tree; | ||
| tree.global_fence = global_fence.value_or(block->getCoreArea()); | ||
| ClusteringEngine engine(block, logger_, tritonpart_, nullptr); | ||
| engine.setTree(&tree); | ||
| engine.setChannel({min_channel_width, min_channel_height}, | ||
| pin_aware_channels); | ||
| engine.checkFeasibility(); | ||
| } | ||
|
|
||
| //////////////////////////////////////////////////////////////////////// | ||
| // Private functions | ||
| //////////////////////////////////////////////////////////////////////// | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2,8 +2,11 @@ | |
| // Copyright (c) 2021-2025, The OpenROAD Authors | ||
|
|
||
| %{ | ||
| #include <optional> | ||
|
|
||
| #include "ord/OpenRoad.hh" | ||
| #include "mpl/rtl_mp.h" | ||
| #include "mpl-util.h" | ||
| #include "MplObserver.h" | ||
| #include "graphics.h" | ||
| #include "odb/db.h" | ||
|
|
@@ -115,6 +118,34 @@ bool rtl_macro_placer_cmd(const std::map<std::string, std::string>& keys, | |
| return macro_placer->run(threads, options); | ||
| } | ||
|
|
||
| void check_macro_placement_cmd(double fence_lx, | ||
| double fence_ly, | ||
| double fence_ux, | ||
| double fence_uy, | ||
| double min_channel_width, | ||
| double min_channel_height, | ||
| bool pin_aware_channels, | ||
| bool fence_provided) | ||
| { | ||
| auto block = ord::OpenRoad::openRoad()->getDb()->getChip()->getBlock(); | ||
|
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. If no design is loaded, |
||
| auto logger = ord::getLogger(); | ||
| const int channel_width = checkedMicronsToDbu( | ||
| block, min_channel_width, "-min_channel_size width", logger); | ||
| const int channel_height = checkedMicronsToDbu( | ||
| block, min_channel_height, "-min_channel_size height", logger); | ||
| std::optional<odb::Rect> global_fence; | ||
| if (fence_provided) { | ||
| global_fence.emplace(); | ||
| // Preserve corner ordering so malformed bounds are not silently normalized. | ||
| global_fence->reset(checkedMicronsToDbu(block, fence_lx, "-fence_lx", logger), | ||
| checkedMicronsToDbu(block, fence_ly, "-fence_ly", logger), | ||
| checkedMicronsToDbu(block, fence_ux, "-fence_ux", logger), | ||
| checkedMicronsToDbu(block, fence_uy, "-fence_uy", logger)); | ||
| } | ||
| getMacroPlacer()->checkMacroPlacement( | ||
| global_fence, channel_width, channel_height, pin_aware_channels); | ||
| } | ||
|
|
||
| void set_debug_cmd(const std::map<std::string, std::string>& keys, | ||
| const std::map<std::string, std::string>& flags) | ||
| { | ||
|
|
||
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.
To ensure robustness and defensive programming, explicitly set
tree_->has_unfixed_macros = true;whenunfixed_macrosis not empty. This prevents potential issues iftree_is reused or ifhas_unfixed_macrosis not default-initialized totrue.