@@ -1194,8 +1194,9 @@ NetRouteMap FastRouteCore::run()
11941194 float logistic_coef = 0 ;
11951195 int slope;
11961196 int max_adj;
1197- const int long_edge_len = 40 ;
1197+ int long_edge_len = 40 ;
11981198 const int short_edge_len = 12 ;
1199+ const int soft_ndr_overflow_th = 10000 ;
11991200
12001201 // call FLUTE to generate RSMT and break the nets into segments (2-pin nets)
12011202 via_cost_ = 0 ;
@@ -1348,9 +1349,6 @@ NetRouteMap FastRouteCore::run()
13481349 if (i % 2 == 0 ) {
13491350 logistic_coef += 0.5 ;
13501351 }
1351- if (i > 40 ) {
1352- break ;
1353- }
13541352 }
13551353 if (i > 10 ) {
13561354 ripup_threshold = 0 ;
@@ -1505,10 +1503,6 @@ NetRouteMap FastRouteCore::run()
15051503 if (bmfl < 30 && bwcnt > 50 ) {
15061504 break ;
15071505 }
1508- if (i >= mazeRound) {
1509- getOverflow2Dmaze (&maxOverflow, &tUsage);
1510- break ;
1511- }
15121506 }
15131507
15141508 if (i >= mazeRound) {
@@ -1538,6 +1532,51 @@ NetRouteMap FastRouteCore::run()
15381532 max_overflow_increases);
15391533 }
15401534
1535+ // Try disabling NDR nets to fix congestion
1536+ if (total_overflow_ > 0
1537+ && (i == overflow_iterations_
1538+ || overflow_increases == max_overflow_increases)) {
1539+ // Compute all the NDR nets involved in congestion
1540+ computeCongestedNDRnets ();
1541+
1542+ std::vector<int > net_ids;
1543+
1544+ // If the congestion is not that high (note that the overflow is inflated
1545+ // by 100x when there is no capacity available for a NDR net in a specific
1546+ // edge)
1547+ if (total_overflow_ < soft_ndr_overflow_th) {
1548+ // Select one NDR net to be disabled
1549+ int net_id = graph2d_.getOneCongestedNDRnet ();
1550+ if (net_id != -1 ) {
1551+ net_ids.push_back (net_id);
1552+ }
1553+ } else { // Select multiple NDR nets
1554+ net_ids = graph2d_.getMultipleCongestedNDRnet ();
1555+ }
1556+
1557+ // Only apply soft NDR if there is NDR nets involved in congestion
1558+ if (!net_ids.empty ()) {
1559+ // Apply the soft NDR to the selected list of nets
1560+ applySoftNDR (net_ids);
1561+
1562+ // Reset loop parameters
1563+ overflow_increases = 0 ;
1564+ i = 1 ;
1565+ costheight_ = COSHEIGHT;
1566+ enlarge_ = ENLARGE;
1567+ ripup_threshold = Ripvalue;
1568+ minofl = total_overflow_;
1569+ bmfl = minofl;
1570+ stopDEC = false ;
1571+
1572+ slope = 20 ;
1573+ L = 1 ;
1574+
1575+ // Increase maze route 3D threshold to fix bad routes
1576+ long_edge_len = BIG_INT;
1577+ }
1578+ }
1579+
15411580 // generate DRC report each interval
15421581 if (congestion_report_iter_step_ && i % congestion_report_iter_step_ == 0 ) {
15431582 saveCongestion (i);
@@ -1630,6 +1669,119 @@ NetRouteMap FastRouteCore::run()
16301669 return routes;
16311670}
16321671
1672+ void FastRouteCore::applySoftNDR (const std::vector<int >& net_ids)
1673+ {
1674+ for (auto net_id : net_ids) {
1675+ logger_->warn (
1676+ GRT, 273 , " Disabled NDR for the {} net." , nets_[net_id]->getName ());
1677+
1678+ // Remove the usage of all the edges involved with this net
1679+ updateSoftNDRNetUsage (net_id, -nets_[net_id]->getEdgeCost ());
1680+
1681+ // Reset the edge cost and layer edge cost to 1
1682+ setSoftNDR (net_id);
1683+
1684+ // Update the usage of all the edges involved with this net considering
1685+ // the new edge cost
1686+ updateSoftNDRNetUsage (net_id, nets_[net_id]->getEdgeCost ());
1687+ }
1688+ }
1689+
1690+ void FastRouteCore::setSoftNDR (const int net_id)
1691+ {
1692+ nets_[net_id]->setIsSoftNDR (true );
1693+ nets_[net_id]->setEdgeCost (1 );
1694+ }
1695+
1696+ void FastRouteCore::computeCongestedNDRnets ()
1697+ {
1698+ // Clear the old list first
1699+ graph2d_.clearCongestedNDRnets ();
1700+
1701+ // Compute all NDR nets to identify those in congestion
1702+ for (auto net_id : net_ids_) {
1703+ FrNet* net = nets_[net_id];
1704+
1705+ // Ignore non-NDR and soft-NDR nets
1706+ if (net->getDbNet ()->getNonDefaultRule () == nullptr || net->isSoftNDR ()) {
1707+ continue ;
1708+ }
1709+
1710+ // Access the routing tree edges for this net
1711+ std::vector<TreeEdge>& treeedges = sttrees_[net_id].edges ;
1712+ const int num_edges = sttrees_[net_id].num_edges ();
1713+
1714+ uint16_t num_congested_edges = 0 ;
1715+
1716+ // Iterate through all edges in the net's routing tree
1717+ for (int edgeID = 0 ; edgeID < num_edges; edgeID++) {
1718+ TreeEdge* treeedge = &(treeedges[edgeID]);
1719+ // Only process edges that have actual routing
1720+ if (treeedge->len > 0 || treeedge->route .routelen > 0 ) {
1721+ int routeLen = treeedge->route .routelen ;
1722+ std::vector<GPoint3D>& grids = treeedge->route .grids ;
1723+
1724+ // Check route
1725+ for (int i = 0 ; i < routeLen; i++) {
1726+ if (grids[i].x == grids[i + 1 ].x ) { // vertical
1727+ const int min_y = std::min (grids[i].y , grids[i + 1 ].y );
1728+ // Increment congested edges if have overflow
1729+ if (graph2d_.getOverflowV (grids[i].x , min_y) > 0 ) {
1730+ num_congested_edges++;
1731+ }
1732+ } else { // horizontal
1733+ const int min_x = std::min (grids[i].x , grids[i + 1 ].x );
1734+ if (graph2d_.getOverflowH (min_x, grids[i].y ) > 0 ) {
1735+ num_congested_edges++;
1736+ }
1737+ }
1738+ }
1739+ }
1740+ }
1741+ if (num_congested_edges > 0 ) {
1742+ // Include the NDR net in the list
1743+ graph2d_.addCongestedNDRnet (net_id, num_congested_edges);
1744+ if (logger_->debugCheck (GRT, " softNDR" , 1 )) {
1745+ logger_->report (" Congested NDR net: {} Edges: {}" ,
1746+ net->getName (),
1747+ num_congested_edges);
1748+ }
1749+ }
1750+ }
1751+
1752+ // Sort the congested NDR nets according to the priorities
1753+ graph2d_.sortCongestedNDRnets ();
1754+ }
1755+
1756+ void FastRouteCore::updateSoftNDRNetUsage (const int net_id, const int edge_cost)
1757+ {
1758+ FrNet* net = nets_[net_id];
1759+ // Access the routing tree edges for this net
1760+ std::vector<TreeEdge>& treeedges = sttrees_[net_id].edges ;
1761+ const int num_edges = sttrees_[net_id].num_edges ();
1762+
1763+ // Iterate through all edges in the net's routing tree
1764+ for (int edgeID = 0 ; edgeID < num_edges; edgeID++) {
1765+ TreeEdge* treeedge = &(treeedges[edgeID]);
1766+ // Only process edges that have actual routing
1767+ if (treeedge->len > 0 || treeedge->route .routelen > 0 ) {
1768+ int routeLen = treeedge->route .routelen ;
1769+ std::vector<GPoint3D>& grids = treeedge->route .grids ;
1770+
1771+ // Update route usage
1772+ for (int i = 0 ; i < routeLen; i++) {
1773+ if (grids[i].x == grids[i + 1 ].x ) { // vertical
1774+ const int min_y = std::min (grids[i].y , grids[i + 1 ].y );
1775+ graph2d_.updateUsageV (grids[i].x , min_y, net, edge_cost);
1776+ } else { // horizontal
1777+ const int min_x = std::min (grids[i].x , grids[i + 1 ].x );
1778+ graph2d_.updateUsageH (min_x, grids[i].y , net, edge_cost);
1779+ }
1780+ }
1781+ }
1782+ }
1783+ }
1784+
16331785void FastRouteCore::setVerbose (bool v)
16341786{
16351787 verbose_ = v;
@@ -1820,7 +1972,7 @@ void FastRouteCore::StTreeVisualization(const StTree& stree,
18201972
18211973int8_t FrNet::getLayerEdgeCost (int layer) const
18221974{
1823- if (edge_cost_per_layer_) {
1975+ if (edge_cost_per_layer_ && !is_soft_ndr_ ) {
18241976 return (*edge_cost_per_layer_)[layer];
18251977 }
18261978
0 commit comments