diff --git a/src/mpl/src/clusterEngine.cpp b/src/mpl/src/clusterEngine.cpp index aab24d62f8d..8a29de44493 100644 --- a/src/mpl/src/clusterEngine.cpp +++ b/src/mpl/src/clusterEngine.cpp @@ -5,6 +5,7 @@ #include #include +#include #include #include #include @@ -1109,6 +1110,25 @@ void ClusteringEngine::breakLargeFlatCluster(Cluster* parent) { updateInstancesAssociation(parent); + // A cluster dominated by one macro cannot be partitioned correctly using + // the weighted min-cut algorithm from TritonPart, so we manually + // split the macro from the cluster + if (parent->getNumMacro() > 0) { + auto macros = parent->getLeafMacros(); + auto max_macro + = *std::ranges::max_element(macros, {}, [](const auto& macro) { + return macro->getBBox()->getBox().area(); + }); + + if (computeArea(max_macro) > (parent->getArea() / 2)) { + splitHugeMacroFromCluster(parent, max_macro); + if (isLargeFlatCluster(parent)) { + breakLargeFlatCluster(parent); + } + return; + } + } + std::map cluster_vertex_id_map; std::vector vertex_weight; int vertex_id = 0; @@ -1120,9 +1140,11 @@ void ClusteringEngine::breakLargeFlatCluster(Cluster* parent) std::vector insts; odb::PtrMap inst_vertex_id_map; + for (auto& macro : parent->getLeafMacros()) { inst_vertex_id_map[macro] = vertex_id++; - vertex_weight.push_back(block_->dbuAreaToMicrons(computeArea(macro))); + float weight = block_->dbuAreaToMicrons(computeArea(macro)); + vertex_weight.push_back(weight); insts.push_back(macro); } for (auto& std_cell : parent->getLeafStdCells()) { @@ -1253,6 +1275,28 @@ void ClusteringEngine::breakLargeFlatCluster(Cluster* parent) } } +void ClusteringEngine::splitHugeMacroFromCluster(Cluster* cluster, + odb::dbInst* huge_macro) +{ + // Remove huge macro from parent cluster + std::vector macros = cluster->getLeafMacros(); + cluster->clearLeafMacros(); + for (auto* macro : macros) { + if (macro != huge_macro) { + cluster->addLeafMacro(macro); + } + } + updateInstancesAssociation(cluster); + setClusterMetrics(cluster); + + // Create a new cluster for the huge macro + auto macro_cluster + = std::make_unique(id_, huge_macro->getName(), logger_); + macro_cluster->addLeafMacro(huge_macro); + macro_cluster->setClusterType(HardMacroCluster); + incorporateNewCluster(std::move(macro_cluster), cluster->getParent()); +} + bool ClusteringEngine::partitionerSolutionIsFullyUnbalanced( const std::vector& solution, const int num_other_cluster_vertices) @@ -1684,6 +1728,10 @@ void ClusteringEngine::fetchMixedLeaves( std::vector sister_mixed_leaves; for (auto& child : parent->getChildren()) { + if (child->getClusterType() == HardMacroCluster) { + continue; + } + updateInstancesAssociation(child.get()); if (child->getNumMacro() == 0) { diff --git a/src/mpl/src/clusterEngine.h b/src/mpl/src/clusterEngine.h index 5c38b9f0fde..f35f8c00f2d 100644 --- a/src/mpl/src/clusterEngine.h +++ b/src/mpl/src/clusterEngine.h @@ -176,6 +176,7 @@ class ClusteringEngine void updateSubTree(Cluster* parent); bool isLargeFlatCluster(const Cluster* cluster) const; void breakLargeFlatCluster(Cluster* parent); + void splitHugeMacroFromCluster(Cluster* cluster, odb::dbInst* huge_macro); bool partitionerSolutionIsFullyUnbalanced(const std::vector& solution, int num_other_cluster_vertices); void mergeChildrenBelowThresholds(std::vector& small_children); diff --git a/src/mpl/test/BUILD b/src/mpl/test/BUILD index c1e2eda5562..9f1b59c330a 100644 --- a/src/mpl/test/BUILD +++ b/src/mpl/test/BUILD @@ -40,6 +40,7 @@ COMPULSORY_TESTS = [ "macro_only", "macros_without_pins1", "mixed_ios1", + "break_cluster_huge_macro", "no_unfixed_macros", "orientation_improve1", "orientation_improve2", @@ -73,6 +74,10 @@ filegroup( "testcases/boundary_push1.def", "testcases/orientation_improve1.lef", ], + "break_cluster_huge_macro": [ + "testcases/break_cluster_huge_macro.def", + "testcases/break_cluster_huge_macro.lef", + ], "centralization1": [ "testcases/centralization1.def", "testcases/orientation_improve1.lef", diff --git a/src/mpl/test/CMakeLists.txt b/src/mpl/test/CMakeLists.txt index 081841ce50c..45b26aa0fa6 100644 --- a/src/mpl/test/CMakeLists.txt +++ b/src/mpl/test/CMakeLists.txt @@ -35,6 +35,7 @@ or_integration_tests( halos2 halos3 halos4 + break_cluster_huge_macro ) diff --git a/src/mpl/test/break_cluster_huge_macro.defok b/src/mpl/test/break_cluster_huge_macro.defok new file mode 100644 index 00000000000..9ee94c26d80 --- /dev/null +++ b/src/mpl/test/break_cluster_huge_macro.defok @@ -0,0 +1,92 @@ +VERSION 5.8 ; +DIVIDERCHAR "/" ; +BUSBITCHARS "[]" ; +DESIGN mpl_dominated ; +UNITS DISTANCE MICRONS 1000 ; +DIEAREA ( 0 0 ) ( 30000000 30000000 ) ; +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 23 ; + - macro1 LARGE_MACRO_CELL + FIXED ( 0 -8895220 ) FS ; + - macro2 LARGE_MACRO_CELL + FIXED ( 0 -8895220 ) S ; + - macro3 LARGE_MACRO_CELL + FIXED ( 0 894780 ) N ; + - sc0 SMALL_STDCELL_CELL + PLACED ( 19999500 5003392 ) N ; + - sc1 SMALL_STDCELL_CELL + PLACED ( 19999500 5003392 ) N ; + - sc10 SMALL_STDCELL_CELL + PLACED ( 19999500 20011177 ) N ; + - sc11 SMALL_STDCELL_CELL + PLACED ( 19999500 20011177 ) N ; + - sc12 SMALL_STDCELL_CELL + PLACED ( 19999500 20011177 ) N ; + - sc13 SMALL_STDCELL_CELL + PLACED ( 19999500 20011177 ) N ; + - sc14 SMALL_STDCELL_CELL + PLACED ( 19999500 20011177 ) N ; + - sc15 SMALL_STDCELL_CELL + PLACED ( 19999500 10011177 ) N ; + - sc16 SMALL_STDCELL_CELL + PLACED ( 19999500 10011177 ) N ; + - sc17 SMALL_STDCELL_CELL + PLACED ( 19999500 10011177 ) N ; + - sc18 SMALL_STDCELL_CELL + PLACED ( 19999500 10011177 ) N ; + - sc19 SMALL_STDCELL_CELL + PLACED ( 19999500 10011177 ) N ; + - sc2 SMALL_STDCELL_CELL + PLACED ( 19999500 5003392 ) N ; + - sc3 SMALL_STDCELL_CELL + PLACED ( 19999500 5003392 ) N ; + - sc4 SMALL_STDCELL_CELL + PLACED ( 19999500 5003392 ) N ; + - sc5 SMALL_STDCELL_CELL + PLACED ( 19999500 10018962 ) N ; + - sc6 SMALL_STDCELL_CELL + PLACED ( 19999500 10018962 ) N ; + - sc7 SMALL_STDCELL_CELL + PLACED ( 19999500 10018962 ) N ; + - sc8 SMALL_STDCELL_CELL + PLACED ( 19999500 10018962 ) N ; + - sc9 SMALL_STDCELL_CELL + PLACED ( 19999500 10018962 ) N ; +END COMPONENTS +BLOCKAGES 3 ; + - PLACEMENT + SOFT + COMPONENT macro1 RECT ( 0 -8895220 ) ( 10000000 1104780 ) ; + - PLACEMENT + SOFT + COMPONENT macro2 RECT ( 0 -8895220 ) ( 10000000 1104780 ) ; + - PLACEMENT + SOFT + COMPONENT macro3 RECT ( 0 894780 ) ( 10000000 10894780 ) ; +END BLOCKAGES +NETS 31 ; + - net1 ( macro1 p ) ( sc0 a ) ( sc1 a ) ( sc2 a ) ( sc3 a ) ( sc4 a ) ( sc5 a ) + ( sc6 a ) ( sc7 a ) ( sc8 a ) ( sc9 a ) ( sc10 a ) ( sc11 a ) ( sc12 a ) ( sc13 a ) + ( sc14 a ) ( sc15 a ) ( sc16 a ) ( sc17 a ) ( sc18 a ) ( sc19 a ) + USE SIGNAL ; + - net_m12_0 + USE SIGNAL ; + - net_m12_1 + USE SIGNAL ; + - net_m12_2 + USE SIGNAL ; + - net_m12_3 + USE SIGNAL ; + - net_m12_4 + USE SIGNAL ; + - net_m12_5 + USE SIGNAL ; + - net_m12_6 + USE SIGNAL ; + - net_m12_7 + USE SIGNAL ; + - net_m12_8 + USE SIGNAL ; + - net_m12_9 + USE SIGNAL ; + - net_m23_0 ( macro2 p0 ) + USE SIGNAL ; + - net_m23_1 ( macro2 p1 ) + USE SIGNAL ; + - net_m23_2 ( macro2 p2 ) + USE SIGNAL ; + - net_m23_3 ( macro2 p3 ) + USE SIGNAL ; + - net_m23_4 ( macro2 p4 ) + USE SIGNAL ; + - net_m23_5 ( macro2 p5 ) + USE SIGNAL ; + - net_m23_6 ( macro2 p6 ) + USE SIGNAL ; + - net_m23_7 ( macro2 p7 ) + USE SIGNAL ; + - net_m23_8 ( macro2 p8 ) + USE SIGNAL ; + - net_m23_9 ( macro2 p9 ) + USE SIGNAL ; + - net_m31_0 ( macro3 p0 ) ( macro1 p0 ) + USE SIGNAL ; + - net_m31_1 ( macro3 p1 ) ( macro1 p1 ) + USE SIGNAL ; + - net_m31_2 ( macro3 p2 ) ( macro1 p2 ) + USE SIGNAL ; + - net_m31_3 ( macro3 p3 ) ( macro1 p3 ) + USE SIGNAL ; + - net_m31_4 ( macro3 p4 ) ( macro1 p4 ) + USE SIGNAL ; + - net_m31_5 ( macro3 p5 ) ( macro1 p5 ) + USE SIGNAL ; + - net_m31_6 ( macro3 p6 ) ( macro1 p6 ) + USE SIGNAL ; + - net_m31_7 ( macro3 p7 ) ( macro1 p7 ) + USE SIGNAL ; + - net_m31_8 ( macro3 p8 ) ( macro1 p8 ) + USE SIGNAL ; + - net_m31_9 ( macro3 p9 ) ( macro1 p9 ) + USE SIGNAL ; +END NETS +END DESIGN diff --git a/src/mpl/test/break_cluster_huge_macro.ok b/src/mpl/test/break_cluster_huge_macro.ok new file mode 100644 index 00000000000..1c3962a62d0 --- /dev/null +++ b/src/mpl/test/break_cluster_huge_macro.ok @@ -0,0 +1,23 @@ +[INFO ODB-0227] LEF file: ./Nangate45/Nangate45_tech.lef, created 22 layers, 27 vias +[INFO ODB-0227] LEF file: ./testcases/break_cluster_huge_macro.lef, created 2 library cells +[INFO ODB-0128] Design: mpl_dominated +[INFO ODB-0131] Created 23 components and 53 component-terminals. +[INFO ODB-0133] Created 31 nets and 81 connections. +Die Area: (0.00, 0.00) (30000.00, 30000.00), Floorplan Area: (0.00, 0.00) (30000.00, 30000.00) + Number of std cell instances: 20 + Area of std cell instances: 20.00 + Number of macros: 3 + Area of macros: 300000000.00 + Base halo (L, B, R, T): (0.00, 0.00, 0.00, 0.00) + Area of macros with halos: 300000000.00 + Area of std cell instances + Area of macros: 300000020.00 + Floorplan area: 900000000.00 + Design Utilization: 0.33 + Floorplan Utilization: 0.00 + Manufacturing Grid: 10 + +[WARNING MPL-0026] Design has no IO pins! +[WARNING MPL-0002] Could not align all pins of the macro macro1 to the track-grid. 1 out of 11 pins were aligned. +[WARNING MPL-0002] Could not align all pins of the macro macro2 to the track-grid. 1 out of 11 pins were aligned. +[WARNING MPL-0002] Could not align all pins of the macro macro3 to the track-grid. 1 out of 11 pins were aligned. +No differences found. diff --git a/src/mpl/test/break_cluster_huge_macro.tcl b/src/mpl/test/break_cluster_huge_macro.tcl new file mode 100644 index 00000000000..c91cbb0b111 --- /dev/null +++ b/src/mpl/test/break_cluster_huge_macro.tcl @@ -0,0 +1,17 @@ +# Test if we handle macro-dominated partitions correctly +source "helpers.tcl" + +read_lef "./Nangate45/Nangate45_tech.lef" +read_lef "./testcases/break_cluster_huge_macro.lef" + +read_def "./testcases/break_cluster_huge_macro.def" + +set_thread_count 0 +rtl_macro_placer -max_num_macro 3 -min_num_macro 1 \ + -max_num_inst 5 -min_num_inst 2 \ + -report_directory [make_result_dir] + +set def_file [make_result_file break_cluster_huge_macro.def] +write_def $def_file + +diff_files break_cluster_huge_macro.defok $def_file diff --git a/src/mpl/test/testcases/break_cluster_huge_macro.def b/src/mpl/test/testcases/break_cluster_huge_macro.def new file mode 100644 index 00000000000..63406c5c53b --- /dev/null +++ b/src/mpl/test/testcases/break_cluster_huge_macro.def @@ -0,0 +1,110 @@ +VERSION 5.8 ; +DIVIDERCHAR "/" ; +BUSBITCHARS "[]" ; +DESIGN mpl_dominated ; +UNITS DISTANCE MICRONS 1000 ; +DIEAREA ( 0 0 ) ( 30000000 30000000 ) ; + +COMPONENTS 23 ; + - macro1 LARGE_MACRO_CELL ; + - macro2 LARGE_MACRO_CELL ; + - macro3 LARGE_MACRO_CELL ; + - sc0 SMALL_STDCELL_CELL ; + - sc1 SMALL_STDCELL_CELL ; + - sc2 SMALL_STDCELL_CELL ; + - sc3 SMALL_STDCELL_CELL ; + - sc4 SMALL_STDCELL_CELL ; + - sc5 SMALL_STDCELL_CELL ; + - sc6 SMALL_STDCELL_CELL ; + - sc7 SMALL_STDCELL_CELL ; + - sc8 SMALL_STDCELL_CELL ; + - sc9 SMALL_STDCELL_CELL ; + - sc10 SMALL_STDCELL_CELL ; + - sc11 SMALL_STDCELL_CELL ; + - sc12 SMALL_STDCELL_CELL ; + - sc13 SMALL_STDCELL_CELL ; + - sc14 SMALL_STDCELL_CELL ; + - sc15 SMALL_STDCELL_CELL ; + - sc16 SMALL_STDCELL_CELL ; + - sc17 SMALL_STDCELL_CELL ; + - sc18 SMALL_STDCELL_CELL ; + - sc19 SMALL_STDCELL_CELL ; +END COMPONENTS + +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 ; + +NETS 31 ; + - net1 + ( macro1 p ) + ( sc0 a ) + ( sc1 a ) + ( sc2 a ) + ( sc3 a ) + ( sc4 a ) + ( sc5 a ) + ( sc6 a ) + ( sc7 a ) + ( sc8 a ) + ( sc9 a ) + ( sc10 a ) + ( sc11 a ) + ( sc12 a ) + ( sc13 a ) + ( sc14 a ) + ( sc15 a ) + ( sc16 a ) + ( sc17 a ) + ( sc18 a ) + ( sc19 a ) ; + - net_m12_0 ( macro1 p0 ) ( macro2 p0 ) ; + - net_m12_1 ( macro1 p1 ) ( macro2 p1 ) ; + - net_m12_2 ( macro1 p2 ) ( macro2 p2 ) ; + - net_m12_3 ( macro1 p3 ) ( macro2 p3 ) ; + - net_m12_4 ( macro1 p4 ) ( macro2 p4 ) ; + - net_m12_5 ( macro1 p5 ) ( macro2 p5 ) ; + - net_m12_6 ( macro1 p6 ) ( macro2 p6 ) ; + - net_m12_7 ( macro1 p7 ) ( macro2 p7 ) ; + - net_m12_8 ( macro1 p8 ) ( macro2 p8 ) ; + - net_m12_9 ( macro1 p9 ) ( macro2 p9 ) ; + - net_m23_0 ( macro2 p0 ) ( macro3 p0 ) ; + - net_m23_1 ( macro2 p1 ) ( macro3 p1 ) ; + - net_m23_2 ( macro2 p2 ) ( macro3 p2 ) ; + - net_m23_3 ( macro2 p3 ) ( macro3 p3 ) ; + - net_m23_4 ( macro2 p4 ) ( macro3 p4 ) ; + - net_m23_5 ( macro2 p5 ) ( macro3 p5 ) ; + - net_m23_6 ( macro2 p6 ) ( macro3 p6 ) ; + - net_m23_7 ( macro2 p7 ) ( macro3 p7 ) ; + - net_m23_8 ( macro2 p8 ) ( macro3 p8 ) ; + - net_m23_9 ( macro2 p9 ) ( macro3 p9 ) ; + - net_m31_0 ( macro3 p0 ) ( macro1 p0 ) ; + - net_m31_1 ( macro3 p1 ) ( macro1 p1 ) ; + - net_m31_2 ( macro3 p2 ) ( macro1 p2 ) ; + - net_m31_3 ( macro3 p3 ) ( macro1 p3 ) ; + - net_m31_4 ( macro3 p4 ) ( macro1 p4 ) ; + - net_m31_5 ( macro3 p5 ) ( macro1 p5 ) ; + - net_m31_6 ( macro3 p6 ) ( macro1 p6 ) ; + - net_m31_7 ( macro3 p7 ) ( macro1 p7 ) ; + - net_m31_8 ( macro3 p8 ) ( macro1 p8 ) ; + - net_m31_9 ( macro3 p9 ) ( macro1 p9 ) ; +END NETS + +END DESIGN diff --git a/src/mpl/test/testcases/break_cluster_huge_macro.lef b/src/mpl/test/testcases/break_cluster_huge_macro.lef new file mode 100644 index 00000000000..635a1989ae4 --- /dev/null +++ b/src/mpl/test/testcases/break_cluster_huge_macro.lef @@ -0,0 +1,105 @@ +VERSION 5.6 ; +BUSBITCHARS "[]" ; +DIVIDERCHAR "/" ; + +MACRO LARGE_MACRO_CELL + CLASS BLOCK ; + ORIGIN 0 0 ; + SYMMETRY X Y ; + SIZE 10000 BY 10000 ; + PIN p + DIRECTION OUTPUT ; + PORT + LAYER metal3 ; + RECT 0 0 10 10 ; + END + END p + PIN p0 + DIRECTION INOUT ; + PORT + LAYER metal3 ; + RECT 0 20 10 30 ; + END + END p0 + PIN p1 + DIRECTION INOUT ; + PORT + LAYER metal3 ; + RECT 0 40 10 50 ; + END + END p1 + PIN p2 + DIRECTION INOUT ; + PORT + LAYER metal3 ; + RECT 0 60 10 70 ; + END + END p2 + PIN p3 + DIRECTION INOUT ; + PORT + LAYER metal3 ; + RECT 0 80 10 90 ; + END + END p3 + PIN p4 + DIRECTION INOUT ; + PORT + LAYER metal3 ; + RECT 0 100 10 110 ; + END + END p4 + PIN p5 + DIRECTION INOUT ; + PORT + LAYER metal3 ; + RECT 0 120 10 130 ; + END + END p5 + PIN p6 + DIRECTION INOUT ; + PORT + LAYER metal3 ; + RECT 0 140 10 150 ; + END + END p6 + PIN p7 + DIRECTION INOUT ; + PORT + LAYER metal3 ; + RECT 0 160 10 170 ; + END + END p7 + PIN p8 + DIRECTION INOUT ; + PORT + LAYER metal3 ; + RECT 0 180 10 190 ; + END + END p8 + PIN p9 + DIRECTION INOUT ; + PORT + LAYER metal3 ; + RECT 0 200 10 210 ; + END + END p9 + OBS + LAYER metal3 ; + RECT 0 0 10000 10000 ; + END +END LARGE_MACRO_CELL + +MACRO SMALL_STDCELL_CELL + CLASS CORE ; + ORIGIN 0 0 ; + SIZE 1 BY 1 ; + SYMMETRY X Y ; + PIN a + DIRECTION INPUT ; + PORT + LAYER metal1 ; + RECT 0 0 0.2 0.2 ; + END + END a +END SMALL_STDCELL_CELL