Skip to content

Commit 4b12c57

Browse files
authored
Merge pull request #1661 from tangxifan/rr_graph_node_side_patch
Deploy new API rr_node.node_sides() to GUI
2 parents 573af4a + a3eebdc commit 4b12c57

File tree

3 files changed

+172
-43
lines changed

3 files changed

+172
-43
lines changed

vpr/src/draw/draw.cpp

Lines changed: 167 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -2121,24 +2121,32 @@ static void draw_rr_pin(int inode, const ezgl::color& color, ezgl::renderer* g)
21212121
g->set_color(color);
21222122

21232123
/* TODO: This is where we can hide fringe physical pins and also identify globals (hide, color, show) */
2124-
draw_get_rr_pin_coords(inode, &xcen, &ycen);
2125-
g->fill_rectangle({xcen - draw_coords->pin_size, ycen - draw_coords->pin_size},
2126-
{xcen + draw_coords->pin_size, ycen + draw_coords->pin_size});
2127-
sprintf(str, "%d", ipin);
2128-
g->set_color(ezgl::BLACK);
2129-
g->draw_text({xcen, ycen}, str, 2 * draw_coords->pin_size, 2 * draw_coords->pin_size);
2130-
g->set_color(color);
2124+
/* As nodes may appear on more than one side, walk through the possible nodes
2125+
* - draw the pin on each side that it appears
2126+
*/
2127+
for (const e_side& pin_side : SIDES) {
2128+
if (!device_ctx.rr_nodes[inode].is_node_on_specific_side(pin_side)) {
2129+
continue;
2130+
}
2131+
draw_get_rr_pin_coords(inode, &xcen, &ycen, pin_side);
2132+
g->fill_rectangle({xcen - draw_coords->pin_size, ycen - draw_coords->pin_size},
2133+
{xcen + draw_coords->pin_size, ycen + draw_coords->pin_size});
2134+
sprintf(str, "%d", ipin);
2135+
g->set_color(ezgl::BLACK);
2136+
g->draw_text({xcen, ycen}, str, 2 * draw_coords->pin_size, 2 * draw_coords->pin_size);
2137+
g->set_color(color);
2138+
}
21312139
}
21322140

21332141
/* Returns the coordinates at which the center of this pin should be drawn. *
21342142
* inode gives the node number, and iside gives the side of the clb or pad *
21352143
* the physical pin is on. */
2136-
void draw_get_rr_pin_coords(int inode, float* xcen, float* ycen) {
2144+
void draw_get_rr_pin_coords(int inode, float* xcen, float* ycen, const e_side& pin_side) {
21372145
auto& device_ctx = g_vpr_ctx.device();
2138-
draw_get_rr_pin_coords(device_ctx.rr_nodes[inode], xcen, ycen);
2146+
draw_get_rr_pin_coords(device_ctx.rr_nodes[inode], xcen, ycen, pin_side);
21392147
}
21402148

2141-
void draw_get_rr_pin_coords(const t_rr_node& node, float* xcen, float* ycen) {
2149+
void draw_get_rr_pin_coords(const t_rr_node& node, float* xcen, float* ycen, const e_side& pin_side) {
21422150
t_draw_coords* draw_coords = get_draw_coords_vars();
21432151

21442152
int i, j, k, ipin, pins_per_sub_tile;
@@ -2164,7 +2172,7 @@ void draw_get_rr_pin_coords(const t_rr_node& node, float* xcen, float* ycen) {
21642172
step = (float)(draw_coords->get_tile_width()) / (float)(type->num_pins + type->capacity);
21652173
offset = (ipin + k + 1) * step;
21662174

2167-
switch (node.side()) {
2175+
switch (pin_side) {
21682176
case LEFT:
21692177
yc += offset;
21702178
break;
@@ -2185,7 +2193,8 @@ void draw_get_rr_pin_coords(const t_rr_node& node, float* xcen, float* ycen) {
21852193

21862194
default:
21872195
vpr_throw(VPR_ERROR_OTHER, __FILE__, __LINE__,
2188-
"in draw_get_rr_pin_coords: Unexpected side %s.\n", node.side_string());
2196+
"in draw_get_rr_pin_coords: Unexpected side %s.\n",
2197+
SIDE_STRING[pin_side]);
21892198
break;
21902199
}
21912200

@@ -2588,11 +2597,10 @@ static int draw_check_rr_node_hit(float click_x, float click_y) {
25882597
int height_offset = device_ctx.grid[i][j].height_offset;
25892598
int ipin = device_ctx.rr_nodes[inode].ptc_num();
25902599
float xcen, ycen;
2591-
int iside;
2592-
for (iside = 0; iside < 4; iside++) {
2600+
for (const e_side& iside : SIDES) {
25932601
// If pin exists on this side of the block, then get pin coordinates
2594-
if (type->pinloc[width_offset][height_offset][iside][ipin]) {
2595-
draw_get_rr_pin_coords(inode, &xcen, &ycen);
2602+
if (type->pinloc[width_offset][height_offset][size_t(iside)][ipin]) {
2603+
draw_get_rr_pin_coords(inode, &xcen, &ycen, iside);
25962604

25972605
// Now check if we clicked on this pin
25982606
if (click_x >= xcen - draw_coords->pin_size && click_x <= xcen + draw_coords->pin_size && click_y >= ycen - draw_coords->pin_size && click_y <= ycen + draw_coords->pin_size) {
@@ -2955,19 +2963,108 @@ static void draw_pin_to_chan_edge(int pin_node, int chan_node, ezgl::renderer* g
29552963

29562964
const t_grid_tile& grid_tile = device_ctx.grid[pin_rr.xlow()][pin_rr.ylow()];
29572965
t_physical_tile_type_ptr grid_type = grid_tile.type;
2958-
VTR_ASSERT_MSG(grid_type->pinloc[grid_tile.width_offset][grid_tile.height_offset][pin_rr.side()][pin_rr.pin_num()],
2959-
"Pin coordinates should match block type pin locations");
29602966

2967+
float x1 = 0, y1 = 0;
2968+
/* If there is only one side, no need for the following inference!!!
2969+
* When a node may have multiple sides,
2970+
* we lack direct information about which side of the node drives the channel node
2971+
* However, we can infer which side is actually used by the driver based on the
2972+
* coordinates of the channel node.
2973+
* In principle, in a regular rr_graph that can pass check_rr_graph() function,
2974+
* the coordinates should follow the illustration:
2975+
*
2976+
* +----------+
2977+
* | CHANX |
2978+
* | [x][y] |
2979+
* +----------+
2980+
* +----------+ +----------+ +--------+
2981+
* | | | | | |
2982+
* | CHANY | | Grid | | CHANY |
2983+
* | [x-1][y] | | [x][y] | | [x][y] |
2984+
* | | | | | |
2985+
* +----------+ +----------+ +--------+
2986+
* +----------+
2987+
* | CHANX |
2988+
* | [x][y-1] |
2989+
* +----------+
2990+
*
2991+
*
2992+
* Therefore, when there are multiple side:
2993+
* - a TOP side node is considered when the ylow of CHANX >= ylow of the node
2994+
* - a BOTTOM side node is considered when the ylow of CHANX <= ylow - 1 of the node
2995+
* - a RIGHT side node is considered when the xlow of CHANY >= xlow of the node
2996+
* - a LEFT side node is considered when the xlow of CHANY <= xlow - 1 of the node
2997+
*
2998+
* Note: ylow == yhigh for CHANX and xlow == xhigh for CHANY
2999+
*
3000+
* Note: Similar rules are applied for grid that has width > 1 and height > 1
3001+
* This is because (xlow, ylow) or (xhigh, yhigh) of the node follows
3002+
* the actual offset of the pin in the context of grid width and height
3003+
*/
3004+
std::vector<e_side> pin_candidate_sides;
3005+
for (const e_side& pin_candidate_side : SIDES) {
3006+
if ((pin_rr.is_node_on_specific_side(pin_candidate_side))
3007+
&& (grid_type->pinloc[grid_tile.width_offset][grid_tile.height_offset][pin_candidate_side][pin_rr.pin_num()])) {
3008+
pin_candidate_sides.push_back(pin_candidate_side);
3009+
}
3010+
}
3011+
/* Only 1 side will be picked in the end
3012+
* Any rr_node of a grid should have at least 1 side!!!
3013+
*/
3014+
e_side pin_side = NUM_SIDES;
3015+
if (1 == pin_candidate_sides.size()) {
3016+
pin_side = pin_candidate_sides[0];
3017+
} else {
3018+
VTR_ASSERT(1 < pin_candidate_sides.size());
3019+
if (CHANX == chan_rr.type() && pin_rr.ylow() <= chan_rr.ylow()) {
3020+
pin_side = TOP;
3021+
} else if (CHANX == chan_rr.type() && pin_rr.ylow() - 1 >= chan_rr.ylow()) {
3022+
pin_side = BOTTOM;
3023+
} else if (CHANY == chan_rr.type() && pin_rr.xlow() <= chan_rr.xlow()) {
3024+
pin_side = RIGHT;
3025+
} else if (CHANY == chan_rr.type() && pin_rr.xlow() - 1 >= chan_rr.xlow()) {
3026+
pin_side = LEFT;
3027+
}
3028+
/* The inferred side must be in the list of sides of the pin rr_node!!! */
3029+
VTR_ASSERT(pin_candidate_sides.end() != std::find(pin_candidate_sides.begin(), pin_candidate_sides.end(), pin_side));
3030+
}
3031+
/* Sanity check */
3032+
VTR_ASSERT(NUM_SIDES != pin_side);
3033+
3034+
/* Now we determine which side to be used, calculate the offset for the pin to be drawn
3035+
* - For the pin locates above/right to the grid (at the top/right side),
3036+
* a positive offset (+ve) is required
3037+
* - For the pin locates below/left to the grid (at the bottom/left side),
3038+
* a negative offset (-ve) is required
3039+
*
3040+
* y
3041+
* ^ +-----+ ---
3042+
* | | PIN | ^
3043+
* | | | offset
3044+
* | | | v
3045+
* | +-----------+-----+----------+
3046+
* | | |<- offset ->|
3047+
* | |<-offset->| +------------+
3048+
* | +----------+ Grid | PIN |
3049+
* | | PIN | +------------+
3050+
* | +----------+ |
3051+
* | | |
3052+
* | +---+-----+------------------+
3053+
* | ^ | |
3054+
* | offset | PIN |
3055+
* | v | |
3056+
* | ----+-----+
3057+
* +------------------------------------------------------------>x
3058+
*/
29613059
float draw_pin_offset;
2962-
if (pin_rr.side() == TOP || pin_rr.side() == RIGHT) {
3060+
if (TOP == pin_side || RIGHT == pin_side) {
29633061
draw_pin_offset = draw_coords->pin_size;
29643062
} else {
2965-
VTR_ASSERT(pin_rr.side() == BOTTOM || pin_rr.side() == LEFT);
3063+
VTR_ASSERT(BOTTOM == pin_side || LEFT == pin_side);
29663064
draw_pin_offset = -draw_coords->pin_size;
29673065
}
29683066

2969-
float x1 = 0, y1 = 0;
2970-
draw_get_rr_pin_coords(pin_node, &x1, &y1);
3067+
draw_get_rr_pin_coords(pin_node, &x1, &y1, pin_side);
29713068

29723069
ezgl::rectangle chan_bbox = draw_get_rr_chan_bbox(chan_node);
29733070

@@ -3022,11 +3119,30 @@ static void draw_pin_to_pin(int opin_node, int ipin_node, ezgl::renderer* g) {
30223119
VTR_ASSERT(device_ctx.rr_nodes[opin_node].type() == OPIN);
30233120
VTR_ASSERT(device_ctx.rr_nodes[ipin_node].type() == IPIN);
30243121

3122+
/* FIXME: May use a smarter strategy
3123+
* Currently, we use the last side found for both OPIN and IPIN
3124+
* when draw the direct connection between the two nodes
3125+
* Note: tried first side but see missing connections
3126+
*/
30253127
float x1 = 0, y1 = 0;
3026-
draw_get_rr_pin_coords(opin_node, &x1, &y1);
3128+
std::vector<e_side> opin_candidate_sides;
3129+
for (const e_side& opin_candidate_side : SIDES) {
3130+
if (device_ctx.rr_nodes[opin_node].is_node_on_specific_side(opin_candidate_side)) {
3131+
opin_candidate_sides.push_back(opin_candidate_side);
3132+
}
3133+
}
3134+
VTR_ASSERT(1 <= opin_candidate_sides.size());
3135+
draw_get_rr_pin_coords(opin_node, &x1, &y1, opin_candidate_sides.back());
30273136

30283137
float x2 = 0, y2 = 0;
3029-
draw_get_rr_pin_coords(ipin_node, &x2, &y2);
3138+
std::vector<e_side> ipin_candidate_sides;
3139+
for (const e_side& ipin_candidate_side : SIDES) {
3140+
if (device_ctx.rr_nodes[ipin_node].is_node_on_specific_side(ipin_candidate_side)) {
3141+
ipin_candidate_sides.push_back(ipin_candidate_side);
3142+
}
3143+
}
3144+
VTR_ASSERT(1 <= ipin_candidate_sides.size());
3145+
draw_get_rr_pin_coords(ipin_node, &x2, &y2, ipin_candidate_sides.back());
30303146

30313147
g->draw_line({x1, y1}, {x2, y2});
30323148

@@ -3039,16 +3155,23 @@ static void draw_pin_to_sink(int ipin_node, int sink_node, ezgl::renderer* g) {
30393155
auto& device_ctx = g_vpr_ctx.device();
30403156

30413157
float x1 = 0, y1 = 0;
3042-
draw_get_rr_pin_coords(ipin_node, &x1, &y1);
3158+
/* Draw the line for each ipin on different sides */
3159+
for (const e_side& pin_side : SIDES) {
3160+
if (!device_ctx.rr_nodes[ipin_node].is_node_on_specific_side(pin_side)) {
3161+
continue;
3162+
}
30433163

3044-
float x2 = 0, y2 = 0;
3045-
draw_get_rr_src_sink_coords(device_ctx.rr_nodes[sink_node], &x2, &y2);
3164+
draw_get_rr_pin_coords(ipin_node, &x1, &y1, pin_side);
30463165

3047-
g->draw_line({x1, y1}, {x2, y2});
3166+
float x2 = 0, y2 = 0;
3167+
draw_get_rr_src_sink_coords(device_ctx.rr_nodes[sink_node], &x2, &y2);
30483168

3049-
float xend = x2 + (x1 - x2) / 10.;
3050-
float yend = y2 + (y1 - y2) / 10.;
3051-
draw_triangle_along_line(g, xend, yend, x1, x2, y1, y2);
3169+
g->draw_line({x1, y1}, {x2, y2});
3170+
3171+
float xend = x2 + (x1 - x2) / 10.;
3172+
float yend = y2 + (y1 - y2) / 10.;
3173+
draw_triangle_along_line(g, xend, yend, x1, x2, y1, y2);
3174+
}
30523175
}
30533176

30543177
static void draw_source_to_pin(int source_node, int opin_node, ezgl::renderer* g) {
@@ -3057,14 +3180,21 @@ static void draw_source_to_pin(int source_node, int opin_node, ezgl::renderer* g
30573180
float x1 = 0, y1 = 0;
30583181
draw_get_rr_src_sink_coords(device_ctx.rr_nodes[source_node], &x1, &y1);
30593182

3060-
float x2 = 0, y2 = 0;
3061-
draw_get_rr_pin_coords(opin_node, &x2, &y2);
3183+
/* Draw the line for each ipin on different sides */
3184+
for (const e_side& pin_side : SIDES) {
3185+
if (!device_ctx.rr_nodes[opin_node].is_node_on_specific_side(pin_side)) {
3186+
continue;
3187+
}
30623188

3063-
g->draw_line({x1, y1}, {x2, y2});
3189+
float x2 = 0, y2 = 0;
3190+
draw_get_rr_pin_coords(opin_node, &x2, &y2, pin_side);
30643191

3065-
float xend = x2 + (x1 - x2) / 10.;
3066-
float yend = y2 + (y1 - y2) / 10.;
3067-
draw_triangle_along_line(g, xend, yend, x1, x2, y1, y2);
3192+
g->draw_line({x1, y1}, {x2, y2});
3193+
3194+
float xend = x2 + (x1 - x2) / 10.;
3195+
float yend = y2 + (y1 - y2) / 10.;
3196+
draw_triangle_along_line(g, xend, yend, x1, x2, y1, y2);
3197+
}
30683198
}
30693199

30703200
static inline void draw_mux_with_size(ezgl::point2d origin, e_side orientation, float height, int size, ezgl::renderer* g) {

vpr/src/draw/draw.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,8 @@ void free_draw_structs();
3232

3333
#ifndef NO_GRAPHICS
3434

35-
void draw_get_rr_pin_coords(int inode, float* xcen, float* ycen);
36-
void draw_get_rr_pin_coords(const t_rr_node& node, float* xcen, float* ycen);
35+
void draw_get_rr_pin_coords(int inode, float* xcen, float* ycen, const e_side& pin_side);
36+
void draw_get_rr_pin_coords(const t_rr_node& node, float* xcen, float* ycen, const e_side& pin_side);
3737

3838
void draw_triangle_along_line(ezgl::renderer* g, ezgl::point2d start, ezgl::point2d end, float relative_position = 1., float arrow_size = DEFAULT_ARROW_SIZE);
3939
void draw_triangle_along_line(ezgl::renderer* g, ezgl::point2d loc, ezgl::point2d start, ezgl::point2d end, float arrow_size = DEFAULT_ARROW_SIZE);

vpr/src/draw/search_bar.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -194,10 +194,9 @@ void auto_zoom_rr_node(int rr_node_id) {
194194
int ipin = device_ctx.rr_nodes[rr_node_id].ptc_num();
195195
float xcen, ycen;
196196

197-
int iside;
198-
for (iside = 0; iside < 4; iside++) {
199-
if (type->pinloc[width_offset][height_offset][iside][ipin]) {
200-
draw_get_rr_pin_coords(rr_node_id, &xcen, &ycen);
197+
for (const e_side& iside : SIDES) {
198+
if (type->pinloc[width_offset][height_offset][size_t(iside)][ipin]) {
199+
draw_get_rr_pin_coords(rr_node_id, &xcen, &ycen, iside);
201200
rr_node = {{xcen - draw_coords->pin_size, ycen - draw_coords->pin_size},
202201
{xcen + draw_coords->pin_size, ycen + draw_coords->pin_size}};
203202
}

0 commit comments

Comments
 (0)