@@ -371,18 +371,19 @@ void FastRouteCore::fixEdgeAssignment(int& net_layer,
371371 const int l,
372372 const bool vertical,
373373 int & best_cost,
374- multi_array<int , 2 >& layer_grid)
374+ multi_array<int , 2 >& layer_grid,
375+ const int net_cost)
375376{
376377 const bool is_vertical
377378 = layer_directions_[l] == odb::dbTechLayerDir::VERTICAL;
378379 // if layer direction doesn't match edge direction or
379380 // if already found a layer for the edge, ignores the remaining layers
380- if (is_vertical != vertical || best_cost > 0 ) {
381+ if (is_vertical != vertical || best_cost >= net_cost ) {
381382 layer_grid[l][k] = std::numeric_limits<int >::min ();
382383 } else {
383384 layer_grid[l][k] = edges_3D[l][y][x].cap - edges_3D[l][y][x].usage ;
384385 best_cost = std::max (best_cost, layer_grid[l][k]);
385- if (best_cost > 0 ) {
386+ if (best_cost >= net_cost ) {
386387 // set the new min/max routing layer for the net to avoid
387388 // errors during mazeRouteMSMDOrder3D
388389 net_layer = l;
@@ -458,6 +459,7 @@ void FastRouteCore::assignEdge(const int netID,
458459 int endLayer = 0 ;
459460
460461 FrNet* net = nets_[netID];
462+ const int8_t net_cost = net->getEdgeCost ();
461463 auto & treeedges = sttrees_[netID].edges ;
462464 auto & treenodes = sttrees_[netID].nodes ;
463465 TreeEdge* treeedge = &(treeedges[edgeID]);
@@ -488,25 +490,31 @@ void FastRouteCore::assignEdge(const int netID,
488490
489491 for (k = 0 ; k < routelen; k++) {
490492 int best_cost = std::numeric_limits<int >::min ();
493+ bool has_available_resources = false ;
491494 if (grids[k].x == grids[k + 1 ].x ) {
492495 const int min_y = std::min (grids[k].y , grids[k + 1 ].y );
493496 for (int l = net->getMinLayer (); l <= net->getMaxLayer (); l++) {
494497 // check if the current layer is vertical to match the edge orientation
495498 bool is_vertical
496499 = layer_directions_[l] == odb::dbTechLayerDir::VERTICAL;
497500 if (is_vertical) {
498- layer_grid[l][k] = v_edges_3D_[l][min_y][grids[k].x ].cap
499- - v_edges_3D_[l][min_y][grids[k].x ].usage ;
501+ const int available_resources
502+ = v_edges_3D_[l][min_y][grids[k].x ].cap
503+ - v_edges_3D_[l][min_y][grids[k].x ].usage ;
504+ layer_grid[l][k] = available_resources;
500505 best_cost = std::max (best_cost, layer_grid[l][k]);
506+ // Check if any layer has enough resources to route
507+ has_available_resources
508+ |= (available_resources >= net->getLayerEdgeCost (l));
501509 } else {
502510 layer_grid[l][k] = std::numeric_limits<int >::min ();
503511 }
504512 }
505513
506- // assigning the edge to the layer range would cause overflow try to
514+ // if no layer has sufficient resources in the range of layers try to
507515 // assign the edge to the closest layer below the min routing layer.
508516 // if design has 2D overflow, accept the congestion in layer assignment
509- if (best_cost <= 0 && !has_2D_overflow_) {
517+ if (!has_available_resources && !has_2D_overflow_) {
510518 int min_layer = net->getMinLayer ();
511519 for (int l = net->getMinLayer () - 1 ; l >= 0 ; l--) {
512520 fixEdgeAssignment (min_layer,
@@ -517,7 +525,8 @@ void FastRouteCore::assignEdge(const int netID,
517525 l,
518526 true ,
519527 best_cost,
520- layer_grid);
528+ layer_grid,
529+ net_cost);
521530 }
522531 net->setMinLayer (min_layer);
523532 // try to assign the edge to the closest layer above the max routing
@@ -532,7 +541,8 @@ void FastRouteCore::assignEdge(const int netID,
532541 l,
533542 true ,
534543 best_cost,
535- layer_grid);
544+ layer_grid,
545+ net_cost);
536546 }
537547 net->setMaxLayer (max_layer);
538548 } else { // the edge was assigned to a layer without causing overflow
@@ -550,18 +560,23 @@ void FastRouteCore::assignEdge(const int netID,
550560 bool is_horizontal
551561 = layer_directions_[l] == odb::dbTechLayerDir::HORIZONTAL;
552562 if (is_horizontal) {
553- layer_grid[l][k] = h_edges_3D_[l][grids[k].y ][min_x].cap
554- - h_edges_3D_[l][grids[k].y ][min_x].usage ;
563+ const int available_resources
564+ = h_edges_3D_[l][grids[k].y ][min_x].cap
565+ - h_edges_3D_[l][grids[k].y ][min_x].usage ;
566+ layer_grid[l][k] = available_resources;
555567 best_cost = std::max (best_cost, layer_grid[l][k]);
568+ // Check if any layer has enough resources to route
569+ has_available_resources
570+ |= (available_resources >= net->getLayerEdgeCost (l));
556571 } else {
557572 layer_grid[l][k] = std::numeric_limits<int >::min ();
558573 }
559574 }
560575
561- // assigning the edge to the layer range would cause overflow try to
576+ // if no layer has sufficient resources in the range of layers try to
562577 // assign the edge to the closest layer below the min routing layer.
563578 // if design has 2D overflow, accept the congestion in layer assignment
564- if (best_cost <= 0 && !has_2D_overflow_) {
579+ if (!has_available_resources && !has_2D_overflow_) {
565580 int min_layer = net->getMinLayer ();
566581 for (int l = net->getMinLayer () - 1 ; l >= 0 ; l--) {
567582 fixEdgeAssignment (min_layer,
@@ -572,7 +587,8 @@ void FastRouteCore::assignEdge(const int netID,
572587 l,
573588 false ,
574589 best_cost,
575- layer_grid);
590+ layer_grid,
591+ net_cost);
576592 }
577593 net->setMinLayer (min_layer);
578594 // try to assign the edge to the closest layer above the max routing
@@ -587,7 +603,8 @@ void FastRouteCore::assignEdge(const int netID,
587603 l,
588604 false ,
589605 best_cost,
590- layer_grid);
606+ layer_grid,
607+ net_cost);
591608 }
592609 net->setMaxLayer (max_layer);
593610 } else { // the edge was assigned to a layer without causing overflow
@@ -1069,7 +1086,6 @@ void FastRouteCore::layerAssignment()
10691086 }
10701087
10711088 layerAssignmentV4 ();
1072-
10731089 ConvertToFull3DType2 ();
10741090}
10751091
0 commit comments