diff --git a/vpr/src/route/check_rr_graph.cpp b/vpr/src/route/check_rr_graph.cpp index cf389736e03..933caf25c91 100644 --- a/vpr/src/route/check_rr_graph.cpp +++ b/vpr/src/route/check_rr_graph.cpp @@ -237,8 +237,14 @@ void check_rr_graph(const t_graph_type graph_type, if (has_adjacent_channel(node, device_ctx.grid)) { auto block_type = device_ctx.grid[node.xlow()][node.ylow()].type; std::string pin_name = block_type_pin_index_to_name(block_type, node.pin_num()); - VTR_LOG_ERROR("in check_rr_graph: node %d (%s) at (%d,%d) block=%s side=%s pin=%s has no fanin.\n", - inode, node.type_string(), node.xlow(), node.ylow(), block_type->name, node.side_string(), pin_name.c_str()); + /* Print error messages for all the sides that a node may appear */ + for (const e_side& node_side : SIDES) { + if (!node.is_node_on_specific_side(node_side)) { + continue; + } + VTR_LOG_ERROR("in check_rr_graph: node %d (%s) at (%d,%d) block=%s side=%s pin=%s has no fanin.\n", + inode, node.type_string(), node.xlow(), node.ylow(), block_type->name, SIDE_STRING[node_side], pin_name.c_str()); + } } } else { VTR_LOG_ERROR("in check_rr_graph: node %d (%s) has no fanin.\n", diff --git a/vpr/src/route/rr_graph.cpp b/vpr/src/route/rr_graph.cpp index b98103cf2c0..75c18fcd3cc 100644 --- a/vpr/src/route/rr_graph.cpp +++ b/vpr/src/route/rr_graph.cpp @@ -1499,13 +1499,8 @@ static void build_rr_sinks_sources(const int i, L_rr_node[inode].add_side(side); // Sanity check - VTR_ASSERT(1 <= L_rr_node[inode].sides().size()); - if (1 == L_rr_node[inode].sides().size()) { - VTR_ASSERT(type->pinloc[width_offset][height_offset][L_rr_node[inode].side()][L_rr_node[inode].pin_num()]); - } else { - VTR_ASSERT(L_rr_node[inode].is_node_on_specific_side(side)); - VTR_ASSERT(type->pinloc[width_offset][height_offset][side][L_rr_node[inode].pin_num()]); - } + VTR_ASSERT(L_rr_node[inode].is_node_on_specific_side(side)); + VTR_ASSERT(type->pinloc[width_offset][height_offset][side][L_rr_node[inode].pin_num()]); } } } @@ -2922,39 +2917,50 @@ static int pick_best_direct_connect_target_rr_node(const t_rr_graph_storage& rr_ //This function attempts to pick the 'best/closest' of the candidates. VTR_ASSERT(rr_nodes[from_rr].type() == OPIN); - e_side from_side = rr_nodes[from_rr].side(); float best_dist = std::numeric_limits::infinity(); int best_rr = OPEN; - for (int to_rr : candidate_rr_nodes) { - VTR_ASSERT(rr_nodes[to_rr].type() == IPIN); - float to_dist = std::abs(rr_nodes[from_rr].xlow() - rr_nodes[to_rr].xlow()) - + std::abs(rr_nodes[from_rr].ylow() - rr_nodes[to_rr].ylow()); - - e_side to_side = rr_nodes[to_rr].side(); - - //Include a partial unit of distance based on side alignment to ensure - //we preferr facing sides - if ((from_side == RIGHT && to_side == LEFT) - || (from_side == LEFT && to_side == RIGHT) - || (from_side == TOP && to_side == BOTTOM) - || (from_side == BOTTOM && to_side == TOP)) { - //Facing sides - to_dist += 0.25; - } else if (((from_side == RIGHT || from_side == LEFT) && (to_side == TOP || to_side == BOTTOM)) - || ((from_side == TOP || from_side == BOTTOM) && (to_side == RIGHT || to_side == LEFT))) { - //Perpendicular sides - to_dist += 0.5; - - } else { - //Opposite sides - to_dist += 0.75; + for (const e_side& from_side : SIDES) { + /* Bypass those side where the node does not appear */ + if (!rr_nodes[from_rr].is_node_on_specific_side(from_side)) { + continue; } - if (to_dist < best_dist) { - best_dist = to_dist; - best_rr = to_rr; + for (int to_rr : candidate_rr_nodes) { + VTR_ASSERT(rr_nodes[to_rr].type() == IPIN); + float to_dist = std::abs(rr_nodes[from_rr].xlow() - rr_nodes[to_rr].xlow()) + + std::abs(rr_nodes[from_rr].ylow() - rr_nodes[to_rr].ylow()); + + for (const e_side& to_side : SIDES) { + /* Bypass those side where the node does not appear */ + if (!rr_nodes[to_rr].is_node_on_specific_side(to_side)) { + continue; + } + + //Include a partial unit of distance based on side alignment to ensure + //we preferr facing sides + if ((from_side == RIGHT && to_side == LEFT) + || (from_side == LEFT && to_side == RIGHT) + || (from_side == TOP && to_side == BOTTOM) + || (from_side == BOTTOM && to_side == TOP)) { + //Facing sides + to_dist += 0.25; + } else if (((from_side == RIGHT || from_side == LEFT) && (to_side == TOP || to_side == BOTTOM)) + || ((from_side == TOP || from_side == BOTTOM) && (to_side == RIGHT || to_side == LEFT))) { + //Perpendicular sides + to_dist += 0.5; + + } else { + //Opposite sides + to_dist += 0.75; + } + + if (to_dist < best_dist) { + best_dist = to_dist; + best_rr = to_rr; + } + } } } diff --git a/vpr/src/route/rr_graph_storage.cpp b/vpr/src/route/rr_graph_storage.cpp index bc0ccc8b866..95242187c94 100644 --- a/vpr/src/route/rr_graph_storage.cpp +++ b/vpr/src/route/rr_graph_storage.cpp @@ -565,7 +565,13 @@ const char* t_rr_graph_storage::node_direction_string(RRNodeId id) const { } const char* t_rr_graph_storage::node_side_string(RRNodeId id) const { - return SIDE_STRING[node_side(id)]; + for (const e_side& side : SIDES) { + if (is_node_on_specific_side(id, side)) { + return SIDE_STRING[side]; + } + } + /* Not found, return an invalid string*/ + return SIDE_STRING[NUM_SIDES]; } float t_rr_graph_storage::node_R(RRNodeId id) const { @@ -707,39 +713,6 @@ void t_rr_graph_storage::set_node_direction(RRNodeId id, e_direction new_directi node_storage_[id].dir_side_.direction = new_direction; } -void t_rr_graph_storage::set_node_side(RRNodeId id, e_side new_side) { - if (node_type(id) != IPIN && node_type(id) != OPIN) { - VPR_FATAL_ERROR(VPR_ERROR_ROUTE, "Attempted to set RR node 'side' for non-channel type '%s'", node_type_string(id)); - } - std::bitset side_bits; - /* The new side will overwrite existing side storage */ - side_bits[size_t(new_side)] = true; - if (side_bits.to_ulong() > CHAR_MAX) { - VPR_FATAL_ERROR(VPR_ERROR_ROUTE, "Invalid side '%s' to be added to rr node %u", SIDE_STRING[new_side], size_t(id)); - } - node_storage_[id].dir_side_.sides = static_cast(side_bits.to_ulong()); -} - -void t_rr_graph_storage::set_node_sides(RRNodeId id, std::bitset new_sides) { - if (node_type(id) != IPIN && node_type(id) != OPIN) { - VPR_FATAL_ERROR(VPR_ERROR_ROUTE, "Attempted to set RR node 'side' for non-channel type '%s'", node_type_string(id)); - } - /* The new sides will overwrite existing side storage */ - if (new_sides.to_ulong() > CHAR_MAX) { - std::string new_sides_str; - for (const e_side& side : SIDES) { - if (new_sides[side]) { - if (!new_sides_str.empty()) { - new_sides_str.append(", "); - } - new_sides_str.append(SIDE_STRING[side]); - } - } - VPR_FATAL_ERROR(VPR_ERROR_ROUTE, "Invalid sides '%s' to be added to rr node %u", new_sides_str.c_str(), size_t(id)); - } - node_storage_[id].dir_side_.sides = static_cast(new_sides.to_ulong()); -} - void t_rr_graph_storage::add_node_side(RRNodeId id, e_side new_side) { if (node_type(id) != IPIN && node_type(id) != OPIN) { VPR_FATAL_ERROR(VPR_ERROR_ROUTE, "Attempted to set RR node 'side' for non-channel type '%s'", node_type_string(id)); diff --git a/vpr/src/route/rr_graph_storage.h b/vpr/src/route/rr_graph_storage.h index 647deebf777..b3a72d3a8a6 100644 --- a/vpr/src/route/rr_graph_storage.h +++ b/vpr/src/route/rr_graph_storage.h @@ -197,41 +197,6 @@ class t_rr_graph_storage { } const char* node_direction_string(RRNodeId id) const; - /* THIS FUNCTION IS GOING TO BE DEPRECATED - * Return the first valid side for the node - */ - e_side node_side(RRNodeId id) const { - return get_node_side( - vtr::array_view_id( - node_storage_.data(), node_storage_.size()), - id); - } - - /* Return a bitmap for all the sides of a given node - * Currently, there are 4 sides: TOP, RIGHT, BOTTOM, LEFT - * The bit set is a 4-bit vector through which users can - * know on which sides the given nodes appear: - * For example, - * // See if the node is on TOP side - * if (true == node_sides(id)[TOP]) { - * } - * // See if the node appears ONLY on 1 side - * if (1 == node_sides(id).count()) { - * } - * - * TODO: This function may be deprecated, depending its utilization - * in client functions, router, GUI etc. It offers a shortcut - * for developers who can check what sides a node appear on. - * However, such query can be done outside RRGraph by iterating - * over all the sides and using API is_node_on_specific_side() - */ - std::bitset node_sides(RRNodeId id) const { - return get_node_sides( - vtr::array_view_id( - node_storage_.data(), node_storage_.size()), - id); - } - /* Find if the given node appears on a specific side */ bool is_node_on_specific_side(RRNodeId id, e_side side) const { return is_node_on_specific_side( @@ -240,6 +205,13 @@ class t_rr_graph_storage { id, side); } + /* FIXME: This function should be DEPRECATED! + * Developers can easily use the following codes with more flexibility + * + * if (rr_graph.is_node_on_specific_side(id, side)) { + * const char* side_string = SIDE_STRING[side]; + * } + */ const char* node_side_string(RRNodeId id) const; /* PTC get methods */ @@ -505,13 +477,6 @@ class t_rr_graph_storage { void set_node_capacity(RRNodeId, short new_capacity); void set_node_direction(RRNodeId, e_direction new_direction); - /* Set a side to the node abbributes - * Note that this function will overwrite any existing side attributes - * If the node has multiple sides, you should use the method set_node_sides() - */ - void set_node_side(RRNodeId, e_side new_side); - /* Set multiple sides to the node abbributes */ - void set_node_sides(RRNodeId, std::bitset new_side); /* Add a side to the node abbributes * This is the function to use when you just add a new side WITHOUT reseting side attributes */ @@ -635,50 +600,6 @@ class t_rr_graph_storage { return node_storage[id].dir_side_.direction; } - /** THIS FUNCTION IS GOING TO BE DEPRECATED - * Return the first valid side for the node - */ - static inline e_side get_node_side( - vtr::array_view_id node_storage, - RRNodeId id) { - auto& node_data = node_storage[id]; - if (node_data.type_ != IPIN && node_data.type_ != OPIN) { - VPR_FATAL_ERROR(VPR_ERROR_ROUTE, - "Attempted to access RR node 'side' for non-IPIN/OPIN type '%s'", - rr_node_typename[node_data.type_]); - } - std::bitset side_tt = node_storage[id].dir_side_.sides; - for (const e_side& side : SIDES) { - if (side_tt[size_t(side)]) { - return side; - } - } - /* No valid sides, return an invalid value */ - VPR_FATAL_ERROR(VPR_ERROR_ROUTE, - "Invalid side for RR node '%d':\n\ttype='%s'\txlow,ylow=(%d,%d)\n\txhigh,yhigh=(%d,%d)", - size_t(id), - rr_node_typename[node_data.type_], - node_data.xlow_, - node_data.ylow_, - node_data.xhigh_, - node_data.yhigh_); - return NUM_SIDES; - } - - static inline std::bitset get_node_sides( - vtr::array_view_id node_storage, - const RRNodeId& id) { - auto& node_data = node_storage[id]; - if (node_data.type_ != IPIN && node_data.type_ != OPIN) { - VPR_FATAL_ERROR(VPR_ERROR_ROUTE, - "Attempted to access RR node 'side' for non-IPIN/OPIN type '%s'", - rr_node_typename[node_data.type_]); - } - // Return a vector showing only the sides that the node appears - std::bitset side_tt = node_storage[id].dir_side_.sides; - return side_tt; - } - /* Find if the given node appears on a specific side */ static inline bool is_node_on_specific_side( vtr::array_view_id node_storage, @@ -839,14 +760,6 @@ class t_rr_graph_view { return t_rr_graph_storage::get_node_direction(node_storage_, id); } - e_side node_side(RRNodeId id) const { - return t_rr_graph_storage::get_node_side(node_storage_, id); - } - - std::bitset node_sides(const RRNodeId& id) const { - return t_rr_graph_storage::get_node_sides(node_storage_, id); - } - /* PTC get methods */ short node_ptc_num(RRNodeId id) const; short node_pin_num(RRNodeId id) const; //Same as ptc_num() but checks that type() is consistent diff --git a/vpr/src/route/rr_graph_uxsdcxx_serializer.h b/vpr/src/route/rr_graph_uxsdcxx_serializer.h index 85725581795..cd67a9d6ff5 100644 --- a/vpr/src/route/rr_graph_uxsdcxx_serializer.h +++ b/vpr/src/route/rr_graph_uxsdcxx_serializer.h @@ -636,12 +636,23 @@ class RrGraphSerializer final : public uxsd::RrGraphBase { inode, node.type()); } } else { - node.set_sides(from_uxsd_loc_side(side)); + std::bitset sides_to_add = from_uxsd_loc_side(side); + for (const e_side& side_to_add : SIDES) { + if (sides_to_add[side_to_add]) { + node.add_side(side_to_add); + } + } } } inline uxsd::enum_loc_side get_node_loc_side(const t_rr_node& node) final { if (node.type() == IPIN || node.type() == OPIN) { - return to_uxsd_loc_side(node.sides()); + std::bitset sides_bitset; + for (const e_side& side : SIDES) { + if (node.is_node_on_specific_side(side)) { + sides_bitset.set(side); + } + } + return to_uxsd_loc_side(sides_bitset); } else { return uxsd::enum_loc_side::UXSD_INVALID; } diff --git a/vpr/src/route/rr_node.cpp b/vpr/src/route/rr_node.cpp index dbd4450e9ca..b824a995180 100644 --- a/vpr/src/route/rr_node.cpp +++ b/vpr/src/route/rr_node.cpp @@ -24,10 +24,6 @@ const char* t_rr_node::direction_string() const { return "NO_DIR"; } -const char* t_rr_node::side_string() const { - return SIDE_STRING[side()]; -} - //Returns the max 'length' over the x or y direction short t_rr_node::length() const { return std::max( @@ -121,14 +117,6 @@ void t_rr_node::set_direction(e_direction new_direction) { storage_->set_node_direction(id_, new_direction); } -void t_rr_node::set_side(e_side new_side) { - storage_->set_node_side(id_, new_side); -} - -void t_rr_node::set_sides(std::bitset new_sides) { - storage_->set_node_sides(id_, new_sides); -} - void t_rr_node::add_side(e_side new_side) { storage_->add_node_side(id_, new_side); } diff --git a/vpr/src/route/rr_node.h b/vpr/src/route/rr_node.h index b43a6cde678..f5ec3faeacf 100644 --- a/vpr/src/route/rr_node.h +++ b/vpr/src/route/rr_node.h @@ -112,10 +112,7 @@ class t_rr_node { e_direction direction() const; const char* direction_string() const; - e_side side() const; - std::bitset sides() const; bool is_node_on_specific_side(e_side side) const; - const char* side_string() const; float R() const; float C() const; @@ -139,7 +136,6 @@ class t_rr_node { void set_direction(e_direction); void set_side(e_side); - void set_sides(std::bitset); void add_side(e_side); void next_node() { diff --git a/vpr/src/route/rr_node_impl.h b/vpr/src/route/rr_node_impl.h index 4e1888c4aa6..6659f9e0243 100644 --- a/vpr/src/route/rr_node_impl.h +++ b/vpr/src/route/rr_node_impl.h @@ -155,14 +155,6 @@ inline e_direction t_rr_node::direction() const { return storage_->node_direction(id_); } -inline e_side t_rr_node::side() const { - return storage_->node_side(id_); -} - -inline std::bitset t_rr_node::sides() const { - return storage_->node_sides(id_); -} - inline bool t_rr_node::is_node_on_specific_side(e_side side) const { return storage_->is_node_on_specific_side(id_, side); } diff --git a/vpr/src/timing/VprTimingGraphResolver.cpp b/vpr/src/timing/VprTimingGraphResolver.cpp index abbc2d93849..88fcc479cc9 100644 --- a/vpr/src/timing/VprTimingGraphResolver.cpp +++ b/vpr/src/timing/VprTimingGraphResolver.cpp @@ -298,8 +298,14 @@ void VprTimingGraphResolver::get_detailed_interconnect_components_helper(std::ve net_component.type_name = device_ctx.rr_nodes[node->inode].type_string(); //write the component's type as a routing resource node net_component.type_name += ":" + std::to_string(node->inode) + " "; //add the index of the routing resource node if (device_ctx.rr_nodes[node->inode].type() == OPIN || device_ctx.rr_nodes[node->inode].type() == IPIN) { - net_component.type_name += "side:"; //add the side of the routing resource node - net_component.type_name += device_ctx.rr_nodes[node->inode].side_string(); //add the side of the routing resource node + net_component.type_name += "side: ("; //add the side of the routing resource node + for (const e_side& node_side : SIDES) { + if (!device_ctx.rr_nodes.is_node_on_specific_side(RRNodeId(node->inode), node_side)) { + continue; + } + net_component.type_name += std::string(SIDE_STRING[node_side]) + ","; //add the side of the routing resource node + } + net_component.type_name += ")"; //add the side of the routing resource node // For OPINs and IPINs the starting and ending coordinate are identical, so we can just arbitrarily assign the start to larger values // and the end to the lower coordinate start_x = " (" + std::to_string(device_ctx.rr_nodes[node->inode].xhigh()) + ","; //start and end coordinates are the same for OPINs and IPINs