Skip to content

Commit 169647b

Browse files
authored
Merge pull request #10759 from The-OpenROAD-Project-staging/grt_cugr_res_aware_stage
grt/cugr: implement resistance-aware stage and resistance costs during congestion handling
2 parents 43d2c5f + da1dbdc commit 169647b

44 files changed

Lines changed: 27963 additions & 4152 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

src/grt/src/GlobalRouter.cpp

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,15 @@ std::vector<Net*> GlobalRouter::initCUGR(int min_routing_layer,
208208
reportNetDegree(nets);
209209

210210
cugr_->setCongestionIterations(congestion_iterations_);
211+
if (sta_->getDbNetwork()->defaultLibertyLibrary() == nullptr) {
212+
if (cugr_->getCriticalNetsPercentage() != 0) {
213+
logger_->warn(
214+
GRT,
215+
309,
216+
"Timing is not available, setting critical nets percentage to 0.");
217+
}
218+
cugr_->setCriticalNetsPercentage(0);
219+
}
211220
cugr_->init(min_routing_layer, max_routing_layer, clock_nets);
212221
return nets;
213222
}
@@ -2519,6 +2528,7 @@ void GlobalRouter::setResistanceAware(bool resistance_aware)
25192528
{
25202529
resistance_aware_ = resistance_aware;
25212530
fastroute_->setResistanceAware(resistance_aware);
2531+
cugr_->setResistanceAware(resistance_aware);
25222532
}
25232533

25242534
void GlobalRouter::setResAwareNetsPercentage(float percentage)
@@ -2531,8 +2541,7 @@ void GlobalRouter::setResAwareNetsPercentage(float percentage)
25312541
"nets percentage to 0.");
25322542
}
25332543
if (use_cugr_) {
2534-
// TODO
2535-
// cugr_->setResAwareNetsPercentage(percentage);
2544+
cugr_->setResAwareNetsPercentage(percentage);
25362545
} else {
25372546
fastroute_->setResAwareNetsPercentage(percentage);
25382547
}
@@ -3137,7 +3146,9 @@ void GlobalRouter::saveGuides(const std::vector<odb::dbNet*>& nets)
31373146
int offset_x = grid_origin_.x();
31383147
int offset_y = grid_origin_.y();
31393148

3140-
bool guide_is_congested = is_congested_ && !allow_congestion_;
3149+
// CUGR can produce congested guides that DRT can handle, resulting in
3150+
// DRC-free final routing.
3151+
bool guide_is_congested = is_congested_ && !allow_congestion_ && !use_cugr_;
31413152

31423153
int net_with_jumpers, total_jumpers;
31433154
net_with_jumpers = 0;

src/grt/src/cugr/include/CUGR.h

Lines changed: 61 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -59,11 +59,22 @@ struct Constants
5959

6060
double maze_logistic_slope = 0.5;
6161

62+
// Min net length (routed-tree length, gcells) for res-aware; shorter nets
63+
// are skipped.
64+
int resistance_min_net_length = 3;
65+
66+
// Scales the res-aware resistance cost to CUGR's wire-cost magnitude.
67+
double resistance_weight = 50.0;
68+
6269
double pin_patch_threshold = 20.0;
6370
int pin_patch_padding = 1;
6471
double wire_patch_threshold = 2.0;
6572
double wire_patch_inflation_rate = 1.2;
6673

74+
// Cost multiplier for wires that don't fit an edge, biasing vias to climb to
75+
// a free layer; 0 disables the gate.
76+
double congestion_gate_penalty = 4.0;
77+
6778
bool write_heatmap = false;
6879
};
6980

@@ -93,6 +104,15 @@ class CUGR
93104
{
94105
critical_nets_percentage_ = percentage;
95106
}
107+
float getCriticalNetsPercentage() const { return critical_nets_percentage_; }
108+
void setResistanceAware(bool resistance_aware)
109+
{
110+
resistance_aware_ = resistance_aware;
111+
}
112+
void setResAwareNetsPercentage(float percentage)
113+
{
114+
res_aware_percentage_ = percentage;
115+
}
96116
void setCongestionIterations(int iterations)
97117
{
98118
congestion_iterations_ = iterations;
@@ -114,7 +134,16 @@ class CUGR
114134
void saveCongestion();
115135

116136
private:
117-
float calculatePartialSlack();
137+
// Refresh net slacks, re-mark the res-aware/critical set, and demote
138+
// non-critical nets so the next stage routes critical nets first.
139+
void updateCriticalNets();
140+
// Re-extract parasitics and refresh every net's slack from the routing.
141+
void updateNetSlacks();
142+
// Slack value at the critical_nets_percentage_ percentile of the nets.
143+
float criticalSlackThreshold() const;
144+
// Push nets with slack above the threshold to the back of the default
145+
// ordering by maxing their slack; res-aware nets are exempt.
146+
void demoteNonCriticalNets(float slack_th);
118147
float getNetSlack(odb::dbNet* net);
119148
void setInitialNetSlacks();
120149

@@ -134,6 +163,8 @@ class CUGR
134163
* at all).
135164
*/
136165
std::vector<double> computeNdrCosts(odb::dbNet* db_net) const;
166+
167+
std::vector<int> computeNdrWidths(odb::dbNet* db_net) const;
137168
/**
138169
* @brief Builds the rip-up set of nets touching a congested edge.
139170
*
@@ -154,11 +185,14 @@ class CUGR
154185
double threshold = 1.0);
155186

156187
void patternRoute(std::vector<int>& net_indices);
188+
// Re-route the critical nets on real 3D-tree resistance, right after the
189+
// neutral first PatternRoute.
190+
void patternRouteResAware(std::vector<int>& net_indices);
157191
void patternRouteWithDetours(std::vector<int>& net_indices);
158192
void mazeRoute(std::vector<int>& net_indices);
159193

160194
/**
161-
* @brief Stage 4 — iterative rip-up and re-route.
195+
* @brief Stage 5 — iterative rip-up and re-route.
162196
*
163197
* Wraps the maze stage in a loop that sharpens the logistic cost
164198
* slope each pass (so `PatternRoute` and the maze cost surface
@@ -169,18 +203,18 @@ class CUGR
169203
* stay idle.
170204
*
171205
* Early-exits when the integer overflow metric (`totalOverflow()`)
172-
* is already zero, so designs that finished stage 3 clean pay no
206+
* is already zero, so designs that finished stage 4 clean pay no
173207
* cost. Emits `GRT-0117` per iteration and `GRT-0118` if overflow
174208
* remains when the loop ends.
175209
*
176-
* See `src/grt/doc/01-iterative-rrr.md` for the cost-model audit
177-
* and the rationale for the chosen defaults.
178-
*
179210
* @param net_indices Reused scratch buffer (cleared on entry by
180211
* `updateCongestedNets`).
181212
*/
182213
void iterativeRRR(std::vector<int>& net_indices);
183-
void sortNetIndices(std::vector<int>& net_indices) const;
214+
// res_aware_order selects the multi-factor res-aware ordering; false uses
215+
// the default slack/bbox order.
216+
void sortNetIndices(std::vector<int>& net_indices,
217+
bool res_aware_order) const;
184218
void getGuides(const GRNet* net,
185219
std::vector<std::pair<int, grt::BoxT>>& guides);
186220
void printStatistics() const;
@@ -224,9 +258,28 @@ class CUGR
224258
int area_of_pin_patches_ = 0;
225259
int area_of_wire_patches_ = 0;
226260

227-
float critical_nets_percentage_ = 0;
261+
float critical_nets_percentage_ = 10;
228262
int congestion_iterations_ = 5;
229263

264+
bool resistance_aware_ = false;
265+
// Per-run normalisers for getResAwareScore (default 1 => well-defined).
266+
float worst_slack_ = 1.0f;
267+
float worst_resistance_ = 1.0f;
268+
int worst_fanout_ = 1;
269+
int worst_net_length_ = 1;
270+
271+
// Percent of eligible candidate nets marked res-aware; set via
272+
// -res_aware_nets_percentage (FastRoute default).
273+
float res_aware_percentage_ = 15.0f;
274+
275+
// Select the res-aware net set (like FastRoute updateSlacks) and refresh the
276+
// worst_* normalisers; no-op unless resistance_aware_.
277+
void markResAwareNets();
278+
279+
// FR-style ordering score (lower routes first): slack/resistance/fanout/
280+
// length blend, each normalised by the per-run worst.
281+
float getResAwareScore(const GRNet* net) const;
282+
230283
std::vector<int> nets_to_route_;
231284
};
232285

0 commit comments

Comments
 (0)