Skip to content

Clean RR graph generation code #2977

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 18 commits into from
Apr 16, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions libs/libarchfpga/src/device_grid.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,10 @@ class DeviceGrid {
inline int get_height_offset(const t_physical_tile_loc& tile_loc) const {
return grid_[tile_loc.layer_num][tile_loc.x][tile_loc.y].height_offset;
}
///@brief Returns true if the given location is the root location (bottom left corner) of a tile.
inline bool is_root_location(const t_physical_tile_loc& tile_loc) const {
return get_width_offset(tile_loc) == 0 && get_height_offset(tile_loc) == 0;
}

///@brief Returns a rectangle which represents the bounding box of the tile at the given location.
inline vtr::Rect<int> get_tile_bb(const t_physical_tile_loc& tile_loc) const {
Expand Down
10 changes: 7 additions & 3 deletions libs/libarchfpga/src/physical_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -540,10 +540,13 @@ struct t_port_power {
bool reverse_scaled; /* Scale by (1-prob) */
};

//The type of Fc specification
/**
* @enum e_fc_type
* @brief The type of Fc specification
*/
enum class e_fc_type {
IN, //The fc specification for an input pin
OUT //The fc specification for an output pin
IN, /**< Fc specification for an input pin. */
OUT /**< Fc specification for an output pin. */
};

//The value type of the Fc specification
Expand Down Expand Up @@ -1562,6 +1565,7 @@ enum e_directionality {
UNI_DIRECTIONAL,
BI_DIRECTIONAL
};

/* X_AXIS: Data that describes an x-directed wire segment (CHANX) *
* Y_AXIS: Data that describes an y-directed wire segment (CHANY) *
* BOTH_AXIS: Data that can be applied to both x-directed and y-directed wire segment */
Expand Down
4 changes: 2 additions & 2 deletions libs/librrgraph/src/base/check_rr_graph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,10 @@ void check_rr_graph(const RRGraphView& rr_graph,
const vtr::vector<RRIndexedDataId, t_rr_indexed_data>& rr_indexed_data,
const DeviceGrid& grid,
const t_chan_width& chan_width,
const t_graph_type graph_type,
const e_graph_type graph_type,
bool is_flat) {
e_route_type route_type = DETAILED;
if (graph_type == GRAPH_GLOBAL) {
if (graph_type == e_graph_type::GLOBAL) {
route_type = GLOBAL;
}

Expand Down
2 changes: 1 addition & 1 deletion libs/librrgraph/src/base/check_rr_graph.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ void check_rr_graph(const RRGraphView& rr_graph,
const vtr::vector<RRIndexedDataId, t_rr_indexed_data>& rr_indexed_data,
const DeviceGrid& grid,
const t_chan_width& chan_width,
const t_graph_type graph_type,
const e_graph_type graph_type,
bool is_flat);

void check_rr_node(const RRGraphView& rr_graph,
Expand Down
2 changes: 0 additions & 2 deletions libs/librrgraph/src/base/get_parallel_segs.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
#include "get_parallel_segs.h"

/*Gets t_segment_inf for parallel segments as defined by the user.
*Segments that have BOTH_AXIS attribute value are always included in the returned vector.*/
std::vector<t_segment_inf> get_parallel_segs(const std::vector<t_segment_inf>& segment_inf,
t_unified_to_parallel_seg_index& seg_index_map,
enum e_parallel_axis parallel_axis) {
Expand Down
12 changes: 12 additions & 0 deletions libs/librrgraph/src/base/get_parallel_segs.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,18 @@
#include "rr_graph_type.h"
#include "physical_types.h"

/**
* @brief Returns segments aligned with a given axis, including BOTH_AXIS segments.
*
* Filters the unified segment list (`segment_inf`) to include only segments matching
* the specified `parallel_axis` or marked as `BOTH_AXIS`. Also populates `seg_index_map`
* to map unified indices to axis-specific ones.
*
* @param segment_inf Unified list of all segments.
* @param seg_index_map Map from unified to axis-specific segment indices.
* @param parallel_axis Axis to filter segments by.
* @return Filtered list of segments for the given axis.
*/
std::vector<t_segment_inf> get_parallel_segs(const std::vector<t_segment_inf>& segment_inf,
t_unified_to_parallel_seg_index& seg_index_map,
enum e_parallel_axis parallel_axis);
Expand Down
34 changes: 24 additions & 10 deletions libs/librrgraph/src/base/rr_graph_type.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,32 @@ enum e_route_type {
DETAILED
};

enum e_graph_type {
GRAPH_GLOBAL, /* One node per channel with wire capacity > 1 and full connectivity */
GRAPH_BIDIR, /* Detailed bidirectional graph */
GRAPH_UNIDIR, /* Detailed unidir graph, untilable */
/* RESEARCH TODO: Get this option debugged */
GRAPH_UNIDIR_TILEABLE /* Detail unidir graph with wire groups multiples of 2*L */
/**
* @enum e_graph_type
* @brief Represents the type of routing resource graph
*/
enum class e_graph_type {
GLOBAL, ///< One node per channel with wire capacity > 1 and full connectivity
BIDIR, ///< Detailed bidirectional routing graph
UNIDIR, ///< Detailed unidirectional routing graph (non-tileable)
UNIDIR_TILEABLE ///< Tileable unidirectional graph with wire groups in multiples of 2 * L (experimental)
};
typedef enum e_graph_type t_graph_type;

/* This map is used to get indices w.r.t segment_inf_x or segment_inf_y based on parallel_axis of a segment,
* from indices w.r.t the **unified** segment vector, segment_inf in devices context which stores all segments
* regardless of their axis. (see get_parallel_segs for more details)*/
/**
* @typedef t_unified_to_parallel_seg_index
* @brief Maps indices from the unified segment list to axis-specific segment lists.
*
* This map is used to translate indices from the unified segment vector
* (`segment_inf` in the device context, which contains all segments regardless of axis)
* to axis-specific segment vectors (`segment_inf_x` or `segment_inf_y`), based on the
* segment's parallel axis.
*
* Each entry maps a unified segment index to a pair containing:
* - The index in the corresponding axis-specific segment vector
* - The axis of the segment (X or Y)
*
* @see get_parallel_segs for more details.
*/
typedef std::unordered_multimap<size_t, std::pair<size_t, e_parallel_axis>> t_unified_to_parallel_seg_index;

#endif
4 changes: 2 additions & 2 deletions libs/librrgraph/src/base/rr_node_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ typedef uint16_t t_edge_size;
/**
* @brief An iterator that dereferences to an edge index
*
* Used inconjunction with vtr::Range to return ranges of edge indices
* Used in conjunction with vtr::Range to return ranges of edge indices
*/
class edge_idx_iterator {
public:
Expand Down Expand Up @@ -101,7 +101,7 @@ typedef vtr::Range<edge_idx_iterator> edge_idx_range;
typedef std::vector<std::map<int, int>> t_arch_switch_fanin;

/*
* Reistance/Capacitance data for an RR Nodes
* Resistance/Capacitance data for an RR Nodes
*
* In practice many RR nodes have the same values, so they are fly-weighted
* to keep t_rr_node small. Each RR node holds an rc_index which allows
Expand Down
2 changes: 1 addition & 1 deletion libs/librrgraph/src/io/rr_graph_reader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ void load_rr_file(RRGraphBuilder* rr_graph_builder,
std::vector<t_rr_rc_data>* rr_rc_data,
const DeviceGrid& grid,
const std::vector<t_arch_switch_inf>& arch_switch_inf,
const t_graph_type graph_type,
e_graph_type graph_type,
const t_arch* arch,
t_chan_width* chan_width,
const enum e_base_cost_type base_cost_type,
Expand Down
2 changes: 1 addition & 1 deletion libs/librrgraph/src/io/rr_graph_reader.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ void load_rr_file(RRGraphBuilder* rr_graph_builder,
std::vector<t_rr_rc_data>* rr_rc_data,
const DeviceGrid& grid,
const std::vector<t_arch_switch_inf>& arch_switch_inf,
const t_graph_type graph_type,
e_graph_type graph_type,
const t_arch* arch,
t_chan_width* chan_width,
const enum e_base_cost_type base_cost_type,
Expand Down
6 changes: 3 additions & 3 deletions libs/librrgraph/src/io/rr_graph_uxsdcxx_serializer.h
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,7 @@ struct RrGraphContextTypes : public uxsd::DefaultRrGraphContextTypes {
class RrGraphSerializer final : public uxsd::RrGraphBase<RrGraphContextTypes> {
public:
RrGraphSerializer(
const t_graph_type graph_type,
const e_graph_type graph_type,
const enum e_base_cost_type base_cost_type,
int* wire_to_rr_ipin_switch,
int* wire_to_rr_ipin_switch_between_dice,
Expand Down Expand Up @@ -823,7 +823,7 @@ class RrGraphSerializer final : public uxsd::RrGraphBase<RrGraphContextTypes> {
auto node = (*rr_nodes_)[inode];
RRNodeId node_id = node.id();

if (GRAPH_GLOBAL == graph_type_) {
if (e_graph_type::GLOBAL == graph_type_) {
rr_graph_builder_->set_node_cost_index(node_id, RRIndexedDataId(0));
} else if (rr_graph.node_type(node.id()) == CHANX) {
int seg_ind_x = find_segment_index_along_axis(segment_id, X_AXIS);
Expand Down Expand Up @@ -2166,7 +2166,7 @@ class RrGraphSerializer final : public uxsd::RrGraphBase<RrGraphContextTypes> {
std::vector<t_rr_rc_data>* rr_rc_data_;

// Constant data for loads and writes.
const t_graph_type graph_type_;
const e_graph_type graph_type_;
const enum e_base_cost_type base_cost_type_;
const bool do_check_rr_graph_;
const char* read_rr_graph_name_;
Expand Down
2 changes: 1 addition & 1 deletion libs/librrgraph/src/io/rr_graph_writer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ void write_rr_graph(RRGraphBuilder* rr_graph_builder,
bool is_flat) {

RrGraphSerializer reader(
/*graph_type=*/t_graph_type(),
/*graph_type=*/e_graph_type(),
/*base_cost_type=*/e_base_cost_type(),
/*wire_to_rr_ipin_switch=*/nullptr,
/*wire_to_rr_ipin_switch_between_dice=*/nullptr,
Expand Down
28 changes: 15 additions & 13 deletions vpr/src/base/place_and_route.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@

/******************* Subroutines local to this module ************************/

static int compute_chan_width(int cfactor, t_chan chan_dist, float distance, float separation, t_graph_type graph_directionality);
static int compute_chan_width(int cfactor, t_chan chan_dist, float distance, float separation, e_graph_type graph_directionality);
static float comp_width(t_chan* chan, float x, float separation);

/************************* Subroutine Definitions ****************************/
Expand Down Expand Up @@ -68,8 +68,8 @@ int binary_search_place_and_route(const Netlist<>& placement_net_list,
int udsd_multiplier;
int warnings;

t_graph_type graph_type;
t_graph_type graph_directionality;
e_graph_type graph_type;
e_graph_type graph_directionality;

/* We have chosen to pass placer_opts_ref by reference because of its large size. *
* However, since the value is mutated later in the function, we declare a *
Expand All @@ -80,11 +80,11 @@ int binary_search_place_and_route(const Netlist<>& placement_net_list,
/* Allocate the major routing structures. */

if (router_opts.route_type == GLOBAL) {
graph_type = GRAPH_GLOBAL;
graph_directionality = GRAPH_BIDIR;
graph_type = e_graph_type::GLOBAL;
graph_directionality = e_graph_type::BIDIR;
} else {
graph_type = (det_routing_arch->directionality == BI_DIRECTIONAL ? GRAPH_BIDIR : GRAPH_UNIDIR);
graph_directionality = (det_routing_arch->directionality == BI_DIRECTIONAL ? GRAPH_BIDIR : GRAPH_UNIDIR);
graph_type = (det_routing_arch->directionality == BI_DIRECTIONAL ? e_graph_type::BIDIR : e_graph_type::UNIDIR);
graph_directionality = (det_routing_arch->directionality == BI_DIRECTIONAL ? e_graph_type::BIDIR : e_graph_type::UNIDIR);
}

VTR_ASSERT(!net_delay.empty());
Expand Down Expand Up @@ -408,7 +408,7 @@ t_chan_width setup_chan_width(const t_router_opts& router_opts,
/*we give plenty of tracks, this increases routability for the */
/*lookup table generation */

t_graph_type graph_directionality;
e_graph_type graph_directionality;
int width_fac;

if (router_opts.fixed_channel_width == NO_FIXED_CHANNEL_WIDTH) {
Expand All @@ -425,9 +425,9 @@ t_chan_width setup_chan_width(const t_router_opts& router_opts,
}

if (router_opts.route_type == GLOBAL) {
graph_directionality = GRAPH_BIDIR;
graph_directionality = e_graph_type::BIDIR;
} else {
graph_directionality = GRAPH_UNIDIR;
graph_directionality = e_graph_type::UNIDIR;
}

return init_chan(width_fac, chan_width_dist, graph_directionality);
Expand All @@ -441,7 +441,9 @@ t_chan_width setup_chan_width(const t_router_opts& router_opts,
* is used to determine if the channel width should be rounded to an
* even number.
*/
t_chan_width init_chan(int cfactor, const t_chan_width_dist& chan_width_dist, t_graph_type graph_directionality) {
t_chan_width init_chan(int cfactor,
const t_chan_width_dist& chan_width_dist,
e_graph_type graph_directionality) {
auto& device_ctx = g_vpr_ctx.mutable_device();
auto& grid = device_ctx.grid;

Expand Down Expand Up @@ -513,10 +515,10 @@ t_chan_width init_chan(int cfactor, const t_chan_width_dist& chan_width_dist, t_
* @param separation The distance between two channels in the 0 to 1 coordinate system.
* @param graph_directionality The directionality of the graph (unidirectional or bidirectional).
*/
static int compute_chan_width(int cfactor, t_chan chan_dist, float distance, float separation, t_graph_type graph_directionality) {
static int compute_chan_width(int cfactor, t_chan chan_dist, float distance, float separation, e_graph_type graph_directionality) {
int computed_width;
computed_width = (int)floor(cfactor * comp_width(&chan_dist, distance, separation) + 0.5);
if ((GRAPH_BIDIR == graph_directionality) || computed_width % 2 == 0) {
if ((e_graph_type::BIDIR == graph_directionality) || computed_width % 2 == 0) {
return computed_width;
} else {
return computed_width - 1;
Expand Down
2 changes: 1 addition & 1 deletion vpr/src/base/place_and_route.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ t_chan_width setup_chan_width(const t_router_opts& router_opts,

t_chan_width init_chan(int cfactor,
const t_chan_width_dist& chan_width_dist,
t_graph_type graph_directionality);
e_graph_type graph_directionality);

void post_place_sync();

Expand Down
12 changes: 6 additions & 6 deletions vpr/src/base/vpr_api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1099,14 +1099,14 @@ void vpr_create_rr_graph(t_vpr_setup& vpr_setup, const t_arch& arch, int chan_wi
auto det_routing_arch = &vpr_setup.RoutingArch;
auto& router_opts = vpr_setup.RouterOpts;

t_graph_type graph_type;
t_graph_type graph_directionality;
e_graph_type graph_type;
e_graph_type graph_directionality;
if (router_opts.route_type == GLOBAL) {
graph_type = GRAPH_GLOBAL;
graph_directionality = GRAPH_BIDIR;
graph_type = e_graph_type::GLOBAL;
graph_directionality = e_graph_type::BIDIR;
} else {
graph_type = (det_routing_arch->directionality == BI_DIRECTIONAL ? GRAPH_BIDIR : GRAPH_UNIDIR);
graph_directionality = (det_routing_arch->directionality == BI_DIRECTIONAL ? GRAPH_BIDIR : GRAPH_UNIDIR);
graph_type = (det_routing_arch->directionality == BI_DIRECTIONAL ? e_graph_type::BIDIR : e_graph_type::UNIDIR);
graph_directionality = (det_routing_arch->directionality == BI_DIRECTIONAL ? e_graph_type::BIDIR : e_graph_type::UNIDIR);
}

t_chan_width chan_width = init_chan(chan_width_fac, arch.Chans, graph_directionality);
Expand Down
Loading