Skip to content

Commit c064501

Browse files
authored
Merge pull request #8895 from The-OpenROAD-Project-staging/grt-resistance-aware-update
grt: resistance aware enhancements
2 parents e074baa + ce78f48 commit c064501

File tree

9 files changed

+220
-25
lines changed

9 files changed

+220
-25
lines changed

src/est/src/EstimateParasitics.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -526,7 +526,13 @@ void EstimateParasitics::estimateGlobalRouteParasitics(odb::dbNet* net,
526526
initBlock();
527527
MakeWireParasitics builder(
528528
logger_, this, sta_, db_->getTech(), block_, global_router_);
529-
builder.estimateParasitics(net, route);
529+
530+
// Check if we are estimating parasitics after layer assignment
531+
if (route.at(0).is3DRoute()) {
532+
builder.estimateParasitics(net, route, nullptr);
533+
} else {
534+
builder.estimateParasitics(net, route);
535+
}
530536
}
531537

532538
void EstimateParasitics::clearParasitics()

src/grt/include/grt/GRoute.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,13 @@ struct GSegment
2626
int final_y;
2727
int final_layer;
2828
bool is_jumper;
29+
bool is_3d_route = false;
2930
GSegment() = default;
3031
GSegment(int x0, int y0, int l0, int x1, int y1, int l1, bool jumper = false);
3132
bool isVia() const { return (init_x == final_x && init_y == final_y); }
3233
bool isJumper() const { return is_jumper; }
34+
bool is3DRoute() const { return is_3d_route; }
35+
void setIs3DRoute(bool is_3d) { is_3d_route = is_3d; }
3336
int length() const
3437
{
3538
return std::abs(init_x - final_x) + std::abs(init_y - final_y);

src/grt/include/grt/GlobalRouter.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -486,7 +486,7 @@ class GlobalRouter
486486
std::vector<RoutingTracks> routing_tracks_;
487487

488488
// Flow variables
489-
bool is_incremental;
489+
bool is_incremental_;
490490
float adjustment_;
491491
int layer_for_guide_dimension_;
492492
int congestion_iterations_{50};

src/grt/src/GlobalRouter.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,7 @@ NetRouteMap GlobalRouter::getPartialRoutes()
217217
{
218218
NetRouteMap net_routes;
219219
// TODO: still need to fix this during incremental grt
220-
if (is_incremental) {
220+
if (is_incremental_) {
221221
for (const auto& [db_net, net] : db_net_map_) {
222222
if (routes_[db_net].empty()) {
223223
GRoute route;
@@ -304,7 +304,7 @@ void GlobalRouter::globalRoute(bool save_guides,
304304
bool end_incremental)
305305
{
306306
bool has_routable_nets = false;
307-
is_incremental = (start_incremental || end_incremental);
307+
is_incremental_ = (start_incremental || end_incremental);
308308

309309
for (auto net : db_->getChip()->getBlock()->getNets()) {
310310
if (net->getITerms().size() + net->getBTerms().size() > 1) {

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,7 @@ struct OrderNetPin
246246
int ndr_priority; // NDR nets are assigned first
247247
int res_aware;
248248
float slack;
249+
int clock;
249250
};
250251

251252
struct OrderTree

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,7 @@ class FastRouteCore
271271

272272
NetRouteMap getPlanarRoutes();
273273
void getPlanarRoute(odb::dbNet* db_net, GRoute& route);
274+
void get3DRoute(odb::dbNet* db_net, GRoute& route);
274275

275276
private:
276277
int getEdgeCapacity(FrNet* net, int x1, int y1, EdgeDirection direction);
@@ -280,7 +281,7 @@ class FastRouteCore
280281
double dbuToMicrons(int dbu);
281282
odb::Rect globalRoutingToBox(const GSegment& route);
282283
NetRouteMap getRoutes();
283-
void updateSlacks(float percentage = 0.7);
284+
void updateSlacks(float percentage = 1);
284285
void preProcessTechLayers();
285286
odb::dbTechLayer* getTechLayer(int layer, bool is_via);
286287

@@ -609,9 +610,10 @@ class FastRouteCore
609610
int x_range_;
610611
int y_range_;
611612

612-
bool estimate_parasitics_ = false;
613+
bool en_estimate_parasitics_ = false;
613614
bool resistance_aware_ = false;
614615
bool enable_resistance_aware_ = false;
616+
bool is_3d_step_ = false;
615617
int num_adjust_;
616618
int v_capacity_;
617619
int h_capacity_;

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

Lines changed: 151 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1011,16 +1011,155 @@ void FastRouteCore::getPlanarRoute(odb::dbNet* db_net, GRoute& route)
10111011
}
10121012
}
10131013

1014+
void FastRouteCore::get3DRoute(odb::dbNet* db_net, GRoute& route)
1015+
{
1016+
int netID;
1017+
bool exists;
1018+
getNetId(db_net, netID, exists);
1019+
1020+
std::unordered_set<GSegment, GSegmentHash> net_segs;
1021+
1022+
const auto& treeedges = sttrees_[netID].edges;
1023+
const int num_edges = sttrees_[netID].num_edges();
1024+
1025+
for (int edgeID = 0; edgeID < num_edges; edgeID++) {
1026+
const TreeEdge* treeedge = &(treeedges[edgeID]);
1027+
if (treeedge->len > 0) {
1028+
int routeLen = treeedge->route.routelen;
1029+
const std::vector<GPoint3D>& grids = treeedge->route.grids;
1030+
const int num_terminals = sttrees_[netID].num_terminals;
1031+
const auto& treenodes = sttrees_[netID].nodes;
1032+
int node1_alias = treeedge->n1a;
1033+
int node2_alias = treeedge->n2a;
1034+
1035+
std::vector<GPoint3D> filled_grids;
1036+
1037+
// Handle vias for node1_alias (start node)
1038+
if (treenodes[node1_alias].hID == edgeID
1039+
|| (edgeID == treenodes[node1_alias].lID
1040+
&& treenodes[node1_alias].hID == BIG_INT
1041+
&& node1_alias < num_terminals)) {
1042+
int16_t bottom_layer = treenodes[node1_alias].botL;
1043+
int16_t top_layer = treenodes[node1_alias].topL;
1044+
int16_t edge_init_layer = grids[0].layer;
1045+
1046+
if (node1_alias < num_terminals) {
1047+
int16_t pin_botL, pin_topL;
1048+
getViaStackRange(netID, node1_alias, pin_botL, pin_topL);
1049+
bottom_layer = std::min(pin_botL, bottom_layer);
1050+
top_layer = std::max(pin_topL, top_layer);
1051+
1052+
for (int16_t l = bottom_layer; l < top_layer; l++) {
1053+
filled_grids.push_back({grids[0].x, grids[0].y, l});
1054+
}
1055+
1056+
for (int16_t l = top_layer; l > edge_init_layer; l--) {
1057+
filled_grids.push_back({grids[0].x, grids[0].y, l});
1058+
}
1059+
} else {
1060+
for (int16_t l = bottom_layer; l < edge_init_layer; l++) {
1061+
filled_grids.push_back({grids[0].x, grids[0].y, l});
1062+
}
1063+
}
1064+
}
1065+
1066+
for (int j = 0; j <= routeLen; j++) {
1067+
filled_grids.emplace_back(grids[j]);
1068+
}
1069+
1070+
// Handle vias for node2_alias (end node)
1071+
if (treenodes[node2_alias].hID == edgeID
1072+
|| (edgeID == treenodes[node2_alias].lID
1073+
&& treenodes[node2_alias].hID == BIG_INT
1074+
&& node2_alias < num_terminals)) {
1075+
int16_t bottom_layer = treenodes[node2_alias].botL;
1076+
int16_t top_layer = treenodes[node2_alias].topL;
1077+
if (node2_alias < num_terminals) {
1078+
int16_t pin_botL, pin_topL;
1079+
getViaStackRange(netID, node2_alias, pin_botL, pin_topL);
1080+
bottom_layer = std::min(pin_botL, bottom_layer);
1081+
top_layer = std::max(pin_topL, top_layer);
1082+
1083+
// Adjust bottom_layer if it's the same as the last filled grid layer
1084+
if (bottom_layer == filled_grids.back().layer) {
1085+
bottom_layer++;
1086+
}
1087+
1088+
// Ensure the loop for descending vias is correct
1089+
for (int16_t l = filled_grids.back().layer - 1; l > bottom_layer;
1090+
l--) {
1091+
filled_grids.push_back(
1092+
{filled_grids.back().x, filled_grids.back().y, l});
1093+
}
1094+
1095+
for (int16_t l = bottom_layer; l <= top_layer; l++) {
1096+
filled_grids.push_back(
1097+
{filled_grids.back().x, filled_grids.back().y, l});
1098+
}
1099+
} else {
1100+
for (int16_t l = top_layer - 1; l >= bottom_layer; l--) {
1101+
filled_grids.push_back(
1102+
{filled_grids.back().x, filled_grids.back().y, l});
1103+
}
1104+
}
1105+
}
1106+
1107+
int lastX = (tile_size_ * (filled_grids[0].x + 0.5)) + x_corner_;
1108+
int lastY = (tile_size_ * (filled_grids[0].y + 0.5)) + y_corner_;
1109+
int lastL = filled_grids[0].layer;
1110+
1111+
for (int i = 1; i < filled_grids.size(); i++) {
1112+
const int xreal = (tile_size_ * (filled_grids[i].x + 0.5)) + x_corner_;
1113+
const int yreal = (tile_size_ * (filled_grids[i].y + 0.5)) + y_corner_;
1114+
const int currentL = filled_grids[i].layer;
1115+
1116+
// Prevent adding segments that are effectively zero-length vias on the
1117+
// same layer
1118+
if (lastX == xreal && lastY == yreal && lastL == currentL) {
1119+
// Skip this segment as it's a redundant via on the same layer
1120+
lastX = xreal;
1121+
lastY = yreal;
1122+
lastL = currentL;
1123+
continue;
1124+
}
1125+
1126+
GSegment segment
1127+
= GSegment(lastX, lastY, lastL + 1, xreal, yreal, currentL + 1);
1128+
segment.setIs3DRoute(true);
1129+
1130+
// Only add segment if it's not a duplicate
1131+
if (net_segs.find(segment) == net_segs.end()) {
1132+
net_segs.insert(segment);
1133+
route.push_back(segment);
1134+
}
1135+
1136+
lastX = xreal;
1137+
lastY = yreal;
1138+
lastL = currentL;
1139+
}
1140+
}
1141+
}
1142+
}
1143+
10141144
NetRouteMap FastRouteCore::getPlanarRoutes()
10151145
{
10161146
NetRouteMap routes;
10171147

10181148
// Get routes before layer assignment
1019-
for (const int& netID : net_ids_) {
1020-
auto fr_net = nets_[netID];
1021-
odb::dbNet* db_net = fr_net->getDbNet();
1022-
GRoute& route = routes[db_net];
1023-
getPlanarRoute(db_net, route);
1149+
if (!is_3d_step_) {
1150+
for (const int& netID : net_ids_) {
1151+
auto fr_net = nets_[netID];
1152+
odb::dbNet* db_net = fr_net->getDbNet();
1153+
GRoute& route = routes[db_net];
1154+
getPlanarRoute(db_net, route);
1155+
}
1156+
} else {
1157+
for (const int& netID : net_ids_) {
1158+
auto fr_net = nets_[netID];
1159+
odb::dbNet* db_net = fr_net->getDbNet();
1160+
GRoute& route = routes[db_net];
1161+
get3DRoute(db_net, route);
1162+
}
10241163
}
10251164

10261165
return routes;
@@ -1643,13 +1782,18 @@ NetRouteMap FastRouteCore::run()
16431782
via_cost_ = 1;
16441783

16451784
if (past_cong == 0) {
1785+
// Increase ripup threshold if res-aware is enabled
1786+
if (enable_resistance_aware_) {
1787+
long_edge_len = BIG_INT;
1788+
}
1789+
16461790
mazeRouteMSMDOrder3D(enlarge_, 0, long_edge_len);
16471791
mazeRouteMSMDOrder3D(enlarge_, 0, short_edge_len);
16481792
}
16491793

16501794
// Disable estimate parasitics for grt incremental steps with resistance-aware
16511795
// strategy to prevent issues during repair design and repair timing
1652-
estimate_parasitics_ = false;
1796+
en_estimate_parasitics_ = false;
16531797

16541798
if (logger_->debugCheck(GRT, "grtSteps", 1)) {
16551799
getOverflow3D();
@@ -1819,7 +1963,7 @@ void FastRouteCore::setCongestionReportIterStep(int congestion_report_iter_step)
18191963
void FastRouteCore::setResistanceAware(bool resistance_aware)
18201964
{
18211965
enable_resistance_aware_ = resistance_aware;
1822-
estimate_parasitics_ = true;
1966+
en_estimate_parasitics_ = true;
18231967
}
18241968

18251969
void FastRouteCore::setCongestionReportFile(const char* congestion_file_name)

src/grt/src/fastroute/src/maze3D.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -695,6 +695,11 @@ void FastRouteCore::mazeRouteMSMDOrder3D(int expand,
695695
}
696696
}
697697

698+
if (enable_resistance_aware_) {
699+
updateSlacks(.8);
700+
netpinOrderInc();
701+
}
702+
698703
const int endIND = tree_order_pv_.size() * 0.9;
699704

700705
for (int orderIndex = 0; orderIndex < endIND; orderIndex++) {
@@ -720,6 +725,16 @@ void FastRouteCore::mazeRouteMSMDOrder3D(int expand,
720725
if (treeedge->len >= ripupTHub || treeedge->len <= ripupTHlb) {
721726
continue;
722727
}
728+
729+
// Force resistance-aware if edge length > 100
730+
if (enable_resistance_aware_) {
731+
if (treeedge->len > 100) {
732+
resistance_aware_ = true;
733+
} else {
734+
resistance_aware_ = net->isResAware();
735+
}
736+
}
737+
723738
int n1 = treeedge->n1;
724739
int n2 = treeedge->n2;
725740
const int n1x = treenodes[n1].x;

0 commit comments

Comments
 (0)