Skip to content

Commit a2277d1

Browse files
Merge pull request #3170 to add CHANZ rr node type
Add CHANZ type
2 parents cd79e68 + 3feadb9 commit a2277d1

32 files changed

+637
-481
lines changed

libs/librrgraph/src/base/check_rr_graph.cpp

Lines changed: 40 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -58,13 +58,13 @@ void check_rr_graph(const RRGraphView& rr_graph,
5858
route_type = e_route_type::GLOBAL;
5959
}
6060

61-
auto total_edges_to_node = std::vector<int>(rr_graph.num_nodes());
62-
auto switch_types_from_current_to_node = std::vector<unsigned char>(rr_graph.num_nodes());
61+
std::vector<int> total_edges_to_node(rr_graph.num_nodes());
62+
std::vector<unsigned char> switch_types_from_current_to_node(rr_graph.num_nodes());
6363
const int num_rr_switches = rr_graph.num_rr_switches();
6464

6565
std::vector<std::pair<int, int>> edges;
6666

67-
for (const RRNodeId& rr_node : rr_graph.nodes()) {
67+
for (const RRNodeId rr_node : rr_graph.nodes()) {
6868
size_t inode = (size_t)rr_node;
6969
rr_graph.validate_node(rr_node);
7070

@@ -83,7 +83,7 @@ void check_rr_graph(const RRGraphView& rr_graph,
8383

8484
check_rr_node(rr_graph, rr_indexed_data, grid, chan_width, route_type, inode, is_flat);
8585

86-
/* Check all the connectivity (edges, etc.) information. */
86+
// Check all the connectivity (edges, etc.) information.
8787
edges.resize(0);
8888
edges.reserve(num_edges);
8989

@@ -329,16 +329,15 @@ void check_rr_node(const RRGraphView& rr_graph,
329329
const enum e_route_type route_type,
330330
const int inode,
331331
bool is_flat) {
332-
/* This routine checks that the rr_node is inside the grid and has a valid
333-
* pin number, etc.
334-
*/
335-
336332
//Make sure over-flow doesn't happen
337333
VTR_ASSERT(inode >= 0);
338-
int nodes_per_chan, tracks_per_node;
339-
float C, R;
334+
int tracks_per_node;
340335
RRNodeId rr_node = RRNodeId(inode);
341336

337+
const int grid_width = grid.width();
338+
const int grid_height = grid.height();
339+
const int grid_layers = grid.get_num_layers();
340+
342341
e_rr_type rr_type = rr_graph.node_type(rr_node);
343342
int xlow = rr_graph.node_xlow(rr_node);
344343
int xhigh = rr_graph.node_xhigh(rr_node);
@@ -348,19 +347,18 @@ void check_rr_node(const RRGraphView& rr_graph,
348347
int ptc_num = rr_graph.node_ptc_num(rr_node);
349348
int capacity = rr_graph.node_capacity(rr_node);
350349
RRIndexedDataId cost_index = rr_graph.node_cost_index(rr_node);
351-
t_physical_tile_type_ptr type = nullptr;
352350

353351
if (xlow > xhigh || ylow > yhigh) {
354352
VPR_ERROR(VPR_ERROR_ROUTE,
355353
"in check_rr_node: rr endpoints are (%d,%d) and (%d,%d).\n", xlow, ylow, xhigh, yhigh);
356354
}
357355

358-
if (xlow < 0 || xhigh > int(grid.width()) - 1 || ylow < 0 || yhigh > int(grid.height()) - 1) {
356+
if (xlow < 0 || xhigh > grid_width - 1 || ylow < 0 || yhigh > grid_height - 1) {
359357
VPR_FATAL_ERROR(VPR_ERROR_ROUTE,
360358
"in check_rr_node: rr endpoints (%d,%d) and (%d,%d) are out of range.\n", xlow, ylow, xhigh, yhigh);
361359
}
362360

363-
if (layer_num < 0 || layer_num > int(grid.get_num_layers()) - 1) {
361+
if (layer_num < 0 || layer_num > grid_layers - 1) {
364362
VPR_FATAL_ERROR(VPR_ERROR_ROUTE,
365363
"in check_rr_node: rr endpoints layer_num (%d) is out of range.\n", layer_num);
366364
}
@@ -375,8 +373,8 @@ void check_rr_node(const RRGraphView& rr_graph,
375373
"in check_rr_node: node %d cost index (%d) is out of range.\n", inode, cost_index);
376374
}
377375

378-
/* Check that the segment is within the array and such. */
379-
type = grid.get_physical_type({xlow, ylow, layer_num});
376+
// Check that the segment is within the array and such.
377+
t_physical_tile_type_ptr type = grid.get_physical_type({xlow, ylow, layer_num});
380378

381379
switch (rr_type) {
382380
case e_rr_type::SOURCE:
@@ -416,7 +414,7 @@ void check_rr_node(const RRGraphView& rr_graph,
416414
break;
417415

418416
case e_rr_type::CHANX:
419-
if (xlow < 1 || xhigh > int(grid.width()) - 2 || yhigh > int(grid.height()) - 2 || yhigh != ylow) {
417+
if (xlow < 1 || xhigh > grid_width - 1 || yhigh > grid_height - 1 || yhigh != ylow) {
420418
VPR_FATAL_ERROR(VPR_ERROR_ROUTE,
421419
"in check_rr_node: CHANX out of range for endpoints (%d,%d) and (%d,%d)\n", xlow, ylow, xhigh, yhigh);
422420
}
@@ -427,7 +425,7 @@ void check_rr_node(const RRGraphView& rr_graph,
427425
break;
428426

429427
case e_rr_type::CHANY:
430-
if (xhigh > int(grid.width()) - 2 || ylow < 1 || yhigh > int(grid.height()) - 2 || xlow != xhigh) {
428+
if (xhigh > grid_width - 1 || ylow < 1 || yhigh > grid_height - 1 || xlow != xhigh) {
431429
VPR_FATAL_ERROR(VPR_ERROR_ROUTE,
432430
"Error in check_rr_node: CHANY out of range for endpoints (%d,%d) and (%d,%d)\n", xlow, ylow, xhigh, yhigh);
433431
}
@@ -437,12 +435,20 @@ void check_rr_node(const RRGraphView& rr_graph,
437435
}
438436
break;
439437

438+
case e_rr_type::CHANZ:
439+
if (xhigh != xlow || yhigh != ylow || xhigh > grid_width - 1 || ylow < 1 || yhigh > grid_height - 1) {
440+
VPR_FATAL_ERROR(VPR_ERROR_ROUTE,
441+
"Error in check_rr_node: CHANZ out of range for endpoints (%d,%d) and (%d,%d)\n", xlow, ylow, xhigh, yhigh);
442+
}
443+
// TODO: handle global routing case
444+
break;
445+
440446
default:
441447
VPR_FATAL_ERROR(VPR_ERROR_ROUTE,
442448
"in check_rr_node: Unexpected segment type: %d\n", rr_type);
443449
}
444450

445-
/* Check that it's capacities and such make sense. */
451+
// Check that its capacities and such make sense.
446452

447453
int class_max_ptc = get_tile_class_max_ptc(type, is_flat);
448454
int pin_max_ptc = get_tile_pin_max_ptc(type, is_flat);
@@ -481,20 +487,9 @@ void check_rr_node(const RRGraphView& rr_graph,
481487
case e_rr_type::CHANX:
482488
case e_rr_type::CHANY:
483489
if (route_type == e_route_type::DETAILED) {
484-
nodes_per_chan = chan_width.max;
485490
tracks_per_node = 1;
486491
} else {
487-
nodes_per_chan = 1;
488-
tracks_per_node = ((rr_type == e_rr_type::CHANX) ? chan_width.x_list[ylow] : chan_width.y_list[xlow]);
489-
}
490-
491-
//if a chanx/chany has length 0, it means it is used to connect different dice together
492-
//hence, the ptc number can be larger than nodes_per_chan
493-
if(xlow != xhigh || ylow != yhigh) {
494-
if (ptc_num >= nodes_per_chan) {
495-
VPR_ERROR(VPR_ERROR_ROUTE,
496-
"in check_rr_node: inode %d (type %d) has a ptc_num of %d.\n", inode, rr_type, ptc_num);
497-
}
492+
tracks_per_node = (rr_type == e_rr_type::CHANX) ? chan_width.x_list[ylow] : chan_width.y_list[xlow];
498493
}
499494

500495
if (capacity != tracks_per_node) {
@@ -503,14 +498,26 @@ void check_rr_node(const RRGraphView& rr_graph,
503498
}
504499
break;
505500

501+
case e_rr_type::CHANZ:
502+
if (route_type == e_route_type::DETAILED) {
503+
tracks_per_node = 1;
504+
} else {
505+
// TODO: do checks for CHANZ type when global routing is enabled
506+
// This can be done once we have a way to specify how many chanz
507+
// nodes per switch block exist.
508+
VPR_FATAL_ERROR(VPR_ERROR_ROUTE,
509+
"in check_rr_node: Global routing is not supported in 3D architectures.\n");
510+
}
511+
break;
512+
506513
default:
507514
VPR_FATAL_ERROR(VPR_ERROR_ROUTE,
508515
"in check_rr_node: Unexpected segment type: %d\n", rr_type);
509516
}
510517

511-
/* Check that the capacitance and resistance are reasonable. */
512-
C = rr_graph.node_C(rr_node);
513-
R = rr_graph.node_R(rr_node);
518+
// Check that the capacitance and resistance are reasonable.
519+
float C = rr_graph.node_C(rr_node);
520+
float R = rr_graph.node_R(rr_node);
514521

515522
if (rr_type == e_rr_type::CHANX || rr_type == e_rr_type::CHANY) {
516523
if (C < 0. || R < 0.) {

libs/librrgraph/src/base/check_rr_graph.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,27 @@ void check_rr_graph(const RRGraphView& rr_graph,
1212
const e_graph_type graph_type,
1313
bool is_flat);
1414

15+
/**
16+
* @brief Validates the internal consistency of a single RR node in the routing resource graph.
17+
*
18+
* This function performs a series of checks on the specified RR node to ensure it conforms
19+
* to architectural and routing constraints. It verifies:
20+
* - That the node's bounding box is valid and within the device grid bounds.
21+
* - That the node's PTC number, capacity, and cost index are within legal limits.
22+
* - That IPINs, OPINs, SOURCEs, and SINKs correspond to valid physical locations and types.
23+
* - That CHANX, CHANY, and CHANZ nodes have legal coordinate bounds and track indices.
24+
* - That electrical characteristics (resistance and capacitance) are appropriate for the node type.
25+
*
26+
* Errors or inconsistencies will cause fatal errors or logged messages, depending on severity.
27+
*
28+
* @param rr_graph The read-only view of the routing resource graph.
29+
* @param rr_indexed_data Indexed data for RR node cost metrics.
30+
* @param grid The device grid.
31+
* @param chan_width The channel widths for different channels
32+
* @param route_type The routing type (GLOBAL or DETAILED).
33+
* @param inode The index of the RR node to be checked.
34+
* @param is_flat Flag indicating if flat routing is enabled.
35+
*/
1536
void check_rr_node(const RRGraphView& rr_graph,
1637
const vtr::vector<RRIndexedDataId, t_rr_indexed_data>& rr_indexed_data,
1738
const DeviceGrid& grid,

libs/librrgraph/src/base/rr_graph_builder.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ void RRGraphBuilder::add_node_to_all_locs(RRNodeId node) {
3333
switch (node_type) {
3434
case e_rr_type::SOURCE:
3535
case e_rr_type::SINK:
36+
case e_rr_type::CHANZ:
3637
case e_rr_type::CHANY:
3738
case e_rr_type::CHANX:
3839
node_lookup_.add_node(node, node_layer, ix, iy, node_type, node_ptc_num, TOTAL_2D_SIDES[0]);

libs/librrgraph/src/base/rr_graph_storage.cpp

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -646,8 +646,8 @@ void t_rr_graph_storage::set_node_pin_num(RRNodeId id, int new_pin_num) {
646646
}
647647

648648
void t_rr_graph_storage::set_node_track_num(RRNodeId id, int new_track_num) {
649-
if (node_type(id) != e_rr_type::CHANX && node_type(id) != e_rr_type::CHANY) {
650-
VTR_LOG_ERROR("Attempted to set RR node 'track_num' for non-CHANX/CHANY type '%s'", node_type_string(id));
649+
if (node_type(id) != e_rr_type::CHANX && node_type(id) != e_rr_type::CHANY && node_type(id) != e_rr_type::CHANZ) {
650+
VTR_LOG_ERROR("Attempted to set RR node 'track_num' for non-CHANX/CHANY/CHANZ type '%s'", node_type_string(id));
651651
}
652652
node_ptc_[id].ptc_.track_num = new_track_num;
653653
}
@@ -663,32 +663,29 @@ int t_rr_graph_storage::node_ptc_num(RRNodeId id) const {
663663
return node_ptc_[id].ptc_.pin_num;
664664
}
665665

666-
static int get_node_pin_num(
667-
vtr::array_view_id<RRNodeId, const t_rr_node_data> node_storage,
668-
vtr::array_view_id<RRNodeId, const t_rr_node_ptc_data> node_ptc,
669-
RRNodeId id) {
666+
static int get_node_pin_num(vtr::array_view_id<RRNodeId, const t_rr_node_data> node_storage,
667+
vtr::array_view_id<RRNodeId, const t_rr_node_ptc_data> node_ptc,
668+
RRNodeId id) {
670669
e_rr_type node_type = node_storage[id].type_;
671670
if (node_type != e_rr_type::IPIN && node_type != e_rr_type::OPIN) {
672671
VTR_LOG_ERROR("Attempted to access RR node 'pin_num' for non-IPIN/OPIN type '%s'", rr_node_typename[node_type]);
673672
}
674673
return node_ptc[id].ptc_.pin_num;
675674
}
676675

677-
static int get_node_track_num(
678-
vtr::array_view_id<RRNodeId, const t_rr_node_data> node_storage,
679-
vtr::array_view_id<RRNodeId, const t_rr_node_ptc_data> node_ptc,
680-
RRNodeId id) {
676+
static int get_node_track_num(vtr::array_view_id<RRNodeId, const t_rr_node_data> node_storage,
677+
vtr::array_view_id<RRNodeId, const t_rr_node_ptc_data> node_ptc,
678+
RRNodeId id) {
681679
e_rr_type node_type = node_storage[id].type_;
682-
if (node_type != e_rr_type::CHANX && node_type != e_rr_type::CHANY) {
683-
VTR_LOG_ERROR("Attempted to access RR node 'track_num' for non-CHANX/CHANY type '%s'", rr_node_typename[node_type]);
680+
if (node_type != e_rr_type::CHANX && node_type != e_rr_type::CHANY && node_type != e_rr_type::CHANZ) {
681+
VTR_LOG_ERROR("Attempted to access RR node 'track_num' for non-CHANX/CHANY/CHANZ type '%s'", rr_node_typename[node_type]);
684682
}
685683
return node_ptc[id].ptc_.track_num;
686684
}
687685

688-
static int get_node_class_num(
689-
vtr::array_view_id<RRNodeId, const t_rr_node_data> node_storage,
690-
vtr::array_view_id<RRNodeId, const t_rr_node_ptc_data> node_ptc,
691-
RRNodeId id) {
686+
static int get_node_class_num(vtr::array_view_id<RRNodeId, const t_rr_node_data> node_storage,
687+
vtr::array_view_id<RRNodeId, const t_rr_node_ptc_data> node_ptc,
688+
RRNodeId id) {
692689
e_rr_type node_type = node_storage[id].type_;
693690
if (node_type != e_rr_type::SOURCE && node_type != e_rr_type::SINK) {
694691
VTR_LOG_ERROR("Attempted to access RR node 'class_num' for non-SOURCE/SINK type '%s'", rr_node_typename[node_type]);
@@ -760,7 +757,7 @@ void t_rr_graph_storage::set_node_capacity(RRNodeId id, short new_capacity) {
760757
}
761758

762759
void t_rr_graph_storage::set_node_direction(RRNodeId id, Direction new_direction) {
763-
if (node_type(id) != e_rr_type::CHANX && node_type(id) != e_rr_type::CHANY) {
760+
if (node_type(id) != e_rr_type::CHANX && node_type(id) != e_rr_type::CHANY && node_type(id) != e_rr_type::CHANZ) {
764761
VTR_LOG_ERROR("Attempted to set RR node 'direction' for non-channel type '%s'", node_type_string(id));
765762
}
766763
node_storage_[id].dir_side_.direction = new_direction;

0 commit comments

Comments
 (0)