|
15 | 15 | #include <cstdio> |
16 | 16 | #include <cstring> |
17 | 17 | #include <cmath> |
| 18 | +#include <vector> |
18 | 19 | #include "draw.h" |
19 | 20 |
|
20 | 21 | #include "draw_interposer.h" |
21 | 22 | #include "draw_types.h" |
| 23 | +#include "rr_graph_fwd.h" |
| 24 | +#include "rr_node_types.h" |
22 | 25 | #include "timing_info.h" |
23 | 26 | #include "physical_types.h" |
24 | 27 |
|
@@ -493,17 +496,51 @@ void init_draw_coords(float clb_width, const BlkLocRegistry& blk_loc_registry) { |
493 | 496 | } |
494 | 497 | } |
495 | 498 |
|
| 499 | + std::vector<int> max_chanx_ptc_nums(grid.height() - 1); |
| 500 | + std::vector<int> max_chany_ptc_nums(grid.width() - 1); |
| 501 | + |
| 502 | + // Normally you could use device_ctx.rr_chany_width to get the device's channel width but in some cases |
| 503 | + // like devices with interposer cuts, you have situations where there are 100 segments in a channel, |
| 504 | + // but the maximum ptc_num is 120. If we only reserve enough space for 100 segments, the segments with |
| 505 | + // ptc_num > 100 would be drawn over the tiles. This loop explicitly calculates the maximum ptc_num in |
| 506 | + // each routing row/column to avoid that issue. |
| 507 | + for (size_t x_loc = 0; x_loc < grid.width() - 1; x_loc++) { |
| 508 | + for (size_t y_loc = 0; y_loc < grid.height() - 1; y_loc++) { |
| 509 | + |
| 510 | + // Get all chanx nodes at location (x_loc, y_loc), find largest ptc_num accross all nodes |
| 511 | + std::vector<RRNodeId> chanx_nodes = rr_graph.node_lookup().find_channel_nodes(0, x_loc, y_loc, e_rr_type::CHANX); |
| 512 | + int max_chanx_ptc_num = 0; |
| 513 | + if (!chanx_nodes.empty()) { |
| 514 | + // Must explicitly check for emptiness, since std::ranges::max will crash if chanx_nodes is empty |
| 515 | + RRNodeId max_chanx_ptc_node = std::ranges::max(chanx_nodes, {}, [&rr_graph](RRNodeId node) { return rr_graph.node_ptc_num(node); }); |
| 516 | + max_chanx_ptc_num= rr_graph.node_ptc_num(max_chanx_ptc_node); |
| 517 | + } |
| 518 | + |
| 519 | + // Do the same for chany |
| 520 | + std::vector<RRNodeId> chany_nodes = rr_graph.node_lookup().find_channel_nodes(0, x_loc, y_loc, e_rr_type::CHANY); |
| 521 | + int max_chany_ptc_num = 0; |
| 522 | + if (!chany_nodes.empty()) { |
| 523 | + RRNodeId max_chany_ptc_node = std::ranges::max(chany_nodes, {}, [&rr_graph](RRNodeId node) { return rr_graph.node_ptc_num(node); }); |
| 524 | + max_chany_ptc_num = rr_graph.node_ptc_num(max_chany_ptc_node); |
| 525 | + } |
| 526 | + |
| 527 | + // Update maximum ptc_num for each routing channel row/column |
| 528 | + max_chany_ptc_nums[x_loc] = std::max(max_chany_ptc_num, max_chany_ptc_nums[x_loc]); |
| 529 | + max_chanx_ptc_nums[y_loc] = std::max(max_chanx_ptc_num, max_chanx_ptc_nums[y_loc]); |
| 530 | + } |
| 531 | + } |
| 532 | + |
496 | 533 | size_t j = 0; |
497 | 534 | for (size_t i = 0; i < grid.width() - 1; i++) { |
498 | 535 | draw_coords->tile_x[i] = i * draw_coords->get_tile_width() + j; |
499 | | - j += device_ctx.rr_chany_width[i] + 1; // N wires need N+1 units of space |
| 536 | + j += max_chany_ptc_nums[i] + 1; // N wires need N+1 units of space |
500 | 537 | } |
501 | 538 | draw_coords->tile_x[grid.width() - 1] = (grid.width() - 1) * draw_coords->get_tile_width() + j; |
502 | 539 |
|
503 | 540 | j = 0; |
504 | 541 | for (size_t i = 0; i < grid.height() - 1; ++i) { |
505 | 542 | draw_coords->tile_y[i] = i * draw_coords->get_tile_width() + j; |
506 | | - j += device_ctx.rr_chanx_width[i] + 1; |
| 543 | + j += max_chanx_ptc_nums[i] + 1; |
507 | 544 | } |
508 | 545 | draw_coords->tile_y[grid.height() - 1] = (grid.height() - 1) * draw_coords->get_tile_width() + j; |
509 | 546 |
|
|
0 commit comments