many bug fixing and now start improving the routability of tileable rr_graph
This commit is contained in:
parent
0d62661c71
commit
fd301eeb66
|
@ -302,3 +302,23 @@ DeviceCoordinator get_track_rr_node_end_coordinator(const t_rr_node* track_rr_no
|
|||
|
||||
return start_coordinator;
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* Get the ptc of a routing track in the channel where it ends
|
||||
* For routing tracks in INC_DIRECTION
|
||||
* the ptc is the last of track_ids
|
||||
*
|
||||
* For routing tracks in DEC_DIRECTION
|
||||
* the ptc is the first of track_ids
|
||||
***********************************************************************/
|
||||
short get_track_rr_node_end_track_id(const t_rr_node* track_rr_node) {
|
||||
/* Make sure we have CHANX or CHANY */
|
||||
assert ( (CHANX == track_rr_node->type) ||(CHANY == track_rr_node->type) );
|
||||
|
||||
if (INC_DIRECTION == track_rr_node->direction) {
|
||||
return track_rr_node->track_ids.back();
|
||||
}
|
||||
assert (DEC_DIRECTION == track_rr_node->direction);
|
||||
return track_rr_node->track_ids.front();
|
||||
}
|
||||
|
||||
|
|
|
@ -34,5 +34,7 @@ DeviceCoordinator get_track_rr_node_start_coordinator(const t_rr_node* track_rr_
|
|||
|
||||
DeviceCoordinator get_track_rr_node_end_coordinator(const t_rr_node* track_rr_node);
|
||||
|
||||
short get_track_rr_node_end_track_id(const t_rr_node* track_rr_node);
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -191,7 +191,7 @@ ChanNodeDetails build_unidir_chan_node_details(const size_t chan_width, const si
|
|||
}
|
||||
|
||||
/* Find the number of segments required by each group */
|
||||
std::vector<size_t> num_tracks = get_num_tracks_per_seg_type(actual_chan_width/2, segment_inf, TRUE);
|
||||
std::vector<size_t> num_tracks = get_num_tracks_per_seg_type(actual_chan_width/2, segment_inf, FALSE);
|
||||
|
||||
/* Add node to ChanNodeDetails */
|
||||
size_t cur_track = 0;
|
||||
|
@ -208,8 +208,9 @@ ChanNodeDetails build_unidir_chan_node_details(const size_t chan_width, const si
|
|||
if (0 == itrack % seg_len) {
|
||||
seg_start = true;
|
||||
}
|
||||
/* Every last track of a group of Length-N wires, we set an ending point */
|
||||
if (seg_len - 1 == itrack % seg_len) {
|
||||
/* Every last track of a group of Length-N wires or this is the last track in this group, we set an ending point */
|
||||
if ( (seg_len - 1 == itrack % seg_len)
|
||||
|| (itrack == num_tracks[iseg] - 1) ) {
|
||||
seg_end = true;
|
||||
}
|
||||
/* Since this is a unidirectional routing architecture,
|
||||
|
|
|
@ -868,6 +868,75 @@ void clear_rr_graph_driver_switch(const t_rr_graph* rr_graph) {
|
|||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* Sort the edges of rr_nodes by node type and ptc_num
|
||||
* 1. node type priority: (follow the index of t_rr_type
|
||||
* SOURCE, SINK, IPIN, OPIN, CHANX, CHANY, INTRA_CLUSTER_EDGE, NUM_RR_TYPES
|
||||
* 2. node ptc_num (feature number): from low to high
|
||||
* The ptc_num only matters when two nodes have the same type
|
||||
***********************************************************************/
|
||||
static
|
||||
void sort_rr_graph_edges(t_rr_graph* rr_graph) {
|
||||
for (int inode = 0; inode < rr_graph->num_rr_nodes; ++inode) {
|
||||
/* Create a copy of the edges and switches of this node */
|
||||
std::vector<int> sorted_edges;
|
||||
std::vector<short> sorted_switches;
|
||||
|
||||
/* Ensure a clean start */
|
||||
sorted_edges.clear();
|
||||
sorted_switches.clear();
|
||||
|
||||
/* Build the vectors w.r.t. to the order of node_type and ptc_num */
|
||||
for (int iedge = 0; iedge < rr_graph->rr_node[inode].num_edges; ++iedge) {
|
||||
/* For blank edges: directly push_back */
|
||||
if (0 == sorted_edges.size()) {
|
||||
sorted_edges.push_back(rr_graph->rr_node[inode].edges[iedge]);
|
||||
sorted_switches.push_back(rr_graph->rr_node[inode].switches[iedge]);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Start sorting since the edges are not empty */
|
||||
size_t insert_pos = sorted_edges.size(); /* the pos to insert. By default, it is the last element */
|
||||
size_t i_to_node = rr_graph->rr_node[inode].edges[iedge]; /* node_id of the edge connects to */
|
||||
for (size_t jedge = 0; jedge < sorted_edges.size(); ++jedge) {
|
||||
size_t j_to_node = sorted_edges[jedge];
|
||||
/* Sort by node_type and ptc_num */
|
||||
if (rr_graph->rr_node[i_to_node].type < rr_graph->rr_node[j_to_node].type) {
|
||||
/* iedge should be ahead of jedge */
|
||||
insert_pos = jedge;
|
||||
break; /* least type should stay in the front of the vector */
|
||||
} else if (rr_graph->rr_node[i_to_node].type == rr_graph->rr_node[j_to_node].type) {
|
||||
/* Special as track_ids vary, we consider the last track_ids for those node has the same type as inode */
|
||||
if (rr_graph->rr_node[i_to_node].type == rr_graph->rr_node[inode].type) {
|
||||
if (get_track_rr_node_end_track_id(&(rr_graph->rr_node[i_to_node]))
|
||||
< get_track_rr_node_end_track_id(&(rr_graph->rr_node[j_to_node])) ) {
|
||||
insert_pos = jedge;
|
||||
break; /* least type should stay in the front of the vector */
|
||||
}
|
||||
} else if (rr_graph->rr_node[i_to_node].ptc_num < rr_graph->rr_node[j_to_node].ptc_num) {
|
||||
/* Now a lower ptc_num will win */
|
||||
insert_pos = jedge;
|
||||
break; /* least type should stay in the front of the vector */
|
||||
}
|
||||
}
|
||||
}
|
||||
/* We find the position, inserted to the vector */
|
||||
sorted_edges.insert(sorted_edges.begin() + insert_pos, i_to_node);
|
||||
sorted_switches.insert(sorted_switches.begin() + insert_pos, rr_graph->rr_node[inode].switches[iedge]);
|
||||
}
|
||||
|
||||
/* Overwrite the edges and switches with sorted numbers */
|
||||
for (size_t iedge = 0; iedge < sorted_edges.size(); ++iedge) {
|
||||
rr_graph->rr_node[inode].edges[iedge] = sorted_edges[iedge];
|
||||
}
|
||||
for (size_t iedge = 0; iedge < sorted_switches.size(); ++iedge) {
|
||||
rr_graph->rr_node[inode].switches[iedge] = sorted_switches[iedge];
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* Main function of this file
|
||||
|
@ -1019,12 +1088,12 @@ void build_tileable_unidir_rr_graph(INP const int L_num_types,
|
|||
}
|
||||
|
||||
/************************************************************************
|
||||
* 6. Build the connections tile by tile:
|
||||
* We classify rr_nodes into a general switch block (GSB) data structure
|
||||
* where we create edges to each rr_nodes in the GSB with respect to
|
||||
* Fc_in and Fc_out, switch block patterns
|
||||
* In addition, we will also handle direct-connections:
|
||||
* Add edges that bridge OPINs and IPINs to the rr_graph
|
||||
* 6.1 Build the connections tile by tile:
|
||||
* We classify rr_nodes into a general switch block (GSB) data structure
|
||||
* where we create edges to each rr_nodes in the GSB with respect to
|
||||
* Fc_in and Fc_out, switch block patterns
|
||||
* In addition, we will also handle direct-connections:
|
||||
* Add edges that bridge OPINs and IPINs to the rr_graph
|
||||
***********************************************************************/
|
||||
/* Create edges for a tileable rr_graph */
|
||||
build_rr_graph_edges(&rr_graph, device_size, grids, device_chan_width, segment_infs,
|
||||
|
@ -1032,7 +1101,7 @@ void build_tileable_unidir_rr_graph(INP const int L_num_types,
|
|||
sb_type, Fs);
|
||||
|
||||
/************************************************************************
|
||||
* 7. Build direction connection lists
|
||||
* 6.2 Build direction connection lists
|
||||
***********************************************************************/
|
||||
/* Create data structure of direct-connections */
|
||||
t_clb_to_clb_directs* clb_to_clb_directs = NULL;
|
||||
|
@ -1042,6 +1111,14 @@ void build_tileable_unidir_rr_graph(INP const int L_num_types,
|
|||
build_rr_graph_direct_connections(&rr_graph, device_size, grids, delayless_switch,
|
||||
num_directs, directs, clb_to_clb_directs);
|
||||
|
||||
/************************************************************************
|
||||
* 6.3 Sort the edges of rr_nodes by node type and ptc_num
|
||||
* During the edge construction, edges are out of orders,
|
||||
* 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);
|
||||
|
||||
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;
|
||||
|
@ -1053,7 +1130,7 @@ void build_tileable_unidir_rr_graph(INP const int L_num_types,
|
|||
clear_rr_graph_driver_switch(&rr_graph);
|
||||
|
||||
/************************************************************************
|
||||
* 8. Allocate external data structures
|
||||
* 7. Allocate external data structures
|
||||
* a. cost_index
|
||||
* b. RC tree
|
||||
***********************************************************************/
|
||||
|
@ -1066,7 +1143,7 @@ void build_tileable_unidir_rr_graph(INP const int L_num_types,
|
|||
wire_to_ipin_switch, base_cost_type);
|
||||
|
||||
/************************************************************************
|
||||
* 9. Sanitizer for the rr_graph, check connectivities of rr_nodes
|
||||
* 8. Sanitizer for the rr_graph, check connectivities of rr_nodes
|
||||
***********************************************************************/
|
||||
|
||||
/* Print useful information on screen */
|
||||
|
@ -1083,7 +1160,7 @@ void build_tileable_unidir_rr_graph(INP const int L_num_types,
|
|||
|
||||
|
||||
/************************************************************************
|
||||
* 10. Free all temp stucts
|
||||
* 9. Free all temp stucts
|
||||
***********************************************************************/
|
||||
|
||||
/* Free all temp structs */
|
||||
|
|
|
@ -1108,6 +1108,11 @@ void build_gsb_one_opin_pin2track_map(const t_rr_graph* rr_graph,
|
|||
/* Push the node to actual_track_list */
|
||||
actual_track_list.push_back(track_list[inode]);
|
||||
}
|
||||
|
||||
/* Go the next segment if offset is zero or actual_track_list is empty */
|
||||
if (0 == actual_track_list.size()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Scale Fc */
|
||||
int actual_Fc = Fc * actual_track_list.size() / chan_width;
|
||||
|
@ -1122,8 +1127,12 @@ void build_gsb_one_opin_pin2track_map(const t_rr_graph* rr_graph,
|
|||
track_step = std::max(1, (int)track_step);
|
||||
/* Adapt offset to the range of actual_track_list */
|
||||
size_t actual_offset = offset % actual_track_list.size();
|
||||
/* rotate the track list by an offset */
|
||||
std::rotate(actual_track_list.begin(), actual_track_list.begin() + actual_offset, actual_track_list.end());
|
||||
|
||||
/* No need to rotate if offset is zero */
|
||||
if (0 < actual_offset) {
|
||||
/* rotate the track list by an offset */
|
||||
std::rotate(actual_track_list.begin(), actual_track_list.begin() + actual_offset, actual_track_list.end());
|
||||
}
|
||||
|
||||
/* Assign tracks */
|
||||
int track_cnt = 0;
|
||||
|
@ -1248,11 +1257,8 @@ t_pin2track_map build_gsb_opin_to_track_map(t_rr_graph* rr_graph,
|
|||
|
||||
/* offset counter: it aims to balance the OPIN-to-track for each switch block */
|
||||
std::vector<size_t> offset;
|
||||
for (size_t side = 0; side < rr_gsb.get_num_sides(); ++side) {
|
||||
/* Get the chan_side: which is the same as the opin side */
|
||||
Side side_manager(side);
|
||||
offset.resize(side_manager.to_size_t());
|
||||
}
|
||||
/* Get the chan_side: which is the same as the opin side */
|
||||
offset.resize(rr_gsb.get_num_sides());
|
||||
/* Initial offset */
|
||||
offset.assign(offset.size(), 0);
|
||||
|
||||
|
@ -1275,8 +1281,7 @@ t_pin2track_map build_gsb_opin_to_track_map(t_rr_graph* rr_graph,
|
|||
int grid_type_index = grids[opin_node->xlow][opin_node->ylow].type->index;
|
||||
/* Get Fc of the ipin */
|
||||
int opin_Fc = Fc_out[grid_type_index][opin_node->ptc_num];
|
||||
/* skip Fc = 0 */
|
||||
//printf("opin_Fc[%d]=%d\n", opin_node->ptc_num, opin_Fc);
|
||||
/* skip Fc = 0 or unintialized, those pins are in the <directlist> */
|
||||
if ( (-1 == opin_Fc)
|
||||
|| (0 == opin_Fc) ) {
|
||||
continue;
|
||||
|
@ -1286,8 +1291,8 @@ t_pin2track_map build_gsb_opin_to_track_map(t_rr_graph* rr_graph,
|
|||
/* Give an offset for the first track that this ipin will connect to */
|
||||
offset[side_manager.to_size_t()],
|
||||
segment_inf, &opin2track_map);
|
||||
/* update offset */
|
||||
offset[side_manager.to_size_t()] += 2;
|
||||
/* update offset: aim to rotate starting tracks by 1*/
|
||||
offset[side_manager.to_size_t()] += 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3137,6 +3137,7 @@ void spice_backannotate_vpr_post_route_info(t_det_routing_arch RoutingArch,
|
|||
/* Build previous node lists for each rr_node */
|
||||
vpr_printf(TIO_MESSAGE_INFO, "Building previous node list for all Routing Resource Nodes...\n");
|
||||
build_prev_node_list_rr_nodes(num_rr_nodes, rr_node);
|
||||
//sort_rr_graph_drive_rr_nodes(num_rr_nodes, rr_node);
|
||||
|
||||
/* Build driver switches for each rr_node*/
|
||||
vpr_printf(TIO_MESSAGE_INFO, "Identifying driver switches for all Routing Resource Nodes...\n");
|
||||
|
|
|
@ -2528,6 +2528,7 @@ void link_one_pb_graph_node_pin_to_phy_pb_graph_pin(t_pb_graph_pin* cur_pb_graph
|
|||
}
|
||||
/* Create the link */
|
||||
cur_pb_graph_pin->physical_pb_graph_pin = phy_pb_graph_pin;
|
||||
/*
|
||||
vpr_printf (TIO_MESSAGE_INFO, " match pin (%s[%d]->%s[%d]) to (%s[%d]->%s[%d]) rotate_offset_acc=%d\n",
|
||||
cur_pb_graph_pin->parent_node->pb_type->name,
|
||||
cur_pb_graph_pin->parent_node->placement_index,
|
||||
|
@ -2537,6 +2538,7 @@ void link_one_pb_graph_node_pin_to_phy_pb_graph_pin(t_pb_graph_pin* cur_pb_graph
|
|||
phy_pb_graph_pin->port->name, phy_pb_graph_pin->pin_number,
|
||||
cur_pb_graph_pin->port->phy_mode_pin_rotate_offset_acc
|
||||
);
|
||||
*/
|
||||
/* Accumulate the phy_mode_pin offset when we have a matched */
|
||||
if (0 != cur_pb_graph_pin->port->physical_mode_pin_rotate_offset) {
|
||||
cur_pb_graph_pin->port->phy_mode_pin_rotate_offset_acc += cur_pb_graph_pin->port->physical_mode_pin_rotate_offset;
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include <assert.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <vector>
|
||||
|
||||
/* Include vpr structs*/
|
||||
#include "util.h"
|
||||
|
@ -25,6 +26,8 @@
|
|||
#include "fpga_x2p_pbtypes_utils.h"
|
||||
#include "fpga_x2p_rr_graph_utils.h"
|
||||
|
||||
#include "rr_graph_builder_utils.h"
|
||||
|
||||
/* Initial rr_graph */
|
||||
void init_rr_graph(INOUTP t_rr_graph* local_rr_graph) {
|
||||
/* Give zero and NULL to all the contents */
|
||||
|
@ -954,8 +957,8 @@ void build_prev_node_list_rr_nodes(int LL_num_rr_nodes,
|
|||
if (0 == LL_rr_node[inode].fan_in) {
|
||||
continue;
|
||||
}
|
||||
LL_rr_node[inode].drive_rr_nodes = (t_rr_node**)my_malloc(sizeof(t_rr_node*)*LL_rr_node[inode].num_drive_rr_nodes);
|
||||
LL_rr_node[inode].drive_switches = (int*)my_malloc(sizeof(int)*LL_rr_node[inode].num_drive_rr_nodes);
|
||||
LL_rr_node[inode].drive_rr_nodes = (t_rr_node**)my_malloc(sizeof(t_rr_node*) * LL_rr_node[inode].num_drive_rr_nodes);
|
||||
LL_rr_node[inode].drive_switches = (int*)my_malloc(sizeof(int) * LL_rr_node[inode].num_drive_rr_nodes);
|
||||
}
|
||||
/* Initialize */
|
||||
for (inode = 0; inode < LL_num_rr_nodes; inode++) {
|
||||
|
@ -985,6 +988,73 @@ void build_prev_node_list_rr_nodes(int LL_num_rr_nodes,
|
|||
return;
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* Sort the drive_rr_nodes by node type and ptc_num
|
||||
* 1. node type priority: (follow the index of t_rr_type
|
||||
* SOURCE, SINK, IPIN, OPIN, CHANX, CHANY, INTRA_CLUSTER_EDGE, NUM_RR_TYPES
|
||||
* 2. node ptc_num (feature number): from low to high
|
||||
* The ptc_num only matters when two nodes have the same type
|
||||
***********************************************************************/
|
||||
void sort_rr_graph_drive_rr_nodes(int LL_num_rr_nodes,
|
||||
t_rr_node* LL_rr_node) {
|
||||
for (int inode = 0; inode < LL_num_rr_nodes; ++inode) {
|
||||
/* 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 < LL_rr_node[inode].num_drive_rr_nodes; ++i_from_node) {
|
||||
/* For blank edges: directly push_back */
|
||||
if (0 == sorted_drive_nodes.size()) {
|
||||
sorted_drive_nodes.push_back(LL_rr_node[inode].drive_rr_nodes[i_from_node]);
|
||||
sorted_drive_switches.push_back(LL_rr_node[inode].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 (LL_rr_node[inode].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 (LL_rr_node[inode].drive_rr_nodes[i_from_node]->type == sorted_drive_nodes[j_from_node]->type) {
|
||||
/* Special as track_ids vary, we consider the last track_ids for those node has the same type as inode */
|
||||
if (LL_rr_node[i_from_node].type == LL_rr_node[inode].type) {
|
||||
if (get_track_rr_node_end_track_id(&(LL_rr_node[i_from_node]))
|
||||
< get_track_rr_node_end_track_id(&(LL_rr_node[j_from_node])) ) {
|
||||
insert_pos = j_from_node;
|
||||
break; /* least type should stay in the front of the vector */
|
||||
}
|
||||
/* Now a lower ptc_num will win */
|
||||
} else if (LL_rr_node[inode].drive_rr_nodes[i_from_node]->ptc_num < sorted_drive_nodes[j_from_node]->ptc_num) {
|
||||
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, LL_rr_node[inode].drive_rr_nodes[i_from_node]);
|
||||
sorted_drive_switches.insert(sorted_drive_switches.begin() + insert_pos, LL_rr_node[inode].drive_switches[i_from_node]);
|
||||
}
|
||||
|
||||
/* Overwrite the edges and switches with sorted numbers */
|
||||
for (size_t iedge = 0; iedge < sorted_drive_nodes.size(); ++iedge) {
|
||||
LL_rr_node[inode].drive_rr_nodes[iedge] = sorted_drive_nodes[iedge];
|
||||
}
|
||||
for (size_t iedge = 0; iedge < sorted_drive_switches.size(); ++iedge) {
|
||||
LL_rr_node[inode].drive_switches[iedge] = sorted_drive_switches[iedge];
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void alloc_and_load_prev_node_list_rr_graph_rr_nodes(t_rr_graph* local_rr_graph) {
|
||||
build_prev_node_list_rr_nodes(local_rr_graph->num_rr_nodes, local_rr_graph->rr_node);
|
||||
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
#ifndef FPGA_X2P_RR_GRAPH_UTILS_H
|
||||
#define FPGA_X2P_RR_GRAPH_UTILS_H
|
||||
|
||||
void init_rr_graph(INOUTP t_rr_graph* local_rr_graph);
|
||||
|
||||
|
@ -89,6 +91,9 @@ void free_rr_graph_traceback(t_rr_graph* local_rr_graph,
|
|||
void build_prev_node_list_rr_nodes(int LL_num_rr_nodes,
|
||||
t_rr_node* LL_rr_node);
|
||||
|
||||
void sort_rr_graph_drive_rr_nodes(int LL_num_rr_nodes,
|
||||
t_rr_node* LL_rr_node);
|
||||
|
||||
void alloc_and_load_prev_node_list_rr_graph_rr_nodes(t_rr_graph* local_rr_graph);
|
||||
|
||||
void backannotate_rr_graph_routing_results_to_net_name(t_rr_graph* local_rr_graph);
|
||||
|
@ -106,3 +111,5 @@ void get_chan_rr_node_end_coordinate(t_rr_node* chan_rr_node,
|
|||
int* x_end, int* y_end);
|
||||
|
||||
int get_rr_node_wire_length(t_rr_node* src_rr_node);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1247,7 +1247,6 @@ RRGSB rotate_rr_switch_block_for_mirror(DeviceCoordinator& device_range,
|
|||
return rotated_rr_switch_block;
|
||||
}
|
||||
|
||||
|
||||
/* 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.
|
||||
|
@ -1258,22 +1257,23 @@ DeviceRRGSB build_device_rr_gsb(boolean output_sb_xml, char* sb_xml_dir,
|
|||
t_ivec*** LL_rr_node_indices, int num_segments,
|
||||
t_rr_indexed_data* LL_rr_indexed_data) {
|
||||
/* Create an object */
|
||||
DeviceRRGSB LL_drive_rr_gsb;
|
||||
DeviceRRGSB LL_device_rr_gsb;
|
||||
|
||||
/* Initialize */
|
||||
DeviceCoordinator sb_range((size_t)nx, (size_t)ny);
|
||||
DeviceCoordinator reserve_range((size_t)nx + 1, (size_t)ny + 1);
|
||||
LL_drive_rr_gsb.reserve(reserve_range);
|
||||
LL_device_rr_gsb.reserve(reserve_range);
|
||||
|
||||
/* For each switch block, determine the size of array */
|
||||
for (size_t ix = 0; ix <= sb_range.get_x(); ++ix) {
|
||||
for (size_t iy = 0; iy <= sb_range.get_y(); ++iy) {
|
||||
RRGSB rr_sb = build_rr_gsb(sb_range, ix, iy,
|
||||
LL_num_rr_nodes, LL_rr_node,
|
||||
LL_rr_node_indices,
|
||||
num_segments, LL_rr_indexed_data);
|
||||
DeviceCoordinator sb_coordinator = rr_sb.get_sb_coordinator();
|
||||
LL_drive_rr_gsb.add_rr_gsb(sb_coordinator, rr_sb);
|
||||
RRGSB rr_gsb = build_rr_gsb(sb_range, ix, iy,
|
||||
LL_num_rr_nodes, LL_rr_node,
|
||||
LL_rr_node_indices,
|
||||
num_segments, LL_rr_indexed_data);
|
||||
/* Add to device_rr_gsb */
|
||||
DeviceCoordinator sb_coordinator = rr_gsb.get_sb_coordinator();
|
||||
LL_device_rr_gsb.add_rr_gsb(sb_coordinator, rr_gsb);
|
||||
}
|
||||
}
|
||||
/* Report number of unique mirrors */
|
||||
|
@ -1283,7 +1283,7 @@ DeviceRRGSB build_device_rr_gsb(boolean output_sb_xml, char* sb_xml_dir,
|
|||
|
||||
|
||||
if (TRUE == output_sb_xml) {
|
||||
write_device_rr_gsb_to_xml(sb_xml_dir, LL_drive_rr_gsb);
|
||||
write_device_rr_gsb_to_xml(sb_xml_dir, LL_device_rr_gsb);
|
||||
|
||||
/* Skip rotating mirror searching */
|
||||
vpr_printf(TIO_MESSAGE_INFO,
|
||||
|
@ -1294,36 +1294,36 @@ DeviceRRGSB build_device_rr_gsb(boolean output_sb_xml, char* sb_xml_dir,
|
|||
|
||||
/* Build a list of unique modules for each Switch Block */
|
||||
/* Build a list of unique modules for each side of each Switch Block */
|
||||
LL_drive_rr_gsb.build_unique_module();
|
||||
LL_device_rr_gsb.build_unique_module();
|
||||
|
||||
vpr_printf(TIO_MESSAGE_INFO,
|
||||
"Detect %lu routing segments used by switch blocks.\n",
|
||||
LL_drive_rr_gsb.get_num_segments());
|
||||
LL_device_rr_gsb.get_num_segments());
|
||||
|
||||
/* Report number of unique CB Modules */
|
||||
vpr_printf(TIO_MESSAGE_INFO,
|
||||
"Detect %d independent connection blocks from %d X-channel connection blocks.\n",
|
||||
LL_drive_rr_gsb.get_num_cb_unique_module(CHANX), (nx + 0) * (ny + 1) );
|
||||
LL_device_rr_gsb.get_num_cb_unique_module(CHANX), (nx + 0) * (ny + 1) );
|
||||
|
||||
vpr_printf(TIO_MESSAGE_INFO,
|
||||
"Detect %d independent connection blocks from %d Y-channel connection blocks.\n",
|
||||
LL_drive_rr_gsb.get_num_cb_unique_module(CHANY), (nx + 1) * (ny + 0) );
|
||||
LL_device_rr_gsb.get_num_cb_unique_module(CHANY), (nx + 1) * (ny + 0) );
|
||||
|
||||
|
||||
/* Report number of unique SB modules */
|
||||
vpr_printf(TIO_MESSAGE_INFO,
|
||||
"Detect %d independent switch blocks from %d switch blocks.\n",
|
||||
LL_drive_rr_gsb.get_num_sb_unique_module(), (nx + 1) * (ny + 1) );
|
||||
LL_device_rr_gsb.get_num_sb_unique_module(), (nx + 1) * (ny + 1) );
|
||||
|
||||
/* Report number of unique mirrors */
|
||||
for (size_t side = 0; side < LL_drive_rr_gsb.get_max_num_sides(); ++side) {
|
||||
for (size_t side = 0; side < LL_device_rr_gsb.get_max_num_sides(); ++side) {
|
||||
Side side_manager(side);
|
||||
/* get segment ids */
|
||||
for (size_t iseg = 0; iseg < LL_drive_rr_gsb.get_num_segments(); ++iseg) {
|
||||
for (size_t iseg = 0; iseg < LL_device_rr_gsb.get_num_segments(); ++iseg) {
|
||||
vpr_printf(TIO_MESSAGE_INFO,
|
||||
"For side %s, segment id %lu: Detect %d independent switch blocks from %d switch blocks.\n",
|
||||
side_manager.c_str(), LL_drive_rr_gsb.get_segment_id(iseg),
|
||||
LL_drive_rr_gsb.get_num_sb_unique_submodule(side_manager.get_side(), iseg),
|
||||
side_manager.c_str(), LL_device_rr_gsb.get_segment_id(iseg),
|
||||
LL_device_rr_gsb.get_num_sb_unique_submodule(side_manager.get_side(), iseg),
|
||||
(nx + 1) * (ny + 1) );
|
||||
}
|
||||
}
|
||||
|
@ -1335,8 +1335,8 @@ DeviceRRGSB build_device_rr_gsb(boolean output_sb_xml, char* sb_xml_dir,
|
|||
|
||||
for (size_t ix = 0; ix <= sb_range.get_x(); ++ix) {
|
||||
for (size_t iy = 0; iy <= sb_range.get_y(); ++iy) {
|
||||
RRGSB rr_sb = LL_drive_rr_gsb.get_gsb(ix, iy);
|
||||
RRGSB rotated_rr_sb = rotate_rr_switch_block_for_mirror(sb_range, rr_sb);
|
||||
RRGSB rr_gsb = LL_device_rr_gsb.get_gsb(ix, iy);
|
||||
RRGSB rotated_rr_sb = rotate_rr_switch_block_for_mirror(sb_range, rr_gsb);
|
||||
if (TRUE == output_sb_xml) {
|
||||
std::string fname_prefix(sb_xml_dir);
|
||||
/* Add slash if needed */
|
||||
|
@ -1345,12 +1345,12 @@ DeviceRRGSB build_device_rr_gsb(boolean output_sb_xml, char* sb_xml_dir,
|
|||
//}
|
||||
//fname_prefix += "rotated_";
|
||||
//write_rr_switch_block_to_xml(fname_prefix, rotated_rr_sb);
|
||||
write_rr_switch_block_to_xml(fname_prefix, rr_sb);
|
||||
write_rr_switch_block_to_xml(fname_prefix, rr_gsb);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return LL_drive_rr_gsb;
|
||||
return LL_device_rr_gsb;
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue