@@ -66,7 +66,7 @@ SACoreSoftMacro::SACoreSoftMacro(PhysicalHierarchy* tree,
6666{
6767 boundary_weight_ = soft_weights.boundary ;
6868 macro_blockage_weight_ = soft_weights.macro_blockage ;
69- original_notch_weight_ = soft_weights.notch ;
69+ notch_weight_ = soft_weights.notch ;
7070 resize_prob_ = resize_prob;
7171 notch_h_th_ = notch_h_threshold;
7272 notch_v_th_ = notch_v_threshold;
@@ -519,199 +519,105 @@ void SACoreSoftMacro::alignMacroClusters()
519519 }
520520}
521521
522+ float SACoreSoftMacro::calSingleNotchPenalty (float width, float height)
523+ {
524+ return std::sqrt ((width * height) / outline_.getArea ());
525+ }
526+
522527// If there is no HardMacroCluster, we do not consider the notch penalty
523528void SACoreSoftMacro::calNotchPenalty ()
524529{
525- // Initialization
526- notch_penalty_ = 0.0 ;
527530 if (notch_weight_ <= 0.0 ) {
528531 return ;
529532 }
530- // If the floorplan cannot fit into the outline
533+
534+ // Initialization
535+ notch_penalty_ = 0.0 ;
536+ notch_h_th_ = outline_.getHeight () / 10.0 ;
537+ notch_v_th_ = outline_.getWidth () / 10.0 ;
538+ float width = 0 ;
539+ float height = 0 ;
540+
541+ // If the floorplan is not valid
531542 // We think the entire floorplan is a "huge" notch
532- if (width_ > outline_. getWidth () * 1.001
533- || height_ > outline_.getHeight () * 1.001 ) {
534- notch_penalty_ += outline_. getWidth () * outline_.getHeight ()
535- / (outline_. getWidth () * outline_. getHeight () );
543+ if (! isValid ()) {
544+ width = std::max (width_, outline_.getWidth ());
545+ height = std::max (height_, outline_.getHeight ());
546+ notch_penalty_ = calSingleNotchPenalty (width, height );
536547 return ;
537548 }
538549
539- // Macros need to be saved (and restored) since alignMacroClusters and
540- // fillDeadSpace move them
541- std::vector<SoftMacro> pre_macros = macros_;
542- // align macro clusters to reduce notches
543- alignMacroClusters ();
544- // Fill dead space
545- fillDeadSpace ();
546550 // Create grids based on location of MixedCluster and HardMacroCluster
547551 std::set<float > x_point;
548552 std::set<float > y_point;
549- std::vector<bool > macro_mask;
550553 for (auto & macro : macros_) {
551- if (macro.getArea () <= 0.0
552- || (!macro.isMacroCluster () && !macro.isMixedCluster ())) {
553- macro_mask.push_back (false );
554+ if (!macro.isMacroCluster () && !macro.isMixedCluster ()) {
554555 continue ;
555556 }
556557 x_point.insert (macro.getX ());
557558 x_point.insert (macro.getX () + macro.getWidth ());
558559 y_point.insert (macro.getY ());
559560 y_point.insert (macro.getY () + macro.getHeight ());
560- macro_mask.push_back (true );
561561 }
562562 x_point.insert (0.0 );
563563 y_point.insert (0.0 );
564564 x_point.insert (outline_.getWidth ());
565565 y_point.insert (outline_.getHeight ());
566- // create grid
567- std::vector<float > x_grid (x_point.begin (), x_point.end ());
568- std::vector<float > y_grid (y_point.begin (), y_point.end ());
569- // create grid in a row-based manner
570- std::vector<std::vector<int >> grids; // store the macro id
571- const int num_x = x_grid.size () - 1 ;
572- const int num_y = y_grid.size () - 1 ;
573- for (int j = 0 ; j < num_y; j++) {
574- std::vector<int > macro_ids (num_x, -1 );
575- grids.push_back (macro_ids);
576- }
577- // detect the notch region around each MixedCluster and HardMacroCluster
578- for (int macro_id = 0 ; macro_id < macros_.size (); macro_id++) {
579- if (!macro_mask[macro_id]) {
566+
567+ std::vector<float > x_coords (x_point.begin (), x_point.end ());
568+ std::vector<float > y_coords (y_point.begin (), y_point.end ());
569+ int num_x = x_coords.size () - 1 ;
570+ int num_y = y_coords.size () - 1 ;
571+
572+ // Assign cluster locations for notch detection
573+ std::vector<std::vector<bool >> grid (num_y, std::vector<bool >(num_x, false ));
574+ for (auto & macro : macros_) {
575+ if (!macro.isMacroCluster () && !macro.isMixedCluster ()) {
580576 continue ;
581577 }
582- int x_start = 0 ;
583- int x_end = 0 ;
584- calSegmentLoc (macros_[macro_id].getX (),
585- macros_[macro_id].getX () + macros_[macro_id].getWidth (),
586- x_start,
587- x_end,
588- x_grid);
589- int y_start = 0 ;
590- int y_end = 0 ;
591- calSegmentLoc (macros_[macro_id].getY (),
592- macros_[macro_id].getY () + macros_[macro_id].getHeight (),
593- y_start,
594- y_end,
595- y_grid);
596- for (int j = y_start; j < y_end; j++) {
597- for (int i = x_start; i < x_end; i++) {
598- grids[j][i] = macro_id;
578+ int x_start = getSegmentIndex (macro.getX (), x_coords);
579+ int x_end = getSegmentIndex (macro.getX () + macro.getWidth (), x_coords);
580+ int y_start = getSegmentIndex (macro.getY (), y_coords);
581+ int y_end = getSegmentIndex (macro.getY () + macro.getHeight (), y_coords);
582+ for (int row = y_start; row < y_end; row++) {
583+ for (int col = x_start; col < x_end; col++) {
584+ grid[row][col] = true ;
599585 }
600586 }
601587 }
602- // check surroundings of each HardMacroCluster and MixecCluster
603- for (int macro_id = 0 ; macro_id < macros_.size (); macro_id++) {
604- if (!macro_mask[macro_id]) {
605- continue ;
606- }
607- int x_start = 0 ;
608- int x_end = 0 ;
609- calSegmentLoc (macros_[macro_id].getX (),
610- macros_[macro_id].getX () + macros_[macro_id].getWidth (),
611- x_start,
612- x_end,
613- x_grid);
614- int y_start = 0 ;
615- int y_end = 0 ;
616- calSegmentLoc (macros_[macro_id].getY (),
617- macros_[macro_id].getY () + macros_[macro_id].getHeight (),
618- y_start,
619- y_end,
620- y_grid);
621- int x_start_new = x_start;
622- int x_end_new = x_end;
623- int y_start_new = y_start;
624- int y_end_new = y_end;
625- // check left first
626- for (int i = x_start - 1 ; i >= 0 ; i--) {
627- bool flag = true ;
628- for (int j = y_start; j < y_end; j++) {
629- if (grids[j][i] != -1 ) {
630- flag = false ; // we cannot extend the current cluster
631- break ;
632- } // end if
633- } // end y
634- if (!flag) { // extension done
635- break ;
636- }
637- x_start_new--; // extend left
638- for (int j = y_start; j < y_end; j++) {
639- grids[j][i] = macro_id;
588+
589+ // An empty grid cell surrounded by 3 or more edges is considered a notch
590+ for (int row = 0 ; row < num_y; row++) {
591+ for (int col = 0 ; col < num_x; col++) {
592+ if (grid[row][col]) {
593+ continue ;
640594 }
641- } // end left
642- // check top second
643- for (int j = y_end; j < num_y; j++) {
644- bool flag = true ;
645- for (int i = x_start; i < x_end; i++) {
646- if (grids[j][i] != -1 ) {
647- flag = false ; // we cannot extend the current cluster
648- break ;
649- } // end if
650- } // end y
651- if (!flag) { // extension done
652- break ;
595+
596+ int surroundings = 0 ;
597+ if (row == 0 || grid[row - 1 ][col]) {
598+ surroundings++;
653599 }
654- y_end_new++; // extend top
655- for (int i = x_start; i < x_end; i++) {
656- grids[j][i] = macro_id;
600+ if (row == num_y - 1 || grid[row + 1 ][col]) {
601+ surroundings++;
657602 }
658- } // end top
659- // check right third
660- for (int i = x_end; i < num_x; i++) {
661- bool flag = true ;
662- for (int j = y_start; j < y_end; j++) {
663- if (grids[j][i] != -1 ) {
664- flag = false ; // we cannot extend the current cluster
665- break ;
666- } // end if
667- } // end y
668- if (!flag) { // extension done
669- break ;
603+ if (col == 0 || grid[row][col - 1 ]) {
604+ surroundings++;
670605 }
671- x_end_new++; // extend right
672- for (int j = y_start; j < y_end; j++) {
673- grids[j][i] = macro_id;
674- }
675- } // end right
676- // check down second
677- for (int j = y_start - 1 ; j >= 0 ; j--) {
678- bool flag = true ;
679- for (int i = x_start; i < x_end; i++) {
680- if (grids[j][i] != -1 ) {
681- flag = false ; // we cannot extend the current cluster
682- break ;
683- } // end if
684- } // end y
685- if (!flag) { // extension done
686- break ;
606+ if (col == num_x - 1 || grid[row][col + 1 ]) {
607+ surroundings++;
687608 }
688- y_start_new--; // extend down
689- for (int i = x_start; i < x_end; i++) {
690- grids[j][i] = macro_id;
609+
610+ if (surroundings >= 3 ) {
611+ width = x_coords[col + 1 ] - x_coords[col];
612+ height = y_coords[row + 1 ] - y_coords[row];
613+
614+ if (width <= notch_h_th_ || height <= notch_v_th_) {
615+ notch_penalty_ += calSingleNotchPenalty (width, height);
616+ }
691617 }
692- } // end down
693- // check the notch area
694- if ((x_grid[x_start] - x_grid[x_start_new]) <= notch_h_th_) {
695- notch_penalty_ += (x_grid[x_start] - x_grid[x_start_new])
696- * macros_[macro_id].getHeight ();
697- }
698- if ((x_grid[x_end_new] - x_grid[x_end]) <= notch_h_th_) {
699- notch_penalty_ += (x_grid[x_end_new] - x_grid[x_end])
700- * macros_[macro_id].getHeight ();
701- }
702- if ((y_grid[y_start] - y_grid[y_start_new]) <= notch_v_th_) {
703- notch_penalty_ += (y_grid[y_start] - y_grid[y_start_new])
704- * macros_[macro_id].getWidth ();
705- }
706- if ((y_grid[y_end_new] - y_grid[y_end]) <= notch_v_th_) {
707- notch_penalty_
708- += (y_grid[y_end_new] - y_grid[y_end]) * macros_[macro_id].getWidth ();
709618 }
710619 }
711- macros_ = pre_macros;
712- // normalization
713- notch_penalty_
714- = notch_penalty_ / (outline_.getWidth () * outline_.getHeight ());
620+
715621 if (graphics_) {
716622 graphics_->setNotchPenalty (
717623 {" Notch" , notch_weight_, notch_penalty_, norm_notch_penalty_});
@@ -866,20 +772,14 @@ void SACoreSoftMacro::fillDeadSpace()
866772 if (macros_[macro_id].getArea () <= 0.0 ) {
867773 continue ;
868774 }
869- int x_start = 0 ;
870- int x_end = 0 ;
871- calSegmentLoc (macros_[macro_id].getX (),
872- macros_[macro_id].getX () + macros_[macro_id].getWidth (),
873- x_start,
874- x_end,
875- x_grid);
876- int y_start = 0 ;
877- int y_end = 0 ;
878- calSegmentLoc (macros_[macro_id].getY (),
879- macros_[macro_id].getY () + macros_[macro_id].getHeight (),
880- y_start,
881- y_end,
882- y_grid);
775+
776+ int x_start = getSegmentIndex (macros_[macro_id].getX (), x_grid);
777+ int x_end = getSegmentIndex (
778+ macros_[macro_id].getX () + macros_[macro_id].getWidth (), x_grid);
779+ int y_start = getSegmentIndex (macros_[macro_id].getY (), y_grid);
780+ int y_end = getSegmentIndex (
781+ macros_[macro_id].getY () + macros_[macro_id].getHeight (), y_grid);
782+
883783 for (int j = y_start; j < y_end; j++) {
884784 for (int i = x_start; i < x_end; i++) {
885785 grids[j][i] = macro_id;
@@ -898,20 +798,14 @@ void SACoreSoftMacro::fillDeadSpace()
898798 if (!forward_flag) {
899799 continue ;
900800 }
901- int x_start = 0 ;
902- int x_end = 0 ;
903- calSegmentLoc (macros_[macro_id].getX (),
904- macros_[macro_id].getX () + macros_[macro_id].getWidth (),
905- x_start,
906- x_end,
907- x_grid);
908- int y_start = 0 ;
909- int y_end = 0 ;
910- calSegmentLoc (macros_[macro_id].getY (),
911- macros_[macro_id].getY () + macros_[macro_id].getHeight (),
912- y_start,
913- y_end,
914- y_grid);
801+
802+ int x_start = getSegmentIndex (macros_[macro_id].getX (), x_grid);
803+ int x_end = getSegmentIndex (
804+ macros_[macro_id].getX () + macros_[macro_id].getWidth (), x_grid);
805+ int y_start = getSegmentIndex (macros_[macro_id].getY (), y_grid);
806+ int y_end = getSegmentIndex (
807+ macros_[macro_id].getY () + macros_[macro_id].getHeight (), y_grid);
808+
915809 int x_start_new = x_start;
916810 int x_end_new = x_end;
917811 int y_start_new = y_start;
@@ -996,27 +890,12 @@ void SACoreSoftMacro::fillDeadSpace()
996890 }
997891}
998892
999- // A utility function for FillDeadSpace.
1000- // It's used for calculate the start point and end point for a segment in a grid
1001- void SACoreSoftMacro::calSegmentLoc (float seg_start,
1002- float seg_end,
1003- int & start_id,
1004- int & end_id,
1005- std::vector<float >& grid)
893+ int SACoreSoftMacro::getSegmentIndex (float segment,
894+ const std::vector<float >& coords)
1006895{
1007- start_id = -1 ;
1008- end_id = -1 ;
1009- for (int i = 0 ; i < grid.size () - 1 ; i++) {
1010- if ((grid[i] <= seg_start) && (grid[i + 1 ] > seg_start)) {
1011- start_id = i;
1012- }
1013- if ((grid[i] <= seg_end) && (grid[i + 1 ] > seg_end)) {
1014- end_id = i;
1015- }
1016- }
1017- if (end_id == -1 ) {
1018- end_id = grid.size () - 1 ;
1019- }
896+ int index = std::distance (
897+ coords.begin (), std::lower_bound (coords.begin (), coords.end (), segment));
898+ return index;
1020899}
1021900
1022901// The blockages here are only those that overlap with the annealing outline.
0 commit comments