@@ -135,6 +135,11 @@ void RepairDesign::computeSlewRCFactor()
135135 slew_rc_factor_ = factor * (1 + pessimism);
136136}
137137
138+ bool RepairDesign::rerouteEnabled () const
139+ {
140+ return reroute_;
141+ }
142+
138143// Repair long wires, max slew, max capacitance, max fanout violations
139144// The whole enchilada.
140145// max_wire_length zero for none (meters)
@@ -301,6 +306,7 @@ void RepairDesign::repairDesign(
301306 repaired_net_count = 0 ;
302307 inserted_buffer_count_ = 0 ;
303308 resize_count_ = 0 ;
309+ rerouted_nets_ = 0 ;
304310 resizer_->resized_multi_output_insts_ .clear ();
305311
306312 sta_->checkSlewsPreamble ();
@@ -1100,21 +1106,44 @@ void RepairDesign::repairNet(sta::Net* net,
11001106 delayAsString (max_slew1, 3 , this ));
11011107
11021108 slew_violation = true ;
1103- if (repairDriverSlew (corner1, drvr_pin)) {
1104- resize_count_++;
1109+
1110+ // Try rerouting to a lower-resistance layer first. If the reroute
1111+ // reduces wire resistance enough, it may fix the slew violation
1112+ // without requiring driver resizing or buffer insertion.
1113+ if (rerouteEnabled () && resizer_->tryRerouteNet (drvr_pin)) {
1114+ rerouted_nets_++;
11051115 estimate_parasitics_->updateParasitics ();
11061116 sta_->findDelays (drvr);
11071117 checkSlew (drvr_pin, slew1, max_slew1, slew_slack1, corner1);
1118+ debugPrint (logger_,
1119+ RSZ ,
1120+ " repair_net" ,
1121+ 2 ,
1122+ " after reroute: drvr slew pin={} slew={} max_slew={}" ,
1123+ network_->name (drvr_pin),
1124+ delayAsString (slew1, 3 , this ),
1125+ delayAsString (max_slew1, 3 , this ));
11081126 }
11091127
1110- // sta::Slew violation persists after resizing the driver, derive
1111- // the max cap we need to apply to remove the slew violation
1128+ // If slew violation persists after reroute, fall back to driver
1129+ // resizing and, if still needed, buffer insertion.
11121130 if (slew_slack1 < 0 .0f ) {
1113- sta::LibertyPort* drvr_port = network_->libertyPort (drvr_pin);
1114- if (drvr_port) {
1115- max_cap = findSlewLoadCap (drvr_port, max_slew1, corner1);
1116- corner = corner1;
1117- repair_cap = true ;
1131+ if (repairDriverSlew (corner1, drvr_pin)) {
1132+ resize_count_++;
1133+ estimate_parasitics_->updateParasitics ();
1134+ sta_->findDelays (drvr);
1135+ checkSlew (drvr_pin, slew1, max_slew1, slew_slack1, corner1);
1136+ }
1137+
1138+ // sta::Slew violation persists after resizing the driver, derive
1139+ // the max cap we need to apply to remove the slew violation
1140+ if (slew_slack1 < 0 .0f ) {
1141+ sta::LibertyPort* drvr_port = network_->libertyPort (drvr_pin);
1142+ if (drvr_port) {
1143+ max_cap = findSlewLoadCap (drvr_port, max_slew1, corner1);
1144+ corner = corner1;
1145+ repair_cap = true ;
1146+ }
11181147 }
11191148 }
11201149 }
@@ -1133,6 +1162,7 @@ void RepairDesign::repairNet(sta::Net* net,
11331162 network_->name (drvr_pin),
11341163 delayAsString (slew1, 3 , this ),
11351164 delayAsString (max_slew1, 3 , this ));
1165+
11361166 slew_violation = true ;
11371167 repair_load_slew = true ;
11381168 // If repair_cap is true, corner is already set to correspond
@@ -1141,8 +1171,24 @@ void RepairDesign::repairNet(sta::Net* net,
11411171 corner = corner1;
11421172 }
11431173 } else if (corner_w_load_slew_viol) {
1144- // There's a violation hidden by an annotation. Repair still
1174+ // There's a violation hidden by an annotation. The forward pass
1175+ // clamped the load pin slew to the limit, so checkLoadSlews above
1176+ // saw slack==0 and didn't fire. Try rerouting before falling back
1177+ // to buffer insertion. Even though we can't re-verify the slew here
1178+ // (the annotation is still active), an improved parasitic from
1179+ // rerouting will reduce how many buffers are needed.
11451180 slew_violation = true ;
1181+ if (rerouteEnabled () && resizer_->tryRerouteNet (drvr_pin)) {
1182+ rerouted_nets_++;
1183+ estimate_parasitics_->updateParasitics ();
1184+ sta_->findDelays (drvr);
1185+ debugPrint (logger_,
1186+ RSZ ,
1187+ " repair_net" ,
1188+ 2 ,
1189+ " rerouted annotated-slew net {}" ,
1190+ network_->name (drvr_pin));
1191+ }
11461192 repair_load_slew = true ;
11471193 if (!repair_cap) {
11481194 corner = corner_w_load_slew_viol;
@@ -2407,6 +2453,9 @@ void RepairDesign::reportViolationCounters(bool invalidate_driver_vertices,
24072453 if (resize_count_ > 0 ) {
24082454 logger_->info (utl::RSZ , 39 , " Resized {} instances." , resize_count_);
24092455 }
2456+ if (rerouted_nets_ > 0 ) {
2457+ logger_->info (utl::RSZ , 44 , " Rerouted {} nets." , rerouted_nets_);
2458+ }
24102459 if (inserted_buffer_count_ > 0 ) {
24112460 logger_->info (utl::RSZ ,
24122461 invalidate_driver_vertices ? 55 : 38 ,
0 commit comments