Skip to content

RRGraphView edge_sink_node()/edge_switch() Implementation #1930

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 21 commits into from
Dec 23, 2021
Merged
Show file tree
Hide file tree
Changes from 20 commits
Commits
Show all changes
21 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
2 changes: 1 addition & 1 deletion README.developers.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ The overall approach is similar, but we call out the differences below.

## Commit Messages

Commit messages are an important part of understanding the code base and it's history.
Commit messages are an important part of understanding the code base and its history.
It is therefore *extremely* important to provide the following information in the commit message:

* What is being changed?
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
[![Build Status](https://github.com/verilog-to-routing/vtr-verilog-to-routing/workflows/Test/badge.svg)](https://github.com/verilog-to-routing/vtr-verilog-to-routing/actions?query=workflow%3ATest) [![Documentation Status](https://readthedocs.org/projects/vtr/badge/?version=latest)](http://docs.verilogtorouting.org/en/latest/)

## Introduction
The Verilog-to-Routing (VTR) project is a world-wide collaborative effort to provide a open-source framework for conducting FPGA architecture and CAD research and development.
The Verilog-to-Routing (VTR) project is a world-wide collaborative effort to provide an open-source framework for conducting FPGA architecture and CAD research and development.
The VTR design flow takes as input a Verilog description of a digital circuit, and a description of the target FPGA architecture.
It then performs:
* Elaboration & Synthesis (ODIN II)
Expand Down
4 changes: 2 additions & 2 deletions utils/fasm/test/test_fasm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -256,8 +256,8 @@ TEST_CASE("fasm_integration_test", "[fasm]") {
const auto& rr_graph = device_ctx.rr_graph;
for(size_t inode = 0; inode < device_ctx.rr_nodes.size(); ++inode) {
for(t_edge_size iedge = 0; iedge < rr_graph.num_edges(RRNodeId(inode)); ++iedge) {
auto sink_inode = device_ctx.rr_nodes[inode].edge_sink_node(iedge);
auto switch_id = device_ctx.rr_nodes[inode].edge_switch(iedge);
auto sink_inode = size_t(rr_graph.edge_sink_node(RRNodeId(inode), iedge));
auto switch_id = rr_graph.edge_switch(RRNodeId(inode), iedge);
auto value = vtr::string_fmt("%d_%d_%zu",
inode, sink_inode, switch_id);

Expand Down
26 changes: 19 additions & 7 deletions vpr/src/device/rr_graph_view.h
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,18 @@ class RRGraphView {
inline const char* node_side_string(RRNodeId node) const {
return node_storage_.node_side_string(node);
}
/** @brief Get the switch id that represents the iedge'th outgoing edge from a specific node
* TODO: We may need to revisit this API and think about higher level APIs, like ``switch_delay()``
**/
inline short edge_switch(RRNodeId id, t_edge_size iedge) const {
return node_storage_.edge_switch(id, iedge);
}
/** @brief Get the destination node for the iedge'th edge from specified RRNodeId.
* This method should generally not be used, and instead first_edge and
* last_edge should be used.*/
inline RRNodeId edge_sink_node(RRNodeId id, t_edge_size iedge) const {
return node_storage_.edge_sink_node(id, iedge);
}

/** @brief Get the number of configurable edges. This function is inlined for runtime optimization. */
inline t_edge_size num_configurable_edges(RRNodeId node) const {
Expand Down Expand Up @@ -298,13 +310,6 @@ class RRGraphView {
* This API is very powerful and developers should not use it unless it is necessary,
* e.g the node type is unknown. If the node type is known, the more specific routines, `node_pin_num()`,
* `node_track_num()`and `node_class_num()`, for different types of nodes should be used.*/
/** @brief Return detailed routing segment information with a given id* @note The routing segments here may not be exactly same as those defined in architecture file. They have been
* adapted to fit the context of routing resource graphs.
*/

inline const t_segment_inf& rr_segments(RRSegmentId seg_id) const {
return rr_segments_[seg_id];
}
inline short node_ptc_num(RRNodeId node) const {
return node_storage_.node_ptc_num(node);
}
Expand All @@ -331,6 +336,13 @@ class RRGraphView {
RRIndexedDataId node_cost_index(RRNodeId node) const {
return node_storage_.node_cost_index(node);
}
/** @brief Return detailed routing segment information with a given id* @note The routing segments here may not be exactly same as those defined in architecture file. They have been
* adapted to fit the context of routing resource graphs.
*/

inline const t_segment_inf& rr_segments(RRSegmentId seg_id) const {
return rr_segments_[seg_id];
}

/** @brief Return the fast look-up data structure for queries from client functions */
const RRSpatialLookup& node_lookup() const {
Expand Down
29 changes: 13 additions & 16 deletions vpr/src/draw/draw.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1686,10 +1686,10 @@ static void draw_rr_edges(int inode, ezgl::renderer* g) {
return; /* Nothing to draw. */
}

from_ptc_num = rr_graph.node_ptc_num(RRNodeId(inode));
from_ptc_num = rr_graph.node_ptc_num(rr_node);

for (t_edge_size iedge = 0, l = rr_graph.num_edges(RRNodeId(inode)); iedge < l; iedge++) {
to_node = device_ctx.rr_nodes[inode].edge_sink_node(iedge);
to_node = size_t(rr_graph.edge_sink_node(rr_node, iedge));
to_type = rr_graph.node_type(RRNodeId(to_node));
to_ptc_num = rr_graph.node_ptc_num(RRNodeId(to_node));
bool edge_configurable = device_ctx.rr_nodes[inode].edge_is_configurable(iedge);
Expand Down Expand Up @@ -1772,8 +1772,8 @@ static void draw_rr_edges(int inode, ezgl::renderer* g) {
} else {
g->set_color(blk_DARKGREEN);
}
switch_type = device_ctx.rr_nodes[inode].edge_switch(iedge);
draw_chanx_to_chanx_edge(RRNodeId(inode), RRNodeId(to_node),
switch_type = rr_graph.edge_switch(rr_node, iedge);
draw_chanx_to_chanx_edge(rr_node, RRNodeId(to_node),
to_ptc_num, switch_type, g);
break;

Expand All @@ -1789,7 +1789,7 @@ static void draw_rr_edges(int inode, ezgl::renderer* g) {
} else {
g->set_color(blk_DARKGREEN);
}
switch_type = device_ctx.rr_nodes[inode].edge_switch(iedge);
switch_type = rr_graph.edge_switch(rr_node, iedge);
draw_chanx_to_chany_edge(inode, from_ptc_num, to_node,
to_ptc_num, FROM_X_TO_Y, switch_type, g);
break;
Expand Down Expand Up @@ -1842,7 +1842,7 @@ static void draw_rr_edges(int inode, ezgl::renderer* g) {
} else {
g->set_color(blk_DARKGREEN);
}
switch_type = device_ctx.rr_nodes[inode].edge_switch(iedge);
switch_type = rr_graph.edge_switch(rr_node, iedge);
draw_chanx_to_chany_edge(to_node, to_ptc_num, inode,
from_ptc_num, FROM_Y_TO_X, switch_type, g);
break;
Expand All @@ -1860,8 +1860,8 @@ static void draw_rr_edges(int inode, ezgl::renderer* g) {
} else {
g->set_color(blk_DARKGREEN);
}
switch_type = device_ctx.rr_nodes[inode].edge_switch(iedge);
draw_chany_to_chany_edge(RRNodeId(inode), RRNodeId(to_node),
switch_type = rr_graph.edge_switch(rr_node, iedge);
draw_chany_to_chany_edge(rr_node, RRNodeId(to_node),
to_ptc_num, switch_type, g);
break;

Expand Down Expand Up @@ -2519,7 +2519,7 @@ void draw_partial_route(const std::vector<int>& rr_nodes_to_draw, ezgl::renderer
auto prev_type = rr_graph.node_type(RRNodeId(prev_node));

auto iedge = find_edge(prev_node, inode);
auto switch_type = device_ctx.rr_nodes[prev_node].edge_switch(iedge);
auto switch_type = rr_graph.edge_switch(RRNodeId(prev_node), iedge);

switch (rr_type) {
case OPIN: {
Expand Down Expand Up @@ -2698,12 +2698,11 @@ void draw_highlight_fan_in_fan_out(const std::set<int>& nodes) {
t_draw_state* draw_state = get_draw_state_vars();
auto& device_ctx = g_vpr_ctx.device();
const auto& rr_graph = device_ctx.rr_graph;

for (auto node : nodes) {
/* Highlight the fanout nodes in red. */
for (t_edge_size iedge = 0, l = rr_graph.num_edges(RRNodeId(node));
iedge < l; iedge++) {
int fanout_node = device_ctx.rr_nodes[node].edge_sink_node(iedge);
int fanout_node = size_t(rr_graph.edge_sink_node(RRNodeId(node), iedge));

if (draw_state->draw_rr_node[node].color == ezgl::MAGENTA
&& draw_state->draw_rr_node[fanout_node].color
Expand All @@ -2722,8 +2721,7 @@ void draw_highlight_fan_in_fan_out(const std::set<int>& nodes) {
for (size_t inode = 0; inode < device_ctx.rr_nodes.size(); inode++) {
for (t_edge_size iedge = 0, l = rr_graph.num_edges(RRNodeId(inode)); iedge < l;
iedge++) {
int fanout_node = device_ctx.rr_nodes[inode].edge_sink_node(
iedge);
int fanout_node = size_t(rr_graph.edge_sink_node(RRNodeId(node), iedge));
if (fanout_node == node) {
if (draw_state->draw_rr_node[node].color == ezgl::MAGENTA
&& draw_state->draw_rr_node[inode].color
Expand Down Expand Up @@ -2825,13 +2823,12 @@ void draw_expand_non_configurable_rr_nodes_recurr(int from_node,
std::set<int>& expanded_nodes) {
auto& device_ctx = g_vpr_ctx.device();
const auto& rr_graph = device_ctx.rr_graph;

expanded_nodes.insert(from_node);

for (t_edge_size iedge = 0;
iedge < rr_graph.num_edges(RRNodeId(from_node)); ++iedge) {
bool edge_configurable = device_ctx.rr_nodes[from_node].edge_is_configurable(iedge);
int to_node = device_ctx.rr_nodes[from_node].edge_sink_node(iedge);
int to_node = size_t(rr_graph.edge_sink_node(RRNodeId(from_node), iedge));

if (!edge_configurable && !expanded_nodes.count(to_node)) {
draw_expand_non_configurable_rr_nodes_recurr(to_node,
Expand Down Expand Up @@ -3788,7 +3785,7 @@ static t_edge_size find_edge(int prev_inode, int inode) {
const auto& rr_graph = device_ctx.rr_graph;
for (t_edge_size iedge = 0;
iedge < rr_graph.num_edges(RRNodeId(prev_inode)); ++iedge) {
if (device_ctx.rr_nodes[prev_inode].edge_sink_node(iedge) == inode) {
if (size_t(rr_graph.edge_sink_node(RRNodeId(prev_inode), iedge)) == size_t(inode)) {
return iedge;
}
}
Expand Down
7 changes: 3 additions & 4 deletions vpr/src/place/timing_place_lookup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1161,22 +1161,21 @@ bool directconnect_exists(int src_rr_node, int sink_rr_node) {
//which starts at src_rr_node and ends at sink_rr_node
auto& device_ctx = g_vpr_ctx.device();
const auto& rr_graph = device_ctx.rr_graph;
auto& rr_nodes = device_ctx.rr_nodes;

VTR_ASSERT(rr_graph.node_type(RRNodeId(src_rr_node)) == SOURCE && rr_graph.node_type(RRNodeId(sink_rr_node)) == SINK);

//TODO: This is a constant depth search, but still may be too slow
for (t_edge_size i_src_edge = 0; i_src_edge < rr_graph.num_edges(RRNodeId(src_rr_node)); ++i_src_edge) {
int opin_rr_node = rr_nodes[src_rr_node].edge_sink_node(i_src_edge);
int opin_rr_node = size_t(rr_graph.edge_sink_node(RRNodeId(src_rr_node), i_src_edge));

if (rr_graph.node_type(RRNodeId(opin_rr_node)) != OPIN) continue;

for (t_edge_size i_opin_edge = 0; i_opin_edge < rr_graph.num_edges(RRNodeId(opin_rr_node)); ++i_opin_edge) {
int ipin_rr_node = rr_nodes[opin_rr_node].edge_sink_node(i_opin_edge);
int ipin_rr_node = size_t(rr_graph.edge_sink_node(RRNodeId(opin_rr_node), i_opin_edge));
if (rr_graph.node_type(RRNodeId(ipin_rr_node)) != IPIN) continue;

for (t_edge_size i_ipin_edge = 0; i_ipin_edge < rr_graph.num_edges(RRNodeId(ipin_rr_node)); ++i_ipin_edge) {
if (sink_rr_node == rr_nodes[ipin_rr_node].edge_sink_node(i_ipin_edge)) {
if (size_t(sink_rr_node) == size_t(rr_graph.edge_sink_node(RRNodeId(ipin_rr_node), i_ipin_edge))) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the for loop (starting from LINE 1169), we can change the data type of

  • opin_rr_node from int to RRNodeId
  • ipin_rr_node from int to RRNodeId

I see in LINE 1174, the num_edges() remain using an old API. I believe that you have patched these line in another PR #1917
It means that we should merge #1917 before this PR.
Let me know if this is fine for you or not.

return true;
}
}
Expand Down
25 changes: 10 additions & 15 deletions vpr/src/power/power.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -814,16 +814,15 @@ static void power_usage_routing(t_power_usage* power_usage,
t_trace* trace;

for (trace = route_ctx.trace[net_id].head; trace != nullptr; trace = trace->next) {
auto node = device_ctx.rr_nodes[trace->index];
t_rr_node_power* node_power = &rr_node_power[trace->index];

if (node_power->visited) {
continue;
}

for (t_edge_size edge_idx = 0; edge_idx < rr_graph.num_edges(RRNodeId(trace->index)); edge_idx++) {
const auto& next_node_id = node.edge_sink_node(edge_idx);
if (next_node_id != OPEN) {
const auto& next_node_id = size_t(rr_graph.edge_sink_node(RRNodeId(trace->index), edge_idx));
if (next_node_id != size_t(OPEN)) {
t_rr_node_power* next_node_power = &rr_node_power[next_node_id];

switch (rr_graph.node_type(RRNodeId(next_node_id))) {
Expand Down Expand Up @@ -857,7 +856,6 @@ static void power_usage_routing(t_power_usage* power_usage,
/* Calculate power of all routing entities */
for (size_t rr_node_idx = 0; rr_node_idx < device_ctx.rr_nodes.size(); rr_node_idx++) {
t_power_usage sub_power_usage;
auto node = device_ctx.rr_nodes[rr_node_idx];
RRNodeId rr_node = RRNodeId(rr_node_idx);
t_rr_node_power* node_power = &rr_node_power[rr_node_idx];
float C_wire;
Expand Down Expand Up @@ -982,9 +980,9 @@ static void power_usage_routing(t_power_usage* power_usage,
connectionbox_fanout = 0;
switchbox_fanout = 0;
for (t_edge_size iedge = 0; iedge < rr_graph.num_edges(rr_node); iedge++) {
if (node.edge_switch(iedge) == routing_arch->wire_to_rr_ipin_switch) {
if (rr_graph.edge_switch(rr_node, iedge) == routing_arch->wire_to_rr_ipin_switch) {
connectionbox_fanout++;
} else if (node.edge_switch(iedge) == routing_arch->delayless_switch) {
} else if (rr_graph.edge_switch(rr_node, iedge) == routing_arch->delayless_switch) {
/* Do nothing */
} else {
switchbox_fanout++;
Expand Down Expand Up @@ -1209,7 +1207,6 @@ void power_routing_init(const t_det_routing_arch* routing_arch) {
for (size_t rr_node_idx = 0; rr_node_idx < device_ctx.rr_nodes.size(); rr_node_idx++) {
t_edge_size fanout_to_IPIN = 0;
t_edge_size fanout_to_seg = 0;
auto node = device_ctx.rr_nodes[rr_node_idx];
t_rr_node_power* node_power = &rr_node_power[rr_node_idx];
const t_edge_size node_fan_in = rr_graph.node_fan_in(RRNodeId(rr_node_idx));

Expand All @@ -1226,9 +1223,9 @@ void power_routing_init(const t_det_routing_arch* routing_arch) {
case CHANX:
case CHANY:
for (t_edge_size iedge = 0; iedge < rr_graph.num_edges(RRNodeId(rr_node_idx)); iedge++) {
if (node.edge_switch(iedge) == routing_arch->wire_to_rr_ipin_switch) {
if (rr_graph.edge_switch(RRNodeId(rr_node_idx), iedge) == routing_arch->wire_to_rr_ipin_switch) {
fanout_to_IPIN++;
} else if (node.edge_switch(iedge) != routing_arch->delayless_switch) {
} else if (rr_graph.edge_switch(RRNodeId(rr_node_idx), iedge) != routing_arch->delayless_switch) {
fanout_to_seg++;
}
}
Expand Down Expand Up @@ -1258,14 +1255,12 @@ void power_routing_init(const t_det_routing_arch* routing_arch) {

/* Populate driver switch type */
for (size_t rr_node_idx = 0; rr_node_idx < device_ctx.rr_nodes.size(); rr_node_idx++) {
auto node = device_ctx.rr_nodes[rr_node_idx];

for (t_edge_size edge_idx = 0; edge_idx < rr_graph.num_edges(RRNodeId(rr_node_idx)); edge_idx++) {
if (node.edge_sink_node(edge_idx) != OPEN) {
if (rr_node_power[node.edge_sink_node(edge_idx)].driver_switch_type == OPEN) {
rr_node_power[node.edge_sink_node(edge_idx)].driver_switch_type = node.edge_switch(edge_idx);
if (size_t(rr_graph.edge_sink_node(RRNodeId(rr_node_idx), edge_idx))) {
if (rr_node_power[size_t(rr_graph.edge_sink_node(RRNodeId(rr_node_idx), edge_idx))].driver_switch_type == OPEN) {
rr_node_power[size_t(rr_graph.edge_sink_node(RRNodeId(rr_node_idx), edge_idx))].driver_switch_type = rr_graph.edge_switch(RRNodeId(rr_node_idx), edge_idx);
} else {
VTR_ASSERT(rr_node_power[node.edge_sink_node(edge_idx)].driver_switch_type == node.edge_switch(edge_idx));
VTR_ASSERT(rr_node_power[size_t(rr_graph.edge_sink_node(RRNodeId(rr_node_idx), edge_idx))].driver_switch_type == rr_graph.edge_switch(RRNodeId(rr_node_idx), edge_idx));
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion vpr/src/route/check_route.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,7 @@ static bool check_adjacent(int from_node, int to_node) {
reached = false;

for (t_edge_size iconn = 0; iconn < rr_graph.num_edges(RRNodeId(from_node)); iconn++) {
if (device_ctx.rr_nodes[from_node].edge_sink_node(iconn) == to_node) {
if (size_t(rr_graph.edge_sink_node(RRNodeId(from_node), iconn)) == size_t(to_node)) {
reached = true;
break;
}
Expand Down
Loading