@@ -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+
10141144NetRouteMap 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)
18191963void FastRouteCore::setResistanceAware (bool resistance_aware)
18201964{
18211965 enable_resistance_aware_ = resistance_aware;
1822- estimate_parasitics_ = true ;
1966+ en_estimate_parasitics_ = true ;
18231967}
18241968
18251969void FastRouteCore::setCongestionReportFile (const char * congestion_file_name)
0 commit comments