Skip to content

Commit aea03d0

Browse files
authored
Merge pull request #10756 from eder-matheus/grt_cugr_fix
grt: ensure CUGR/FastRoute paths will not call functions from the wrong engine
2 parents 9f87d49 + 1d645dd commit aea03d0

2 files changed

Lines changed: 130 additions & 44 deletions

File tree

src/grt/include/grt/GlobalRouter.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -361,6 +361,7 @@ class GlobalRouter
361361
void applyAdjustments(int min_routing_layer, int max_routing_layer);
362362
// main functions
363363
void initCoreGrid(int max_routing_layer);
364+
void mirrorGridToFastRoute(int max_routing_layer);
364365
void initRoutingLayers(int min_routing_layer, int max_routing_layer);
365366
void checkAdjacentLayersDirection(int min_routing_layer,
366367
int max_routing_layer);
@@ -375,6 +376,11 @@ class GlobalRouter
375376
bool horizontal);
376377
odb::Rect getGCellRect(int x, int y);
377378
void initNetlist(std::vector<Net*>& nets, bool incremental = false);
379+
void computeNetDegree(const std::vector<Net*>& nets,
380+
int& min_degree,
381+
int& max_degree);
382+
void reportNetDegree(const std::vector<Net*>& nets);
383+
void reportMacrosAndBlockages();
378384
std::vector<Net*> initNets(bool check_pin_placement = true);
379385
void initRoutingGrid(int min_routing_layer, int max_routing_layer);
380386
std::vector<Net*> initCUGR(int min_routing_layer, int max_routing_layer);

src/grt/src/GlobalRouter.cpp

Lines changed: 124 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,9 @@ void GlobalRouter::clear()
155155
routing_tracks_.clear();
156156
routing_layers_.clear();
157157
grid_->clear();
158-
fastroute_->clear();
158+
if (!use_cugr_) {
159+
fastroute_->clear();
160+
}
159161
vertical_capacities_.clear();
160162
horizontal_capacities_.clear();
161163
initialized_ = false;
@@ -180,7 +182,6 @@ std::vector<Net*> GlobalRouter::initNets(bool check_pin_placement)
180182
if (check_pin_placement) {
181183
checkPinPlacement();
182184
}
183-
initNetlist(nets);
184185
return nets;
185186
}
186187

@@ -190,18 +191,21 @@ void GlobalRouter::initRoutingGrid(int min_routing_layer, int max_routing_layer)
190191
reportLayerSettings(min_routing_layer, max_routing_layer);
191192
initRoutingTracks(max_routing_layer);
192193
initCoreGrid(max_routing_layer);
193-
computeObstructionsAdjustments();
194-
computeUserGlobalAdjustments(min_routing_layer, max_routing_layer);
195194
}
196195

197196
std::vector<Net*> GlobalRouter::initCUGR(int min_routing_layer,
198197
int max_routing_layer)
199198
{
200199
initRoutingGrid(min_routing_layer, max_routing_layer);
200+
// Propagate the global adjustment to per-layer values that CUGR reads from
201+
// the tech layers; this is engine-agnostic, unlike the FastRoute edge passes.
202+
computeUserGlobalAdjustments(min_routing_layer, max_routing_layer);
203+
reportMacrosAndBlockages();
201204
std::vector<Net*> nets = initNets(true);
202205
initialized_ = true;
203206
odb::PtrSet<odb::dbNet> clock_nets;
204207
findClockNets(nets, clock_nets);
208+
reportNetDegree(nets);
205209

206210
cugr_->setCongestionIterations(congestion_iterations_);
207211
cugr_->init(min_routing_layer, max_routing_layer, clock_nets);
@@ -222,6 +226,7 @@ std::vector<Net*> GlobalRouter::initFastRoute(int min_routing_layer,
222226
reportLayerSettings(min_routing_layer, max_routing_layer);
223227
initRoutingTracks(max_routing_layer);
224228
initCoreGrid(max_routing_layer);
229+
mirrorGridToFastRoute(max_routing_layer);
225230
setCapacities(min_routing_layer, max_routing_layer);
226231

227232
applyAdjustments(min_routing_layer, max_routing_layer);
@@ -231,6 +236,7 @@ std::vector<Net*> GlobalRouter::initFastRoute(int min_routing_layer,
231236
fastroute_->initEdgesCapacityPerLayer();
232237

233238
std::vector<Net*> nets = initNets(check_pin_placement);
239+
initNetlist(nets);
234240

235241
initialized_ = true;
236242
return nets;
@@ -240,6 +246,7 @@ void GlobalRouter::applyAdjustments(int min_routing_layer,
240246
int max_routing_layer)
241247
{
242248
computeObstructionsAdjustments();
249+
reportMacrosAndBlockages();
243250
std::vector<int> track_space = grid_->getTrackPitches();
244251
fastroute_->initBlockedIntervals(track_space);
245252
// Save global resources before add adjustment by layer
@@ -291,12 +298,25 @@ NetRouteMap GlobalRouter::getPartialRoutes()
291298
NetRouteMap net_routes;
292299
// TODO: still need to fix this during incremental grt
293300
if (is_incremental_) {
301+
// Source partial routes from the active engine; CUGR has no FastRoute
302+
// trees.
303+
NetRouteMap cugr_routes;
304+
if (use_cugr_) {
305+
cugr_routes = cugr_->getRoutes();
306+
}
294307
for (const auto& [db_net, net] : db_net_map_) {
295308
// Do not add local nets, as they are not routed in incremental grt.
296309
if (routes_[db_net].empty() && !net->isLocal()) {
297-
GRoute route;
298-
net_routes.insert({db_net, route});
299-
fastroute_->getPlanarRoute(db_net, net_routes[db_net]);
310+
if (use_cugr_) {
311+
auto it = cugr_routes.find(db_net);
312+
if (it != cugr_routes.end() && !it->second.empty()) {
313+
net_routes[db_net] = it->second;
314+
}
315+
} else {
316+
GRoute route;
317+
net_routes.insert({db_net, route});
318+
fastroute_->getPlanarRoute(db_net, net_routes[db_net]);
319+
}
300320
}
301321
}
302322
} else {
@@ -409,7 +429,6 @@ void GlobalRouter::startIncremental()
409429
void GlobalRouter::endIncremental(bool save_guides)
410430
{
411431
is_incremental_ = true;
412-
fastroute_->setResistanceAware(resistance_aware_);
413432
updateDirtyRoutes(save_guides);
414433
grouter_cbk_->removeOwner();
415434
delete grouter_cbk_;
@@ -499,8 +518,10 @@ void GlobalRouter::finishGlobalRouting(bool save_guides)
499518
}
500519

501520
if (is_congested_) {
502-
// Suggest adjustment value
503-
suggestAdjustment();
521+
// suggestAdjustment relies on FastRoute congestion data.
522+
if (!use_cugr_) {
523+
suggestAdjustment();
524+
}
504525
// CUGR overflow is downgraded to a warning even without -allow_congestion,
505526
// since it produces good results on detailed routing.
506527
if (allow_congestion_ || use_cugr_) {
@@ -769,7 +790,14 @@ void GlobalRouter::initCoreGrid(int max_routing_layer)
769790
{
770791
initGrid(max_routing_layer);
771792
findTrackPitches(max_routing_layer);
793+
}
772794

795+
// Mirror the engine-agnostic grid into FastRoute's structures. Only the
796+
// FastRoute path needs this; CUGR maintains its own grid.
797+
void GlobalRouter::mirrorGridToFastRoute(int max_routing_layer)
798+
{
799+
fastroute_->setRegularX(grid_->isPerfectRegularX());
800+
fastroute_->setRegularY(grid_->isPerfectRegularY());
773801
fastroute_->setLowerLeft(grid_->getXMin(), grid_->getYMin());
774802
fastroute_->setTileSize(grid_->getTileSize());
775803
fastroute_->setGridsAndLayers(
@@ -1413,8 +1441,9 @@ std::vector<RoutePt> GlobalRouter::findOnGridPositions(
14131441
pos_on_grid = grid_->getPositionOnGrid(rect_middle);
14141442
// if a macro/pad pin is unreachable due to not having enough resources
14151443
// at its on grid position, get the position closest to the macro/pad
1416-
// boundary to ensure routability
1417-
if (pin.isConnectedToPadOrMacro()
1444+
// boundary to ensure routability. CUGR has no FastRoute edge capacities
1445+
// to query, so it skips this heuristic and routes from the center.
1446+
if (!use_cugr_ && pin.isConnectedToPadOrMacro()
14181447
&& !isPinReachable(pin, pos_on_grid)) {
14191448
pos_on_grid = grid_->getPositionOnGrid(
14201449
pin.getPositionNearInstEdge(pin_box, rect_middle));
@@ -1560,17 +1589,85 @@ float GlobalRouter::getNetSlack(Net* net)
15601589
return sta_->slack(net->getDbNet(), sta::MinMax::max());
15611590
}
15621591

1592+
// Net degree (pin count) statistics over the nets that get routed; engine
1593+
// agnostic, so both FastRoute and CUGR report the same numbers.
1594+
void GlobalRouter::computeNetDegree(const std::vector<Net*>& nets,
1595+
int& min_degree,
1596+
int& max_degree)
1597+
{
1598+
min_degree = std::numeric_limits<int>::max();
1599+
// Do NOT use numeric_limits<int>::min() to init this because if there are
1600+
// no FR nets the max degree will be big negative and cannot be used to init
1601+
// the vectors in FR.
1602+
max_degree = 1;
1603+
for (Net* net : nets) {
1604+
int pin_count = net->getNumPins();
1605+
int min_layer, max_layer;
1606+
getNetLayerRange(net->getDbNet(), min_layer, max_layer);
1607+
odb::dbTechLayer* max_routing_layer
1608+
= db_->getTech()->findRoutingLayer(max_layer);
1609+
if (pin_count > 1
1610+
&& (!net->hasWires() || net->hasStackedVias(max_routing_layer))) {
1611+
min_degree = std::min(pin_count, min_degree);
1612+
max_degree = std::max(pin_count, max_degree);
1613+
}
1614+
}
1615+
}
1616+
1617+
void GlobalRouter::reportNetDegree(const std::vector<Net*>& nets)
1618+
{
1619+
if (!verbose_) {
1620+
return;
1621+
}
1622+
int min_degree, max_degree;
1623+
computeNetDegree(nets, min_degree, max_degree);
1624+
// No routable net passed the degree filter; report zeros instead of the
1625+
// sentinel min_degree.
1626+
if (nets.empty() || min_degree == std::numeric_limits<int>::max()) {
1627+
min_degree = 0;
1628+
max_degree = 0;
1629+
}
1630+
logger_->info(GRT, 1, "Minimum degree: {}", min_degree);
1631+
logger_->info(GRT, 2, "Maximum degree: {}", max_degree);
1632+
}
1633+
1634+
// Macro and blockage counts read straight from the db; engine agnostic.
1635+
void GlobalRouter::reportMacrosAndBlockages()
1636+
{
1637+
if (!verbose_) {
1638+
return;
1639+
}
1640+
const int min_layer = getMinRoutingLayer();
1641+
const int max_layer = getMaxRoutingLayer();
1642+
int macros_cnt = 0;
1643+
int blockages_cnt = 0;
1644+
1645+
for (odb::dbObstruction* obstruction : block_->getObstructions()) {
1646+
const int layer = obstruction->getBBox()->getTechLayer()->getRoutingLevel();
1647+
if (min_layer <= layer && layer <= max_layer) {
1648+
blockages_cnt++;
1649+
}
1650+
}
1651+
for (odb::dbInst* inst : block_->getInsts()) {
1652+
odb::dbMaster* master = inst->getMaster();
1653+
if (master->isBlock()) {
1654+
macros_cnt++;
1655+
}
1656+
for (odb::dbBox* box : master->getObstructions()) {
1657+
const int layer = box->getTechLayer()->getRoutingLevel();
1658+
if (min_layer <= layer && layer <= max_layer) {
1659+
blockages_cnt++;
1660+
}
1661+
}
1662+
}
1663+
logger_->info(GRT, 3, "Macros: {}", macros_cnt);
1664+
logger_->info(GRT, 4, "Blockages: {}", blockages_cnt);
1665+
}
1666+
15631667
void GlobalRouter::initNetlist(std::vector<Net*>& nets, bool incremental)
15641668
{
15651669
pad_pins_connections_.clear();
15661670

1567-
int min_degree = std::numeric_limits<int>::max();
1568-
// Do NOT use numeric_limits<int>::min() to init
1569-
// this because if there are no FR nets the max
1570-
// degree will be big negative and cannot be used
1571-
// to init the vectors in FR.
1572-
int max_degree = 1;
1573-
15741671
if (nets.size() > 1 && seed_ != 0) {
15751672
std::mt19937 g;
15761673
g.seed(seed_);
@@ -1585,20 +1682,13 @@ void GlobalRouter::initNetlist(std::vector<Net*>& nets, bool incremental)
15851682
= db_->getTech()->findRoutingLayer(max_layer);
15861683
if (pin_count > 1
15871684
&& (!net->hasWires() || net->hasStackedVias(max_routing_layer))) {
1588-
min_degree = std::min(pin_count, min_degree);
1589-
1590-
max_degree = std::max(pin_count, max_degree);
15911685
makeFastrouteNet(net);
15921686
}
15931687
}
1688+
int min_degree, max_degree;
1689+
computeNetDegree(nets, min_degree, max_degree);
15941690
fastroute_->setMaxNetDegree(max_degree);
1595-
1596-
if (verbose_) {
1597-
min_degree = nets.empty() ? 0 : min_degree;
1598-
max_degree = nets.empty() ? 0 : max_degree;
1599-
logger_->info(GRT, 1, "Minimum degree: {}", min_degree);
1600-
logger_->info(GRT, 2, "Maximum degree: {}", max_degree);
1601-
}
1691+
reportNetDegree(nets);
16021692

16031693
// Add resources for pin access in macro/pad pins after defining their on grid
16041694
// position. It must be done only in the initialization of the tool, not
@@ -2522,6 +2612,7 @@ void GlobalRouter::initGridAndNets()
25222612
initRoutingLayers(min_layer, max_layer);
25232613
initRoutingTracks(max_layer);
25242614
initCoreGrid(max_layer);
2615+
mirrorGridToFastRoute(max_layer);
25252616
setCapacities(min_layer, max_layer);
25262617
applyAdjustments(min_layer, max_layer);
25272618
}
@@ -4350,9 +4441,6 @@ void GlobalRouter::initGrid(int max_layer)
43504441
bool perfect_regular_x = (x_grids * tile_size) == dx;
43514442
bool perfect_regular_y = (y_grids * tile_size) == dy;
43524443

4353-
fastroute_->setRegularX(perfect_regular_x);
4354-
fastroute_->setRegularY(perfect_regular_y);
4355-
43564444
int num_layers = routing_layers_.size();
43574445
if (max_layer > -1) {
43584446
num_layers = max_layer;
@@ -4990,17 +5078,12 @@ void GlobalRouter::computeObstructionsAdjustments()
49905078
std::map<int, std::vector<odb::Rect>> layer_obs_map;
49915079

49925080
findLayerExtensions(layer_extensions);
4993-
int obstructions_cnt = findObstructions(die_area);
4994-
obstructions_cnt
4995-
+= findInstancesObstructions(die_area, layer_extensions, layer_obs_map);
5081+
findObstructions(die_area);
5082+
findInstancesObstructions(die_area, layer_extensions, layer_obs_map);
49965083
findNetsObstructions(die_area);
49975084

49985085
std::vector<LayerId> transition_layers = findTransitionLayers();
49995086
adjustTransitionLayers(transition_layers, layer_obs_map);
5000-
5001-
if (verbose_) {
5002-
logger_->info(GRT, 4, "Blockages: {}", obstructions_cnt);
5003-
}
50045087
}
50055088

50065089
void GlobalRouter::findLayerExtensions(std::vector<int>& layer_extensions)
@@ -5151,7 +5234,6 @@ int GlobalRouter::findInstancesObstructions(
51515234
const std::vector<int>& layer_extensions,
51525235
std::map<int, std::vector<odb::Rect>>& layer_obs_map)
51535236
{
5154-
int macros_cnt = 0;
51555237
int obstructions_cnt = 0;
51565238
int pin_out_of_die_count = 0;
51575239
odb::dbTech* tech = db_->getTech();
@@ -5162,7 +5244,6 @@ int GlobalRouter::findInstancesObstructions(
51625244

51635245
bool is_macro = false;
51645246
if (master->isBlock()) {
5165-
macros_cnt++;
51665247
is_macro = true;
51675248
has_macros_or_pads_ = true;
51685249
}
@@ -5283,9 +5364,6 @@ int GlobalRouter::findInstancesObstructions(
52835364
}
52845365
}
52855366

5286-
if (verbose_) {
5287-
logger_->info(GRT, 3, "Macros: {}", macros_cnt);
5288-
}
52895367
return obstructions_cnt;
52905368
}
52915369

@@ -6263,6 +6341,8 @@ std::vector<Net*> GlobalRouter::updateDirtyRoutes(bool save_guides)
62636341

62646342
std::vector<Net*> dirty_nets;
62656343

6344+
fastroute_->setResistanceAware(resistance_aware_);
6345+
62666346
if (!initialized_) {
62676347
int min_layer, max_layer;
62686348
getMinMaxLayer(min_layer, max_layer);

0 commit comments

Comments
 (0)