sorted drive_rr_nodes for RR GSBs, #. of SBs should be constant now

This commit is contained in:
tangxifan 2019-06-24 22:46:56 -06:00
parent fd301eeb66
commit 785b560bd5
3 changed files with 213 additions and 12 deletions

View File

@ -1117,14 +1117,15 @@ void build_tileable_unidir_rr_graph(INP const int L_num_types,
* which are not easy to build tileable routing architecture
* This step can be skipped when you do not use FPGA X2P
***********************************************************************/
sort_rr_graph_edges(&rr_graph);
//sort_rr_graph_edges(&rr_graph);
size_t num_edges = 0;
for (int inode = 0; inode < rr_graph.num_rr_nodes; ++inode) {
num_edges += rr_graph.rr_node[inode].num_edges;
}
vpr_printf(TIO_MESSAGE_INFO,
"%lu edges of RR graph built.\n", num_edges);
"%lu edges of RR graph built.\n",
num_edges);
/* Clear driver switches of the rr_graph */
clear_rr_graph_driver_switch(&rr_graph);

View File

@ -1247,6 +1247,193 @@ RRGSB rotate_rr_switch_block_for_mirror(DeviceCoordinator& device_range,
return rotated_rr_switch_block;
}
/* sort drive_rr_nodes of a rr_node inside rr_gsb subject to the index of rr_gsb array */
static
void sort_rr_gsb_one_ipin_node_drive_rr_nodes(const RRGSB& rr_gsb,
t_rr_node* ipin_node,
enum e_side ipin_chan_side) {
/* Create a copy of the edges and switches of this node */
std::vector<t_rr_node*> sorted_drive_nodes;
std::vector<int> sorted_drive_switches;
/* Ensure a clean start */
sorted_drive_nodes.clear();
sorted_drive_switches.clear();
/* Build the vectors w.r.t. to the order of node_type and ptc_num */
for (int i_from_node = 0; i_from_node < ipin_node->num_drive_rr_nodes; ++i_from_node) {
/* For blank edges: directly push_back */
if (0 == sorted_drive_nodes.size()) {
sorted_drive_nodes.push_back(ipin_node->drive_rr_nodes[i_from_node]);
sorted_drive_switches.push_back(ipin_node->drive_switches[i_from_node]);
continue;
}
/* Start sorting since the edges are not empty */
size_t insert_pos = sorted_drive_nodes.size(); /* the pos to insert. By default, it is the last element */
for (size_t j_from_node = 0; j_from_node < sorted_drive_nodes.size(); ++j_from_node) {
/* Sort by node_type and ptc_num */
if (ipin_node->drive_rr_nodes[i_from_node]->type < sorted_drive_nodes[j_from_node]->type) {
/* iedge should be ahead of jedge */
insert_pos = j_from_node;
break; /* least type should stay in the front of the vector */
} else if (ipin_node->drive_rr_nodes[i_from_node]->type
== sorted_drive_nodes[j_from_node]->type) {
/* For channel node, we do not know the node direction
* But we are pretty sure it is either IN_PORT or OUT_PORT
* So we just try and find what is valid
*/
enum PORTS i_from_node_direction = IN_PORT;
if (-1 == rr_gsb.get_node_index(ipin_node->drive_rr_nodes[i_from_node],
ipin_chan_side,
IN_PORT)) {
i_from_node_direction = OUT_PORT;
}
enum PORTS j_from_node_direction = IN_PORT;
if (-1 != rr_gsb.get_node_index(sorted_drive_nodes[j_from_node],
ipin_chan_side,
IN_PORT)) {
j_from_node_direction = OUT_PORT;
}
/* Now a lower ptc_num will win */
if ( rr_gsb.get_node_index(ipin_node->drive_rr_nodes[i_from_node], ipin_chan_side, i_from_node_direction)
< rr_gsb.get_node_index(sorted_drive_nodes[j_from_node], ipin_chan_side, j_from_node_direction) ) {
insert_pos = j_from_node;
break; /* least type should stay in the front of the vector */
}
}
}
/* We find the position, inserted to the vector */
sorted_drive_nodes.insert(sorted_drive_nodes.begin() + insert_pos, ipin_node->drive_rr_nodes[i_from_node]);
sorted_drive_switches.insert(sorted_drive_switches.begin() + insert_pos, ipin_node->drive_switches[i_from_node]);
}
/* Overwrite the edges and switches with sorted numbers */
for (size_t iedge = 0; iedge < sorted_drive_nodes.size(); ++iedge) {
ipin_node->drive_rr_nodes[iedge] = sorted_drive_nodes[iedge];
}
for (size_t iedge = 0; iedge < sorted_drive_switches.size(); ++iedge) {
ipin_node->drive_switches[iedge] = sorted_drive_switches[iedge];
}
return;
}
/* sort drive_rr_nodes of a rr_node inside rr_gsb subject to the index of rr_gsb array */
static
void sort_rr_gsb_one_chan_node_drive_rr_nodes(const RRGSB& rr_gsb,
t_rr_node* chan_node,
enum e_side chan_side) {
/* If this is a passing wire, we return directly.
* The passing wire will be handled in other GSBs
*/
if (true == rr_gsb.is_sb_node_imply_short_connection(chan_node)) {
/* Double check if the interc lies inside a channel wire, that is interc between segments */
assert(true == rr_gsb.is_sb_node_exist_opposite_side(chan_node, chan_side));
return;
}
/* Create a copy of the edges and switches of this node */
std::vector<t_rr_node*> sorted_drive_nodes;
std::vector<int> sorted_drive_switches;
/* Ensure a clean start */
sorted_drive_nodes.clear();
sorted_drive_switches.clear();
/* Build the vectors w.r.t. to the order of node_type and ptc_num */
for (int i_from_node = 0; i_from_node < chan_node->num_drive_rr_nodes; ++i_from_node) {
/* For blank edges: directly push_back */
if (0 == sorted_drive_nodes.size()) {
sorted_drive_nodes.push_back(chan_node->drive_rr_nodes[i_from_node]);
sorted_drive_switches.push_back(chan_node->drive_switches[i_from_node]);
continue;
}
/* Start sorting since the edges are not empty */
size_t insert_pos = sorted_drive_nodes.size(); /* the pos to insert. By default, it is the last element */
for (size_t j_from_node = 0; j_from_node < sorted_drive_nodes.size(); ++j_from_node) {
/* Sort by node_type and ptc_num */
if (chan_node->drive_rr_nodes[i_from_node]->type < sorted_drive_nodes[j_from_node]->type) {
/* iedge should be ahead of jedge */
insert_pos = j_from_node;
break; /* least type should stay in the front of the vector */
} else if (chan_node->drive_rr_nodes[i_from_node]->type
== sorted_drive_nodes[j_from_node]->type) {
/* For channel node, we do not know the node direction
* But we are pretty sure it is either IN_PORT or OUT_PORT
* So we just try and find what is valid
*/
enum e_side i_from_node_side = NUM_SIDES;
int i_from_node_index = -1;
rr_gsb.get_node_side_and_index(chan_node->drive_rr_nodes[i_from_node],
IN_PORT, &i_from_node_side, &i_from_node_index);
/* check */
if (! ( (NUM_SIDES != i_from_node_side) && (-1 != i_from_node_index) ) )
assert ( (NUM_SIDES != i_from_node_side) && (-1 != i_from_node_index) );
enum e_side j_from_node_side = NUM_SIDES;
int j_from_node_index = -1;
rr_gsb.get_node_side_and_index(sorted_drive_nodes[j_from_node],
IN_PORT, &j_from_node_side, &j_from_node_index);
/* check */
assert ( (NUM_SIDES != j_from_node_side) && (-1 != j_from_node_index) );
/* Now a lower ptc_num will win */
if ( i_from_node_index < j_from_node_index) {
insert_pos = j_from_node;
break; /* least type should stay in the front of the vector */
}
}
}
/* We find the position, inserted to the vector */
sorted_drive_nodes.insert(sorted_drive_nodes.begin() + insert_pos, chan_node->drive_rr_nodes[i_from_node]);
sorted_drive_switches.insert(sorted_drive_switches.begin() + insert_pos, chan_node->drive_switches[i_from_node]);
}
/* Overwrite the edges and switches with sorted numbers */
for (size_t iedge = 0; iedge < sorted_drive_nodes.size(); ++iedge) {
chan_node->drive_rr_nodes[iedge] = sorted_drive_nodes[iedge];
}
for (size_t iedge = 0; iedge < sorted_drive_switches.size(); ++iedge) {
chan_node->drive_switches[iedge] = sorted_drive_switches[iedge];
}
return;
}
/* sort drive_rr_nodes of each rr_node subject to the index of rr_gsb array */
static
void sort_rr_gsb_drive_rr_nodes(const RRGSB& rr_gsb) {
/* Sort the drive_rr_nodes for each rr_node */
for (size_t side = 0; side < rr_gsb.get_num_sides(); ++side) {
Side gsb_side_manager(side);
enum e_side gsb_side = gsb_side_manager.get_side();
/* For IPIN node: sort drive_rr_nodes according to the index in the routing channels */
for (size_t inode = 0; inode < rr_gsb.get_num_ipin_nodes(gsb_side); ++inode) {
/* Get the chan side, so we have the routing tracks */
enum e_side ipin_chan_side = rr_gsb.get_cb_chan_side(gsb_side);
sort_rr_gsb_one_ipin_node_drive_rr_nodes(rr_gsb,
rr_gsb.get_ipin_node(gsb_side, inode),
ipin_chan_side);
}
/* For CHANX | CHANY node: sort drive_rr_nodes according to the index in the routing channels */
for (size_t inode = 0; inode < rr_gsb.get_chan_width(gsb_side); ++inode) {
/* Bypass IN_PORT */
if (IN_PORT == rr_gsb.get_chan_node_direction(gsb_side, inode)) {
continue;
}
/* Get the chan side, so we have the routing tracks */
sort_rr_gsb_one_chan_node_drive_rr_nodes(rr_gsb,
rr_gsb.get_chan_node(gsb_side, inode),
gsb_side);
}
}
return;
}
/* Build a list of Switch blocks, each of which contains a collection of rr_nodes
* We will maintain a list of unique switch blocks, which will be outputted as a Verilog module
* Each switch block in the FPGA fabric will be an instance of these modules.
@ -1271,6 +1458,8 @@ DeviceRRGSB build_device_rr_gsb(boolean output_sb_xml, char* sb_xml_dir,
LL_num_rr_nodes, LL_rr_node,
LL_rr_node_indices,
num_segments, LL_rr_indexed_data);
/* sort drive_rr_nodes */
sort_rr_gsb_drive_rr_nodes(rr_gsb);
/* Add to device_rr_gsb */
DeviceCoordinator sb_coordinator = rr_gsb.get_sb_coordinator();
LL_device_rr_gsb.add_rr_gsb(sb_coordinator, rr_gsb);

View File

@ -1882,8 +1882,10 @@ void RRGSB::mirror_side_chan_node_direction(enum e_side side) {
void RRGSB::swap_chan_node(enum e_side src_side, enum e_side des_side) {
Side src_side_manager(src_side);
Side des_side_manager(des_side);
std::swap(chan_node_[src_side_manager.to_size_t()], chan_node_[des_side_manager.to_size_t()]);
std::swap(chan_node_direction_[src_side_manager.to_size_t()], chan_node_direction_[des_side_manager.to_size_t()]);
std::swap(chan_node_[src_side_manager.to_size_t()],
chan_node_[des_side_manager.to_size_t()]);
std::swap(chan_node_direction_[src_side_manager.to_size_t()],
chan_node_direction_[des_side_manager.to_size_t()]);
return;
}
@ -1891,8 +1893,10 @@ void RRGSB::swap_chan_node(enum e_side src_side, enum e_side des_side) {
void RRGSB::swap_opin_node(enum e_side src_side, enum e_side des_side) {
Side src_side_manager(src_side);
Side des_side_manager(des_side);
std::swap(opin_node_[src_side_manager.to_size_t()], opin_node_[des_side_manager.to_size_t()]);
std::swap(opin_node_grid_side_[src_side_manager.to_size_t()], opin_node_grid_side_[des_side_manager.to_size_t()]);
std::swap(opin_node_[src_side_manager.to_size_t()],
opin_node_[des_side_manager.to_size_t()]);
std::swap(opin_node_grid_side_[src_side_manager.to_size_t()],
opin_node_grid_side_[des_side_manager.to_size_t()]);
return;
}
@ -1900,27 +1904,34 @@ void RRGSB::swap_opin_node(enum e_side src_side, enum e_side des_side) {
void RRGSB::swap_ipin_node(enum e_side src_side, enum e_side des_side) {
Side src_side_manager(src_side);
Side des_side_manager(des_side);
std::swap(ipin_node_[src_side_manager.to_size_t()], ipin_node_[des_side_manager.to_size_t()]);
std::swap(ipin_node_grid_side_[src_side_manager.to_size_t()], ipin_node_grid_side_[des_side_manager.to_size_t()]);
std::swap(ipin_node_[src_side_manager.to_size_t()],
ipin_node_[des_side_manager.to_size_t()]);
std::swap(ipin_node_grid_side_[src_side_manager.to_size_t()],
ipin_node_grid_side_[des_side_manager.to_size_t()]);
return;
}
/* Reverse the vector of the OPIN rr_nodes on a side */
void RRGSB::reverse_opin_node(enum e_side side) {
Side side_manager(side);
std::reverse(opin_node_[side_manager.to_size_t()].begin(), opin_node_[side_manager.to_size_t()].end());
std::reverse(opin_node_grid_side_[side_manager.to_size_t()].begin(), opin_node_grid_side_[side_manager.to_size_t()].end());
std::reverse(opin_node_[side_manager.to_size_t()].begin(),
opin_node_[side_manager.to_size_t()].end());
std::reverse(opin_node_grid_side_[side_manager.to_size_t()].begin(),
opin_node_grid_side_[side_manager.to_size_t()].end());
return;
}
/* Reverse the vector of the OPIN rr_nodes on a side */
void RRGSB::reverse_ipin_node(enum e_side side) {
Side side_manager(side);
std::reverse(ipin_node_[side_manager.to_size_t()].begin(), ipin_node_[side_manager.to_size_t()].end());
std::reverse(ipin_node_grid_side_[side_manager.to_size_t()].begin(), ipin_node_grid_side_[side_manager.to_size_t()].end());
std::reverse(ipin_node_[side_manager.to_size_t()].begin(),
ipin_node_[side_manager.to_size_t()].end());
std::reverse(ipin_node_grid_side_[side_manager.to_size_t()].begin(),
ipin_node_grid_side_[side_manager.to_size_t()].end());
return;
}
/* Reset the RRGSB to pristine state */
void RRGSB::clear() {
/* Clean all the vectors */
assert(validate_num_sides());