Skip to content

Commit 7648711

Browse files
authored
Merge pull request #8282 from The-OpenROAD-Project-staging/grt-soft-ndr-nets
grt: soft NDR initial implementation
2 parents 2ef7fd0 + b945334 commit 7648711

File tree

9 files changed

+635
-22
lines changed

9 files changed

+635
-22
lines changed

src/grt/src/fastroute/include/DataType.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ struct FrNet // A Net is a set of connected MazePoints
8080
odb::dbNet* getDbNet() const { return db_net_; }
8181
int getDriverIdx() const { return driver_idx_; }
8282
int8_t getEdgeCost() const { return edge_cost_; }
83+
void setEdgeCost(int cost) { edge_cost_ = cost; }
8384
const char* getName() const;
8485
int getMaxLayer() const { return max_layer_; }
8586
int getMinLayer() const { return min_layer_; }
@@ -106,6 +107,8 @@ struct FrNet // A Net is a set of connected MazePoints
106107
void setMinLayer(int min_layer) { min_layer_ = min_layer; }
107108
void setSlack(float slack) { slack_ = slack; }
108109
void setIsCritical(bool is_critical) { is_critical_ = is_critical; }
110+
void setIsSoftNDR(bool is_soft) { is_soft_ndr_ = is_soft; }
111+
bool isSoftNDR() { return is_soft_ndr_; }
109112

110113
private:
111114
odb::dbNet* db_net_;
@@ -119,6 +122,7 @@ struct FrNet // A Net is a set of connected MazePoints
119122
int min_layer_;
120123
int max_layer_;
121124
float slack_;
125+
bool is_soft_ndr_ = false;
122126
// Non-null when an NDR has been applied to the net.
123127
std::unique_ptr<std::vector<int8_t>> edge_cost_per_layer_;
124128
};

src/grt/src/fastroute/include/FastRoute.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,10 @@ class FastRouteCore
250250
const odb::dbNet* getDebugNet();
251251
bool hasSaveSttInput();
252252
void clearNDRnets();
253+
void computeCongestedNDRnets();
254+
void updateSoftNDRNetUsage(int net_id, int edge_cost);
255+
void setSoftNDR(int net_id);
256+
void applySoftNDR(const std::vector<int>& net_ids);
253257

254258
int x_corner() const { return x_corner_; }
255259
int y_corner() const { return y_corner_; }

src/grt/src/fastroute/include/Graph2D.h

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
#include <set>
99
#include <string>
1010
#include <utility>
11-
#include <vector>
1211

1312
#include "DataType.h"
1413
#include "boost/multi_array.hpp"
@@ -33,6 +32,25 @@ class Graph2D
3332
double cap_ndr; // capacity available for NDR
3433
};
3534

35+
struct NDRCongestion
36+
{
37+
int net_id; // NDR net id
38+
uint16_t num_edges; // number of congested edges
39+
40+
NDRCongestion(int net_id, uint16_t num_edges)
41+
: net_id(net_id), num_edges(num_edges)
42+
{
43+
}
44+
};
45+
46+
struct NDRCongestionComparator
47+
{
48+
bool operator()(const NDRCongestion& a, const NDRCongestion& b) const
49+
{
50+
return a.num_edges > b.num_edges;
51+
}
52+
};
53+
3654
void init(int x_grid,
3755
int y_grid,
3856
int h_capacity,
@@ -100,6 +118,12 @@ class Graph2D
100118
double cap);
101119

102120
void clearNDRnets();
121+
std::vector<NDRCongestion> getCongestedNDRnets() { return congested_ndrs_; };
122+
void clearCongestedNDRnets() { congested_ndrs_.clear(); };
123+
void addCongestedNDRnet(int net_id, uint16_t num_edges);
124+
void sortCongestedNDRnets();
125+
int getOneCongestedNDRnet();
126+
std::vector<int> getMultipleCongestedNDRnet();
103127

104128
private:
105129
int x_grid_;
@@ -130,10 +154,11 @@ class Graph2D
130154
multi_array<Edge, 2> h_edges_; // The way it is indexed is (X, Y)
131155
multi_array<Cap3D, 3> v_cap_3D_; // The way it is indexed is (Layer, X, Y)
132156
multi_array<Cap3D, 3> h_cap_3D_; // The way it is indexed is (Layer, X, Y)
133-
multi_array<std::set<std::string>, 2>
157+
multi_array<std::set<FrNet*>, 2>
134158
v_ndr_nets_; // The way it is indexed is (X, Y)
135-
multi_array<std::set<std::string>, 2>
159+
multi_array<std::set<FrNet*>, 2>
136160
h_ndr_nets_; // The way it is indexed is (X, Y)
161+
std::vector<NDRCongestion> congested_ndrs_;
137162

138163
utl::Logger* logger_;
139164

src/grt/src/fastroute/src/FastRoute.cpp

Lines changed: 161 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
16331785
void FastRouteCore::setVerbose(bool v)
16341786
{
16351787
verbose_ = v;
@@ -1820,7 +1972,7 @@ void FastRouteCore::StTreeVisualization(const StTree& stree,
18201972

18211973
int8_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

Comments
 (0)