From a7c97255c6f9d736bddb7153634a563012f0fe71 Mon Sep 17 00:00:00 2001 From: ZhiangWang033 Date: Tue, 17 Dec 2024 10:36:15 -0800 Subject: [PATCH] fix the TP invalid partitioning issue and add the real_blockage_flag which converts the placement blockages into macros with fence constraints Signed-off-by: ZhiangWang033 --- src/mpl2/src/clusterEngine.cpp | 77 ++++- src/mpl2/src/hier_rtlmp.cpp | 69 ++++- src/mpl2/src/hier_rtlmp.h | 3 + src/mpl2/src/mpl.i | 234 +++++++-------- src/mpl2/src/mpl.tcl | 506 ++++++++++++++++++--------------- 5 files changed, 525 insertions(+), 364 deletions(-) diff --git a/src/mpl2/src/clusterEngine.cpp b/src/mpl2/src/clusterEngine.cpp index 5c000cffcdd..a5b37e0d5ff 100644 --- a/src/mpl2/src/clusterEngine.cpp +++ b/src/mpl2/src/clusterEngine.cpp @@ -1367,20 +1367,32 @@ void ClusteringEngine::breakLargeFlatCluster(Cluster* parent) cluster_vertex_id_map[cluster_id] = vertex_id++; vertex_weight.push_back(0.0f); } - const int num_other_cluster_vertices = vertex_id; std::vector insts; std::map inst_vertex_id_map; - for (auto& macro : parent->getLeafMacros()) { - inst_vertex_id_map[macro] = vertex_id++; - vertex_weight.push_back(computeMicronArea(macro)); - insts.push_back(macro); - } + + float std_cell_area = 0.0f; + int num_std_cells = 0; + int std_cell_start_index = vertex_id; for (auto& std_cell : parent->getLeafStdCells()) { inst_vertex_id_map[std_cell] = vertex_id++; vertex_weight.push_back(computeMicronArea(std_cell)); + std_cell_area += vertex_weight.back(); + num_std_cells++; insts.push_back(std_cell); } + int std_cell_index_end = insts.size(); + + float avg_std_cell_area = std_cell_area / num_std_cells; + logger_->report( + "During partitioning, modeling each macro as a vertex with an area of " + "%.2f", + avg_std_cell_area); + for (auto& macro : parent->getLeafMacros()) { + inst_vertex_id_map[macro] = vertex_id++; + vertex_weight.push_back(avg_std_cell_area); + insts.push_back(macro); + } std::vector> hyperedges; for (odb::dbNet* net : block_->getNets()) { @@ -1432,8 +1444,8 @@ void ClusteringEngine::breakLargeFlatCluster(Cluster* parent) } const int seed = 0; - const float balance_constraint = 1.0; - const int num_parts = 2; // We use two-way partitioning here + float balance_constraint = 5.0; // relax the balance constraint to 5% + const int num_parts = 2; // We use two-way partitioning here const int num_vertices = static_cast(vertex_weight.size()); std::vector hyperedge_weights(hyperedges.size(), 1.0f); @@ -1452,6 +1464,50 @@ void ClusteringEngine::breakLargeFlatCluster(Cluster* parent) vertex_weight, hyperedge_weights); + // Check if the partitioning was successful + auto checkBalance = [&]() -> bool { + float balance_part_0 = 0.0; + float balance_part_1 = 0.0; + for (int i = 0; i < num_vertices; i++) { + if (part[i] == 0) { + balance_part_0 += vertex_weight[i]; + } else { + balance_part_1 += vertex_weight[i]; + } + } + + float balance_ratio + = std::abs(balance_part_0 / (balance_part_0 + balance_part_1) - 0.5); + if (balance_ratio < balance_constraint) { + logger_->report("Partitioning successful with balance ratio of %.2f%%", + balance_ratio * 100); + return true; + } + + logger_->report("Partitioning failed with balance ratio of %.2f%%", + balance_ratio * 100); + return false; + }; + + if (checkBalance() == false) { + logger_->report("Relaxing balance constraint to 10%"); + balance_constraint = 10.0; + part.clear(); + part = triton_part_->PartitionKWaySimpleMode(num_parts, + balance_constraint, + seed, + hyperedges, + vertex_weight, + hyperedge_weights); + if (checkBalance() == false) { + logger_->error( + MPL, + 206, + "Partitioning failed with balance constriant of {}. Exiting...", + balance_constraint); + } + } + parent->clearLeafStdCells(); parent->clearLeafMacros(); @@ -1459,9 +1515,8 @@ void ClusteringEngine::breakLargeFlatCluster(Cluster* parent) parent->setName(cluster_name + std::string("_0")); auto cluster_part_1 = std::make_unique( id_, cluster_name + std::string("_1"), logger_); - - for (int i = num_other_cluster_vertices; i < num_vertices; i++) { - odb::dbInst* inst = insts[i - num_other_cluster_vertices]; + for (int i = std_cell_start_index; i < std_cell_index_end; i++) { + odb::dbInst* inst = insts[i - std_cell_start_index]; if (part[i] == 0) { parent->addLeafInst(inst); } else { diff --git a/src/mpl2/src/hier_rtlmp.cpp b/src/mpl2/src/hier_rtlmp.cpp index 335d41834b0..dd1019fe336 100644 --- a/src/mpl2/src/hier_rtlmp.cpp +++ b/src/mpl2/src/hier_rtlmp.cpp @@ -952,7 +952,17 @@ void HierRTLMP::setIOClustersBlockages() io_spans[L].second); boundary_to_io_blockage_[L] = left_io_blockage; - macro_blockages_.push_back(left_io_blockage); + if (real_blockage_flag_ == true) { + placement_blockages_.push_back(left_io_blockage); + logger_->report( + "Add left IO blockage : lx = {}, ly = {}, ux = {}, uy = {}", + left_io_blockage.xMin(), + left_io_blockage.yMin(), + left_io_blockage.xMax(), + left_io_blockage.yMax()); + } else { + macro_blockages_.push_back(left_io_blockage); + } } if (io_spans[T].second > io_spans[T].first) { @@ -962,7 +972,17 @@ void HierRTLMP::setIOClustersBlockages() root.yMax()); boundary_to_io_blockage_[T] = top_io_blockage; - macro_blockages_.push_back(top_io_blockage); + if (real_blockage_flag_ == true) { + placement_blockages_.push_back(top_io_blockage); + logger_->report( + "Add top IO blockage : lx = {}, ly = {}, ux = {}, uy = {}", + top_io_blockage.xMin(), + top_io_blockage.yMin(), + top_io_blockage.xMax(), + top_io_blockage.yMax()); + } else { + macro_blockages_.push_back(top_io_blockage); + } } if (io_spans[R].second > io_spans[R].first) { @@ -970,9 +990,18 @@ void HierRTLMP::setIOClustersBlockages() io_spans[R].first, root.xMax(), io_spans[R].second); - boundary_to_io_blockage_[R] = right_io_blockage; - macro_blockages_.push_back(right_io_blockage); + if (real_blockage_flag_ == true) { + placement_blockages_.push_back(right_io_blockage); + logger_->report( + "Add right IO blockage : lx = {}, ly = {}, ux = {}, uy = {}", + right_io_blockage.xMin(), + right_io_blockage.yMin(), + right_io_blockage.xMax(), + right_io_blockage.yMax()); + } else { + macro_blockages_.push_back(right_io_blockage); + } } if (io_spans[B].second > io_spans[B].first) { @@ -982,7 +1011,17 @@ void HierRTLMP::setIOClustersBlockages() root.yMin() + depth); boundary_to_io_blockage_[B] = bottom_io_blockage; - macro_blockages_.push_back(bottom_io_blockage); + if (real_blockage_flag_ == true) { + placement_blockages_.push_back(bottom_io_blockage); + logger_->report( + "Add bottom IO blockage : lx = {}, ly = {}, ux = {}, uy = {}", + bottom_io_blockage.xMin(), + bottom_io_blockage.yMin(), + bottom_io_blockage.xMax(), + bottom_io_blockage.yMax()); + } else { + macro_blockages_.push_back(bottom_io_blockage); + } } } @@ -2810,6 +2849,22 @@ void HierRTLMP::runEnhancedHierarchicalMacroPlacement(Cluster* parent) } } + // Model each placement blockage as macros with fence constraints + if (real_blockage_flag_ == true) { + for (auto& rect : placement_blockages) { + soft_macro_id_map["blockage" + std::to_string(macros.size())] + = macros.size(); + macros.emplace_back(std::pair(rect.xMin() - outline.xMin(), + rect.yMin() - outline.yMin()), + "blockage" + std::to_string(macros.size()), + rect.getWidth(), + rect.getHeight(), + nullptr); + Rect fence(rect.xMin(), rect.yMin(), rect.xMax(), rect.yMax()); + fences[macros.size() - 1] = fence; + } + } + // update the connnection clustering_engine_->updateConnections(); debugPrint(logger_, @@ -3004,7 +3059,9 @@ void HierRTLMP::runEnhancedHierarchicalMacroPlacement(Cluster* parent) sa->setFences(fences); sa->setGuides(guides); sa->setNets(nets); - sa->addBlockages(placement_blockages); + if (real_blockage_flag_ == false) { + sa->addBlockages(placement_blockages); + } sa->addBlockages(macro_blockages); sa_batch.push_back(std::move(sa)); } diff --git a/src/mpl2/src/hier_rtlmp.h b/src/mpl2/src/hier_rtlmp.h index f7a132d1ff9..47ef9a300a4 100644 --- a/src/mpl2/src/hier_rtlmp.h +++ b/src/mpl2/src/hier_rtlmp.h @@ -268,6 +268,9 @@ class HierRTLMP // ASASP7, you should turn off this option. bool bus_planning_on_ = false; + // For testing + bool real_blockage_flag_ = true; + // Parameters related to macro placement std::string report_directory_; std::string macro_placement_file_; diff --git a/src/mpl2/src/mpl.i b/src/mpl2/src/mpl.i index e57264f63f9..ee8eedfd467 100644 --- a/src/mpl2/src/mpl.i +++ b/src/mpl2/src/mpl.i @@ -31,133 +31,135 @@ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. /////////////////////////////////////////////////////////////////////////////// -%{ -#include "ord/OpenRoad.hh" -#include "mpl2/rtl_mp.h" +% +{ #include "Mpl2Observer.h" #include "graphics.h" +#include "mpl2/rtl_mp.h" #include "odb/db.h" +#include "ord/OpenRoad.hh" -namespace ord { -// Defined in OpenRoad.i -mpl2::MacroPlacer2* -getMacroPlacer2(); -utl::Logger* getLogger(); -} - -using utl::MPL; -using ord::getMacroPlacer2; -%} - -%include "../../Exception.i" -%include + namespace ord { + // Defined in OpenRoad.i + mpl2::MacroPlacer2* getMacroPlacer2(); + utl::Logger* getLogger(); + } // namespace ord -%inline %{ + using ord::getMacroPlacer2; + using utl::MPL; + % +} -namespace mpl2 { +% include "../../Exception.i" % include -bool rtl_macro_placer_cmd(const int max_num_macro, - const int min_num_macro, - const int max_num_inst, - const int min_num_inst, - 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, - const float halo_height, - const float fence_lx, - const float fence_ly, - const float fence_ux, - const float fence_uy, - const float area_weight, - const float outline_weight, - const float wirelength_weight, - const float guidance_weight, - const float fence_weight, - const float boundary_weight, - const float notch_weight, - const float macro_blockage_weight, - const float pin_access_th, - const float target_util, - const float target_dead_space, - const float min_ar, - const int snap_layer, - const bool bus_planning_on, - const char* report_directory) { + % inline % +{ + namespace mpl2 { - auto macro_placer = getMacroPlacer2(); - const int num_threads = ord::OpenRoad::openRoad()->getThreadCount(); - return macro_placer->place(num_threads, - max_num_macro, - min_num_macro, - max_num_inst, - min_num_inst, - tolerance, - max_num_level, - coarsening_ratio, - num_bundled_ios, - 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, - boundary_weight, - notch_weight, - macro_blockage_weight, - pin_access_th, - target_util, - target_dead_space, - min_ar, - snap_layer, - bus_planning_on, - report_directory); -} + bool rtl_macro_placer_cmd(const int max_num_macro, + const int min_num_macro, + const int max_num_inst, + const int min_num_inst, + 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, + const float halo_height, + const float fence_lx, + const float fence_ly, + const float fence_ux, + const float fence_uy, + const float area_weight, + const float outline_weight, + const float wirelength_weight, + const float guidance_weight, + const float fence_weight, + const float boundary_weight, + const float notch_weight, + const float macro_blockage_weight, + const float pin_access_th, + const float target_util, + const float target_dead_space, + const float min_ar, + const int snap_layer, + const bool bus_planning_on, + const char* report_directory) + { + auto macro_placer = getMacroPlacer2(); + const int num_threads = ord::OpenRoad::openRoad()->getThreadCount(); + return macro_placer->place(num_threads, + max_num_macro, + min_num_macro, + max_num_inst, + min_num_inst, + tolerance, + max_num_level, + coarsening_ratio, + num_bundled_ios, + 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, + boundary_weight, + notch_weight, + macro_blockage_weight, + pin_access_th, + target_util, + target_dead_space, + min_ar, + snap_layer, + bus_planning_on, + report_directory); + } -void set_debug_cmd(odb::dbBlock* block, - bool coarse, - bool fine, - bool show_bundled_nets, - bool show_clusters_ids, - bool skip_steps, - bool only_final_result, - int target_cluster_id) -{ - auto macro_placer = getMacroPlacer2(); - std::unique_ptr graphics - = std::make_unique(coarse, fine, block, ord::getLogger()); - macro_placer->setDebug(graphics); - macro_placer->setDebugShowBundledNets(show_bundled_nets); - macro_placer->setDebugShowClustersIds(show_clusters_ids); - macro_placer->setDebugSkipSteps(skip_steps); - macro_placer->setDebugOnlyFinalResult(only_final_result); - macro_placer->setDebugTargetClusterId(target_cluster_id); -} + void set_debug_cmd(odb::dbBlock* block, + bool coarse, + bool fine, + bool show_bundled_nets, + bool show_clusters_ids, + bool skip_steps, + bool only_final_result, + int target_cluster_id) + { + auto macro_placer = getMacroPlacer2(); + std::unique_ptr graphics + = std::make_unique(coarse, fine, block, ord::getLogger()); + macro_placer->setDebug(graphics); + macro_placer->setDebugShowBundledNets(show_bundled_nets); + macro_placer->setDebugShowClustersIds(show_clusters_ids); + macro_placer->setDebugSkipSteps(skip_steps); + macro_placer->setDebugOnlyFinalResult(only_final_result); + macro_placer->setDebugTargetClusterId(target_cluster_id); + } -void -place_macro(odb::dbInst* inst, float x_origin, float y_origin, std::string orientation_string) -{ - odb::dbOrientType orientation(orientation_string.c_str()); + void place_macro(odb::dbInst* inst, + float x_origin, + float y_origin, + std::string orientation_string) + { + odb::dbOrientType orientation(orientation_string.c_str()); - getMacroPlacer2()->placeMacro(inst, x_origin, y_origin, orientation); -} + getMacroPlacer2()->placeMacro(inst, x_origin, y_origin, orientation); + } -void -set_macro_placement_file(std::string file_name) -{ - getMacroPlacer2()->setMacroPlacementFile(file_name); -} + void set_macro_placement_file(std::string file_name) + { + getMacroPlacer2()->setMacroPlacementFile(file_name); + } -} // namespace + } // namespace mpl2 -%} // inline + % +} // inline diff --git a/src/mpl2/src/mpl.tcl b/src/mpl2/src/mpl.tcl index e0b1206634f..fc4b3053afc 100644 --- a/src/mpl2/src/mpl.tcl +++ b/src/mpl2/src/mpl.tcl @@ -1,340 +1,384 @@ -############################################################################ -## BSD 3-Clause License -## -## Copyright (c) 2021, The Regents of the University of California -## All rights reserved. -## -## Redistribution and use in source and binary forms, with or without -## modification, are permitted provided that the following conditions are met: -## -## * Redistributions of source code must retain the above copyright notice, this -## list of conditions and the following disclaimer. -## -## * Redistributions in binary form must reproduce the above copyright notice, -## this list of conditions and the following disclaimer in the documentation -## and/or other materials provided with the distribution. -## -## * Neither the name of the copyright holder nor the names of its -## contributors may be used to endorse or promote products derived from -## this software without specific prior written permission. -## -## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -## ARE -## DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -## FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -############################################################################ +##############################################################################BSD 3 + - Clause License####Copyright(c) 2021, + The Regents of the University of California + ##All rights reserved.####Redistribution and use in source and binary forms, + with or without##modification, + are permitted provided that the following conditions are met + :####*Redistributions of source code must retain the above copyright notice, + this##list of conditions and the following disclaimer.####*Redistributions + in binary form must reproduce the above copyright notice, + ##this list of conditions and the following disclaimer in the documentation + ##and / + or other materials provided with the distribution.####*Neither the name + of the copyright holder nor the names of its + ##contributors may be used to endorse + or promote products derived from + ##this software without specific prior written permission.####THIS + SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS"##AND ANY EXPRESS OR IMPLIED WARRANTIES, + INCLUDING, + BUT NOT LIMITED TO, + THE##IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + PARTICULAR PURPOSE##ARE + ##DISCLAIMED.IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + CONTRIBUTORS BE LIABLE##FOR ANY DIRECT, + INDIRECT, + INCIDENTAL, + SPECIAL, + EXEMPLARY, + OR CONSEQUENTIAL##DAMAGES(INCLUDING, + BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR##SERVICES; + LOSS OF USE, DATA, OR PROFITS; + OR BUSINESS INTERRUPTION) HOWEVER + ##CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, + STRICT LIABILITY, + ##OR + TORT(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + ##OF THIS SOFTWARE, + EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE + .############################################################################ -sta::define_cmd_args "rtl_macro_placer" { -max_num_macro max_num_macro \ - -min_num_macro min_num_macro \ - -max_num_inst max_num_inst \ - -min_num_inst min_num_inst \ - -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 \ - -halo_height halo_height \ - -fence_lx fence_lx \ - -fence_ly fence_ly \ - -fence_ux fence_ux \ - -fence_uy fence_uy \ - -area_weight area_weight \ - -outline_weight outline_weight \ - -wirelength_weight wirelength_weight \ - -guidance_weight guidance_weight \ - -fence_weight fence_weight \ - -boundary_weight boundary_weight \ - -notch_weight notch_weight \ - -macro_blockage_weight macro_blockage_weight \ - -pin_access_th pin_access_th \ - -target_util target_util \ - -target_dead_space target_dead_space \ - -min_ar min_ar \ - -snap_layer snap_layer \ - -bus_planning \ - -report_directory report_directory \ - -write_macro_placement file_name \ - } -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 \ - -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 \ - -boundary_weight -notch_weight -macro_blockage_weight \ - -pin_access_th -target_util \ - -target_dead_space -min_ar -snap_layer \ - -report_directory \ - -write_macro_placement } \ - flags {-bus_planning} + sta::define_cmd_args "rtl_macro_placer" { + -max_num_macro max_num_macro - min_num_macro min_num_macro + - max_num_inst max_num_inst - min_num_inst min_num_inst + - 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 - halo_height halo_height - fence_lx fence_lx + - fence_ly fence_ly - fence_ux fence_ux - fence_uy fence_uy + - area_weight area_weight - outline_weight outline_weight + - wirelength_weight wirelength_weight - guidance_weight guidance_weight + - fence_weight fence_weight - boundary_weight boundary_weight + - notch_weight notch_weight + - macro_blockage_weight macro_blockage_weight + - pin_access_th pin_access_th - target_util target_util + - target_dead_space target_dead_space - min_ar min_ar + - snap_layer snap_layer - bus_planning + - report_directory report_directory + - write_macro_placement file_name} 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 + - 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 - boundary_weight - notch_weight + - macro_blockage_weight - pin_access_th - target_util - target_dead_space + - min_ar - snap_layer - report_directory + - write_macro_placement} flags{-bus_planning} sta::check_argc_eq0 "rtl_macro_placer" $args - # - # Check for valid design - if { [ord::get_db_block] == "NULL" } { +# +#Check for valid design + if {[ord::get_db_block] == "NULL"} + { utl::error MPL 1 "No block found for Macro Placement." } - # Set the default parameters for the macro_placer - # Set auto defaults for min/max std cells and macros based on design - set max_num_macro 0 - set min_num_macro 0 - set max_num_inst 0 - set min_num_inst 0 - 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 - set halo_height 0.0 - set fence_lx 0.0 - set fence_ly 0.0 - set fence_ux 100000000.0 - set fence_uy 100000000.0 +#Set the default parameters for the macro_placer +#Set auto defaults for min / max std cells and macros based on design + set max_num_macro 0 set min_num_macro 0 set max_num_inst 0 set + min_num_inst 0 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 set halo_height 0.0 set fence_lx 0.0 set + fence_ly 0.0 set fence_ux 100000000.0 set + fence_uy 100000000.0 - set area_weight 0.1 - set outline_weight 100.0 - set wirelength_weight 100.0 - set guidance_weight 10.0 - set fence_weight 10.0 - set boundary_weight 50.0 - set notch_weight 10.0 - set macro_blockage_weight 10.0 - set pin_access_th 0.00 - set target_util 0.25 - set target_dead_space 0.05 - set min_ar 0.33 - set snap_layer -1 - set report_directory "hier_rtlmp" + set area_weight 0.1 set outline_weight 100.0 set + wirelength_weight 100.0 set guidance_weight 10.0 set + fence_weight 10.0 set boundary_weight 50.0 set + notch_weight 10.0 set macro_blockage_weight 10.0 set + pin_access_th 0.00 set target_util 0.25 set + target_dead_space 0.05 set min_ar 0.33 set snap_layer + - 1 set report_directory "hier_rtlmp" - if { [info exists keys(-max_num_macro)] } { + if {[info exists keys(-max_num_macro)]} + { set max_num_macro $keys(-max_num_macro) } - if { [info exists keys(-min_num_macro)] } { + if { + [info exists keys(-min_num_macro)] + } + { set min_num_macro $keys(-min_num_macro) } - if { [info exists keys(-max_num_inst)] } { + if { + [info exists keys(-max_num_inst)] + } + { set max_num_inst $keys(-max_num_inst) } - if { [info exists keys(-min_num_inst)] } { + if { + [info exists keys(-min_num_inst)] + } + { set min_num_inst $keys(-min_num_inst) } - if { [info exists keys(-tolerance)] } { + if { + [info exists keys(-tolerance)] + } + { set tolerance $keys(-tolerance) } - if { [info exists keys(-max_num_level)] } { + if { + [info exists keys(-max_num_level)] + } + { set max_num_level $keys(-max_num_level) } - if { [info exists keys(-coarsening_ratio)] } { + if { + [info exists keys(-coarsening_ratio)] + } + { set coarsening_ratio $keys(-coarsening_ratio) } - if { [info exists keys(-num_bundled_ios)] } { + if { + [info exists keys(-num_bundled_ios)] + } + { set num_bundled_ios $keys(-num_bundled_ios) } - if { [info exists keys(-large_net_threshold)] } { + if { + [info exists keys(-large_net_threshold)] + } + { set large_net_threshold $keys(-large_net_threshold) } - if { [info exists keys(-signature_net_threshold)] } { + if { + [info exists keys(-signature_net_threshold)] + } + { set signature_net_threshold $keys(-signature_net_threshold) } - if { [info exists keys(-halo_width)] && [info exists keys(-halo_height)] } { - set halo_width $keys(-halo_width) - set halo_height $keys(-halo_height) - } elseif { [info exists keys(-halo_width)] } { - set halo_width $keys(-halo_width) - set halo_height $keys(-halo_width) - } elseif { [info exists keys(-halo_height)] } { - set halo_width $keys(-halo_height) - set halo_height $keys(-halo_height) + if { + [info exists keys(-halo_width)] && [info exists keys(-halo_height)] + } + {set halo_width $keys(-halo_width) set halo_height $keys( + -halo_height)} elseif{[info exists keys(-halo_width)]} { + set halo_width $keys(-halo_width) set halo_height $keys( + -halo_width)} elseif{[info exists keys(-halo_height)]} + { + set halo_width $keys(-halo_height) set halo_height $keys(-halo_height) } - if { [info exists keys(-fence_lx)] } { + if { + [info exists keys(-fence_lx)] + } + { set fence_lx $keys(-fence_lx) } - if { [info exists keys(-fence_ly)] } { + if { + [info exists keys(-fence_ly)] + } + { set fence_ly $keys(-fence_ly) } - if { [info exists keys(-fence_ux)] } { + if { + [info exists keys(-fence_ux)] + } + { set fence_ux $keys(-fence_ux) } - if { [info exists keys(-fence_uy)] } { + if { + [info exists keys(-fence_uy)] + } + { set fence_uy $keys(-fence_uy) } - if { [info exists keys(-area_weight)] } { + if { + [info exists keys(-area_weight)] + } + { set area_weight $keys(-area_weight) } - if { [info exists keys(-wirelength_weight)] } { + if { + [info exists keys(-wirelength_weight)] + } + { set wirelength_weight $keys(-wirelength_weight) } - if { [info exists keys(-outline_weight)] } { + if { + [info exists keys(-outline_weight)] + } + { set outline_weight $keys(-outline_weight) } - if { [info exists keys(-guidance_weight)] } { + if { + [info exists keys(-guidance_weight)] + } + { set guidance_weight $keys(-guidance_weight) } - if { [info exists keys(-fence_weight)] } { + if { + [info exists keys(-fence_weight)] + } + { set fence_weight $keys(-fence_weight) } - if { [info exists keys(-boundary_weight)] } { + if { + [info exists keys(-boundary_weight)] + } + { set boundary_weight $keys(-boundary_weight) } - if { [info exists keys(-notch_weight)] } { + if { + [info exists keys(-notch_weight)] + } + { set notch_weight $keys(-notch_weight) } - if { [info exists keys(-macro_blockage_weight)] } { + if { + [info exists keys(-macro_blockage_weight)] + } + { set macro_blockage_weight $keys(-macro_blockage_weight) } - if { [info exists keys(-pin_access_th)] } { + if { + [info exists keys(-pin_access_th)] + } + { set pin_access_th $keys(-pin_access_th) } - if { [info exists keys(-target_util)] } { + if { + [info exists keys(-target_util)] + } + { set target_util $keys(-target_util) } - if { [info exists keys(-target_dead_space)] } { + if { + [info exists keys(-target_dead_space)] + } + { set target_dead_space $keys(-target_dead_space) } - if { [info exists keys(-min_ar)] } { + if { + [info exists keys(-min_ar)] + } + { set min_ar $keys(-min_ar) } - if { [info exists keys(-snap_layer)] } { + if { + [info exists keys(-snap_layer)] + } + { set snap_layer $keys(-snap_layer) } - if { [info exists keys(-report_directory)] } { - set report_directory $keys(-report_directory) + if { + [info exists keys(-report_directory)] } + {set report_directory $keys(-report_directory)} file mkdir $report_directory - if { [info exists keys(-write_macro_placement)] } { + if {[info exists keys(-write_macro_placement)]} + { mpl2::set_macro_placement_file $keys(-write_macro_placement) } if { - ![mpl2::rtl_macro_placer_cmd $max_num_macro \ - $min_num_macro \ - $max_num_inst \ - $min_num_inst \ - $tolerance \ - $max_num_level \ - $coarsening_ratio \ - $num_bundled_ios \ - $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 $boundary_weight \ - $notch_weight $macro_blockage_weight \ - $pin_access_th \ - $target_util \ - $target_dead_space \ - $min_ar \ - $snap_layer \ - [info exists flags(-bus_planning)] \ - $report_directory] - } { + ![mpl2::rtl_macro_placer_cmd $max_num_macro $min_num_macro $max_num_inst + $min_num_inst $tolerance $max_num_level $coarsening_ratio + $num_bundled_ios $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 + $boundary_weight $notch_weight + $macro_blockage_weight $pin_access_th + $target_util $target_dead_space $min_ar + $snap_layer[info exists flags( + -bus_planning)] + $report_directory] + } + { return false } return true } -sta::define_cmd_args "place_macro" {-macro_name macro_name \ - -location location \ - [-orientation orientation] \ -} +sta::define_cmd_args "place_macro" { + -macro_name macro_name - location location[-orientation orientation]} -proc place_macro { args } { - sta::parse_key_args "place_macro" args \ - keys {-macro_name -location -orientation} flags {} +proc place_macro{args} +{ + sta::parse_key_args + "place_macro" args keys{-macro_name - location - orientation} flags + { + } - if { [info exists keys(-macro_name)] } { + if { + [info exists keys(-macro_name)] + } + { set macro_name $keys(-macro_name) - } else { - utl::error MPL 19 "-macro_name is required." } + else {utl::error MPL 19 "-macro_name is required."} - set macro [mpl2::parse_macro_name "place_macro" $macro_name] + set macro[mpl2::parse_macro_name "place_macro" $macro_name] - if { [info exists keys(-location)] } { + if {[info exists keys(-location)]} + { set location $keys(-location) - } else { - utl::error MPL 22 "-location is required." } + else { utl::error MPL 22 "-location is required." } - if { [llength $location] != 2 } { - utl::error MPL 12 "-location is not a list of 2 values." + if { + [llength $location] != 2 } - lassign $location x_origin y_origin - set x_origin $x_origin - set y_origin $y_origin + {utl::error MPL 12 "-location is not a list of 2 values."} lassign $location + x_origin y_origin set x_origin $x_origin set y_origin $y_origin - set orientation R0 - if { [info exists keys(-orientation)] } { - set orientation $keys(-orientation) - } + set orientation R0 if {[info exists keys(-orientation)]} { + set orientation $keys(-orientation)} mpl2::place_macro $macro $x_origin $y_origin $orientation } namespace eval mpl2 { -proc parse_macro_name { cmd macro_name } { - set block [ord::get_db_block] - set inst [$block findInst "$macro_name"] +proc parse_macro_name{cmd macro_name} +{ + set block[ord::get_db_block] set inst[$block findInst "$macro_name"] - if { $inst == "NULL" } { - utl::error MPL 20 "Couldn't find a macro named $macro_name." - } elseif { ![$inst isBlock] } { + if {$inst == "NULL"} { + utl::error MPL 20 "Couldn't find a macro named $macro_name."} elseif{ + ![$inst isBlock]} + { utl::error MPL 21 "[$inst getName] is not a macro." } return $inst } -proc mpl_debug { args } { - sta::parse_key_args "mpl_debug" args \ - keys { -target_cluster_id target_cluster_id } \ - flags {-coarse -fine -show_bundled_nets \ - -show_clusters_ids \ - -skip_steps -only_final_result} ;# checker off +proc mpl_debug{args} +{ + sta::parse_key_args + "mpl_debug" args keys{-target_cluster_id target_cluster_id} flags{ + -coarse - fine - show_bundled_nets - show_clusters_ids - skip_steps + - only_final_result}; +#checker off - set coarse [info exists flags(-coarse)] - set fine [info exists flags(-fine)] - if { !$coarse && !$fine } { - set coarse true - set fine true - } - set block [ord::get_db_block] + set coarse[info exists flags(-coarse)] set fine[info exists flags( + -fine)] if { + !$coarse + && !$fine } {set coarse true set fine true } set + block[ord::get_db_block] - set target_cluster_id -1 - if { [info exists keys(-target_cluster_id)] } { - set target_cluster_id $keys(-target_cluster_id) - } + set target_cluster_id + - 1 if {[info exists keys(-target_cluster_id)] } { + set target_cluster_id $keys(-target_cluster_id) } - mpl2::set_debug_cmd $block \ - $coarse \ - $fine \ - [info exists flags(-show_bundled_nets)] \ - [info exists flags(-show_clusters_ids)] \ - [info exists flags(-skip_steps)] \ - [info exists flags(-only_final_result)] \ - $target_cluster_id -} + mpl2::set_debug_cmd $block $coarse $fine[info exists flags( + -show_bundled_nets)][info exists + flags(-show_clusters_ids)] + [info exists flags(-skip_steps)][info exists flags( + -only_final_result)] $target_cluster_id } +} // namespace mpl2