|
| 1 | +#include <cstddef> |
| 2 | +#include <vector> |
| 3 | +#include <algorithm> |
| 4 | +#include <ranges> |
| 5 | + |
| 6 | +#include "device_grid.h" |
| 7 | +#include "rr_graph_builder.h" |
| 8 | +#include "rr_graph_fwd.h" |
| 9 | +#include "rr_graph_view.h" |
| 10 | +#include "rr_node_types.h" |
| 11 | +#include "rr_spatial_lookup.h" |
| 12 | +#include "vtr_assert.h" |
| 13 | +#include "vtr_log.h" |
| 14 | + |
| 15 | +#include "interposer_cut.h" |
| 16 | + |
| 17 | +static bool should_cut_edge(int src_start_loc, int sink_start_loc, int cut_loc) { |
| 18 | + int src_delta = src_start_loc - cut_loc; |
| 19 | + int sink_delta = sink_start_loc - cut_loc; |
| 20 | + |
| 21 | + // Same sign means that both sink and source are on the same side of this cut |
| 22 | + if ((src_delta < 0 && sink_delta < 0) || (src_delta >= 0 && sink_delta >= 0)) { |
| 23 | + return false; |
| 24 | + } else { |
| 25 | + return true; |
| 26 | + } |
| 27 | +} |
| 28 | + |
| 29 | +static bool should_cut_node(int src_start_loc, int sink_start_loc, int cut_loc) { |
| 30 | + int src_delta = src_start_loc - cut_loc; |
| 31 | + int sink_delta = sink_start_loc - cut_loc; |
| 32 | + |
| 33 | + // Same sign means that both sink and source are on the same side of this cut |
| 34 | + if ((src_delta <= 0 && sink_delta <= 0) || (src_delta > 0 && sink_delta > 0)) { |
| 35 | + return false; |
| 36 | + } else { |
| 37 | + return true; |
| 38 | + } |
| 39 | +} |
| 40 | + |
| 41 | +static short node_xstart(const RRGraphView& rr_graph, RRNodeId node) { |
| 42 | + // Return early for OPIN and IPIN types (Some BIDIR pins would trigger the assertion below) |
| 43 | + if (rr_graph.node_type(node) == e_rr_type::OPIN || rr_graph.node_type(node) == e_rr_type::IPIN) { |
| 44 | + VTR_ASSERT(rr_graph.node_xlow(node) == rr_graph.node_xhigh(node)); |
| 45 | + return rr_graph.node_xlow(node); |
| 46 | + } |
| 47 | + |
| 48 | + switch (rr_graph.node_direction(node)) { |
| 49 | + case Direction::DEC: |
| 50 | + return rr_graph.node_xhigh(node); |
| 51 | + break; |
| 52 | + |
| 53 | + case Direction::INC: |
| 54 | + return rr_graph.node_xlow(node); |
| 55 | + break; |
| 56 | + |
| 57 | + case Direction::NONE: |
| 58 | + VTR_ASSERT(rr_graph.node_xlow(node) == rr_graph.node_xhigh(node)); |
| 59 | + return (rr_graph.node_xlow(node)); |
| 60 | + break; |
| 61 | + |
| 62 | + case Direction::BIDIR: |
| 63 | + VTR_ASSERT_MSG(false, "Bidir node has no starting point"); |
| 64 | + break; |
| 65 | + |
| 66 | + default: |
| 67 | + VTR_ASSERT(false); |
| 68 | + break; |
| 69 | + } |
| 70 | +} |
| 71 | + |
| 72 | +static short node_ystart(const RRGraphView& rr_graph, RRNodeId node) { |
| 73 | + // Return early for OPIN and IPIN types (Some BIDIR pins would trigger the assertion below) |
| 74 | + if (rr_graph.node_type(node) == e_rr_type::OPIN || rr_graph.node_type(node) == e_rr_type::IPIN) { |
| 75 | + return rr_graph.node_ylow(node); |
| 76 | + } |
| 77 | + |
| 78 | + switch (rr_graph.node_direction(node)) { |
| 79 | + case Direction::DEC: |
| 80 | + return rr_graph.node_yhigh(node); |
| 81 | + break; |
| 82 | + |
| 83 | + case Direction::INC: |
| 84 | + return rr_graph.node_ylow(node); |
| 85 | + break; |
| 86 | + |
| 87 | + case Direction::NONE: |
| 88 | + VTR_ASSERT(rr_graph.node_ylow(node) == rr_graph.node_yhigh(node)); |
| 89 | + return (rr_graph.node_ylow(node)); |
| 90 | + break; |
| 91 | + |
| 92 | + case Direction::BIDIR: |
| 93 | + VTR_ASSERT_MSG(false, "Bidir node has no starting point"); |
| 94 | + break; |
| 95 | + |
| 96 | + default: |
| 97 | + VTR_ASSERT(false); |
| 98 | + break; |
| 99 | + } |
| 100 | +} |
| 101 | + |
| 102 | +std::vector<RREdgeId> mark_interposer_cut_edges_for_removal(const RRGraphView& rr_graph, const DeviceGrid& grid) { |
| 103 | + std::vector<RREdgeId> edges_to_be_removed; |
| 104 | + |
| 105 | + // Loop over all RREdgeIds and mark ones that cross a cutline to be removed |
| 106 | + |
| 107 | + for (RREdgeId edge_id : rr_graph.all_edges()) { |
| 108 | + RRNodeId src_node = rr_graph.edge_src_node(edge_id); |
| 109 | + RRNodeId sink_node = rr_graph.edge_sink_node(edge_id); |
| 110 | + |
| 111 | + if (src_node == RRNodeId(5866) && sink_node == RRNodeId(5604)) { |
| 112 | + VTR_LOG("HI\n"); |
| 113 | + } |
| 114 | + |
| 115 | + // TODO: ignoring chanz nodes for now |
| 116 | + if (rr_graph.node_type(src_node) == e_rr_type::CHANZ || rr_graph.node_type(sink_node) == e_rr_type::CHANZ) { |
| 117 | + continue; |
| 118 | + } |
| 119 | + |
| 120 | + VTR_ASSERT(rr_graph.node_layer_low(src_node) == rr_graph.node_layer_low(sink_node)); |
| 121 | + VTR_ASSERT(rr_graph.node_layer_low(src_node) == rr_graph.node_layer_high(src_node)); |
| 122 | + VTR_ASSERT(rr_graph.node_layer_low(sink_node) == rr_graph.node_layer_high(sink_node)); |
| 123 | + |
| 124 | + int layer = rr_graph.node_layer_low(src_node); |
| 125 | + |
| 126 | + for (int cut_loc_y : grid.get_horizontal_interposer_cuts()[layer]) { |
| 127 | + int src_start_loc_y = node_ystart(rr_graph, src_node); |
| 128 | + int sink_start_loc_y = node_ystart(rr_graph, sink_node); |
| 129 | + |
| 130 | + if (should_cut_edge(src_start_loc_y, sink_start_loc_y, cut_loc_y)) { |
| 131 | + edges_to_be_removed.push_back(edge_id); |
| 132 | + } |
| 133 | + } |
| 134 | + |
| 135 | + for (int cut_loc_x : grid.get_vertical_interposer_cuts()[layer]) { |
| 136 | + int src_start_loc_x = node_xstart(rr_graph, src_node); |
| 137 | + int sink_start_loc_x = node_xstart(rr_graph, sink_node); |
| 138 | + |
| 139 | + if (should_cut_edge(src_start_loc_x, sink_start_loc_x, cut_loc_x)) { |
| 140 | + edges_to_be_removed.push_back(edge_id); |
| 141 | + } |
| 142 | + } |
| 143 | + } |
| 144 | + |
| 145 | + return edges_to_be_removed; |
| 146 | +} |
| 147 | + |
| 148 | +// TODO: workshop a better name |
| 149 | +void update_interposer_crossing_nodes_in_spatial_lookup_and_rr_graph_storage(const RRGraphView& rr_graph, const DeviceGrid& grid, RRGraphBuilder& rr_graph_builder, const std::vector<std::pair<RRNodeId, int>>& sg_node_indices) { |
| 150 | + VTR_ASSERT(std::is_sorted(sg_node_indices.begin(), sg_node_indices.end())); |
| 151 | + |
| 152 | + RRSpatialLookup& spatial_lookup = rr_graph_builder.node_lookup(); |
| 153 | + size_t num_sg = 0; |
| 154 | + for (size_t layer = 0; layer < grid.get_num_layers(); layer++) { |
| 155 | + for (int cut_loc_y : grid.get_horizontal_interposer_cuts()[layer]) { |
| 156 | + for (size_t x_loc = 0; x_loc < grid.width(); x_loc++) { |
| 157 | + std::vector<RRNodeId> channel_nodes = spatial_lookup.find_channel_nodes(layer, x_loc, cut_loc_y, e_rr_type::CHANY); |
| 158 | + for (RRNodeId node : channel_nodes) { |
| 159 | + |
| 160 | + bool is_sg_node = std::ranges::binary_search(std::views::keys(sg_node_indices), node, [](RRNodeId l, RRNodeId r) {return size_t(l) < size_t(r);}); |
| 161 | + if (is_sg_node) { |
| 162 | + num_sg++; |
| 163 | + continue; |
| 164 | + } |
| 165 | + |
| 166 | + |
| 167 | + int x_high = rr_graph.node_xhigh(node); |
| 168 | + int x_low = rr_graph.node_xlow(node); |
| 169 | + VTR_ASSERT(x_high == x_low); |
| 170 | + int y_high = rr_graph.node_yhigh(node); |
| 171 | + int y_low = rr_graph.node_ylow(node); |
| 172 | + int ptc_num = rr_graph.node_ptc_num(node); |
| 173 | + |
| 174 | + |
| 175 | + // No need to cut 1-length wires |
| 176 | + if (y_high == y_low) { |
| 177 | + continue; |
| 178 | + } |
| 179 | + |
| 180 | + if (!should_cut_node(y_low, y_high, cut_loc_y)) { |
| 181 | + continue; |
| 182 | + } |
| 183 | + |
| 184 | + if (rr_graph.node_direction(node) == Direction::INC) { |
| 185 | + // Anything above cut_loc_y shouldn't exist |
| 186 | + rr_graph_builder.set_node_coordinates(node, x_low, y_low, x_high, cut_loc_y); |
| 187 | + |
| 188 | + // Do a loop from cut_loc_y to y_high and remove node from spatial lookup |
| 189 | + for (int y_loc = cut_loc_y + 1; y_loc <= y_high; y_loc++) { |
| 190 | + spatial_lookup.remove_node(node, layer, x_low, y_loc, e_rr_type::CHANY, ptc_num); |
| 191 | + } |
| 192 | + } else if (rr_graph.node_direction(node) == Direction::DEC) { |
| 193 | + // Anything below cut_loc_y shouldn't exist |
| 194 | + rr_graph_builder.set_node_coordinates(node, x_low, cut_loc_y + 1, x_high, y_high); |
| 195 | + |
| 196 | + // Do a loop from y_low to cut_loc_y and remove node from spatial lookup |
| 197 | + for (int y_loc = y_low; y_loc <= cut_loc_y; y_loc++) { |
| 198 | + spatial_lookup.remove_node(node, layer, x_low, y_loc, e_rr_type::CHANY, ptc_num); |
| 199 | + } |
| 200 | + } |
| 201 | + } |
| 202 | + } |
| 203 | + } |
| 204 | + } |
| 205 | +} |
0 commit comments