many bug fixing for tileable rr_graph generator. Still debugging
This commit is contained in:
parent
d48fd959a9
commit
41954056ce
|
@ -73,6 +73,15 @@ size_t ChanNodeDetails::get_track_node_id(size_t track_id) const {
|
|||
return track_node_ids_[track_id];
|
||||
}
|
||||
|
||||
/* Return a copy of vector */
|
||||
std::vector<size_t> ChanNodeDetails::get_track_node_ids() const {
|
||||
std::vector<size_t> copy;
|
||||
for (size_t inode = 0; inode < get_chan_width(); ++inode) {
|
||||
copy.push_back(track_node_ids_[inode]);
|
||||
}
|
||||
return copy;
|
||||
}
|
||||
|
||||
e_direction ChanNodeDetails::get_track_direction(size_t track_id) const {
|
||||
assert(validate_track_id(track_id));
|
||||
return track_direction_[track_id];
|
||||
|
@ -111,9 +120,6 @@ std::vector<size_t> ChanNodeDetails::get_seg_group(size_t track_id) const {
|
|||
/* Make sure a clean start */
|
||||
group.clear();
|
||||
|
||||
/* track_id is the first element */
|
||||
group.push_back(track_id);
|
||||
|
||||
for (size_t itrack = track_id; itrack < get_chan_width(); ++itrack) {
|
||||
if ( (get_track_direction(itrack) == get_track_direction(track_id) )
|
||||
&& (get_track_segment_length(itrack) == get_track_segment_length(track_id)) ) {
|
||||
|
@ -146,9 +152,13 @@ std::vector<size_t> ChanNodeDetails::get_seg_group_node_id(std::vector<size_t> s
|
|||
}
|
||||
|
||||
/* Get the number of tracks that starts in this routing channel */
|
||||
size_t ChanNodeDetails::get_num_starting_tracks() const {
|
||||
size_t ChanNodeDetails::get_num_starting_tracks(enum e_direction track_direction) const {
|
||||
size_t counter = 0;
|
||||
for (size_t itrack = 0; itrack < get_chan_width(); ++itrack) {
|
||||
/* Bypass unmatched track_direction */
|
||||
if (track_direction != get_track_direction(itrack)) {
|
||||
continue;
|
||||
}
|
||||
if (false == is_track_start(itrack)) {
|
||||
continue;
|
||||
}
|
||||
|
@ -158,9 +168,13 @@ size_t ChanNodeDetails::get_num_starting_tracks() const {
|
|||
}
|
||||
|
||||
/* Get the number of tracks that ends in this routing channel */
|
||||
size_t ChanNodeDetails::get_num_ending_tracks() const {
|
||||
size_t ChanNodeDetails::get_num_ending_tracks(enum e_direction track_direction) const {
|
||||
size_t counter = 0;
|
||||
for (size_t itrack = 0; itrack < get_chan_width(); ++itrack) {
|
||||
/* Bypass unmatched track_direction */
|
||||
if (track_direction != get_track_direction(itrack)) {
|
||||
continue;
|
||||
}
|
||||
if (false == is_track_end(itrack)) {
|
||||
continue;
|
||||
}
|
||||
|
@ -169,6 +183,7 @@ size_t ChanNodeDetails::get_num_ending_tracks() const {
|
|||
return counter;
|
||||
}
|
||||
|
||||
|
||||
/************************************************************************
|
||||
* Mutators
|
||||
***********************************************************************/
|
||||
|
@ -198,6 +213,15 @@ void ChanNodeDetails::set_track_node_id(size_t track_index, size_t track_node_id
|
|||
track_node_ids_[track_index] = track_node_id;
|
||||
}
|
||||
|
||||
/* Update the node_ids from a vector */
|
||||
void ChanNodeDetails::set_track_node_ids(std::vector<size_t> track_node_ids) {
|
||||
/* the size of vector should match chan_width */
|
||||
assert ( get_chan_width() == track_node_ids.size() );
|
||||
for (size_t inode = 0; inode < track_node_ids.size(); ++inode) {
|
||||
track_node_ids_[inode] = track_node_ids[inode];
|
||||
}
|
||||
}
|
||||
|
||||
/* Set tracks with a given direction to start */
|
||||
void ChanNodeDetails::set_tracks_start(e_direction track_direction) {
|
||||
for (size_t inode = 0; inode < get_chan_width(); ++inode) {
|
||||
|
@ -220,6 +244,11 @@ void ChanNodeDetails::set_tracks_end(e_direction track_direction) {
|
|||
|
||||
/* rotate the track_node_id by an offset */
|
||||
void ChanNodeDetails::rotate_track_node_id(size_t offset, e_direction track_direction, bool counter_rotate) {
|
||||
/* Direct return if offset = 0*/
|
||||
if (0 == offset) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Rotate the node_ids by groups
|
||||
* A group begins from a track_start and ends before another track_start
|
||||
*/
|
||||
|
@ -237,11 +266,13 @@ void ChanNodeDetails::rotate_track_node_id(size_t offset, e_direction track_dire
|
|||
std::vector<size_t> track_group = get_seg_group(itrack);
|
||||
/* Build a vector of the node ids of the tracks */
|
||||
std::vector<size_t> track_group_node_id = get_seg_group_node_id(track_group);
|
||||
/* adapt offset to the range of track_group_node_id */
|
||||
size_t actual_offset = offset % track_group_node_id.size();
|
||||
/* Rotate or Counter rotate */
|
||||
if (true == counter_rotate) {
|
||||
std::rotate(track_group_node_id.begin(), track_group_node_id.end() - offset, track_group_node_id.end());
|
||||
std::rotate(track_group_node_id.rbegin(), track_group_node_id.rbegin() + actual_offset, track_group_node_id.rend());
|
||||
} else {
|
||||
std::rotate(track_group_node_id.begin(), track_group_node_id.begin() + offset, track_group_node_id.end());
|
||||
std::rotate(track_group_node_id.begin(), track_group_node_id.begin() + actual_offset, track_group_node_id.end());
|
||||
}
|
||||
/* Update the node_ids */
|
||||
for (size_t inode = 0; inode < track_group.size(); ++inode) {
|
||||
|
|
|
@ -75,6 +75,7 @@ class ChanNodeDetails {
|
|||
public: /* Accessors */
|
||||
size_t get_chan_width() const;
|
||||
size_t get_track_node_id(size_t track_id) const;
|
||||
std::vector<size_t> get_track_node_ids() const;
|
||||
e_direction get_track_direction(size_t track_id) const;
|
||||
size_t get_track_segment_length(size_t track_id) const;
|
||||
size_t get_track_segment_id(size_t track_id) const;
|
||||
|
@ -82,12 +83,13 @@ class ChanNodeDetails {
|
|||
bool is_track_end(size_t track_id) const;
|
||||
std::vector<size_t> get_seg_group(size_t track_id) const;
|
||||
std::vector<size_t> get_seg_group_node_id(std::vector<size_t> seg_group) const;
|
||||
size_t get_num_starting_tracks() const;
|
||||
size_t get_num_ending_tracks() const;
|
||||
size_t get_num_starting_tracks(enum e_direction track_direction) const;
|
||||
size_t get_num_ending_tracks(enum e_direction track_direction) const;
|
||||
public: /* Mutators */
|
||||
void reserve(size_t chan_width); /* Reserve the capacitcy of vectors */
|
||||
void add_track(size_t track_node_id, e_direction track_direction, size_t seg_id, size_t seg_length, size_t is_start, size_t is_end);
|
||||
void set_track_node_id(size_t track_index, size_t track_node_id);
|
||||
void set_track_node_ids(std::vector<size_t> track_node_ids);
|
||||
void set_tracks_start(e_direction track_direction);
|
||||
void set_tracks_end(e_direction track_direction);
|
||||
void rotate_track_node_id(size_t offset, e_direction track_direction, bool counter_rotate); /* rotate the track_node_id by an offset */
|
||||
|
|
|
@ -254,10 +254,10 @@ std::vector<size_t> get_num_tracks_per_seg_type(const size_t chan_width,
|
|||
* +---------------------------------------+--------------+
|
||||
* | 10 | <--------MUX | Yes | No |
|
||||
* +---------------------------------------+--------------+
|
||||
* | 11 | --------> | No |
|
||||
* +---------------------------------+
|
||||
* | 12 | <-------- | No |
|
||||
* +---------------------------------+
|
||||
* | 11 | -------->MUX | No | Yes |
|
||||
* +------------------------------------------------------+
|
||||
* | 12 | <-------- | No | No |
|
||||
* +------------------------------------------------------+
|
||||
*
|
||||
* 3. SPECIAL for fringes: TOP|RIGHT|BOTTOM|RIGHT
|
||||
* if device_side is NUM_SIDES, we assume this channel does not locate on borders
|
||||
|
@ -383,8 +383,9 @@ std::vector<int> get_grid_side_pins(const t_grid_tile& cur_grid,
|
|||
pin_list.clear();
|
||||
|
||||
for (int ipin = 0; ipin < cur_grid.type->num_pins; ++ipin) {
|
||||
int class_id = cur_grid.type->pin_class[ipin];
|
||||
if ( (1 == cur_grid.type->pinloc[pin_height][pin_side][ipin])
|
||||
&& (pin_type == cur_grid.type->pin_class[ipin]) ) {
|
||||
&& (pin_type == cur_grid.type->class_inf[class_id].type) ) {
|
||||
pin_list.push_back(ipin);
|
||||
}
|
||||
}
|
||||
|
@ -400,24 +401,52 @@ static
|
|||
size_t get_grid_num_pins(const t_grid_tile& cur_grid, const enum e_pin_type pin_type, const enum e_side io_side) {
|
||||
size_t num_pins = 0;
|
||||
Side io_side_manager(io_side);
|
||||
/* For IO_TYPE sides */
|
||||
for (size_t side = 0; side < NUM_SIDES; ++side) {
|
||||
Side side_manager(side);
|
||||
/* skip unwanted sides */
|
||||
if ( (IO_TYPE == cur_grid.type)
|
||||
&& (side != io_side_manager.to_size_t()) ) {
|
||||
continue;
|
||||
|
||||
/* Consider capacity of the grid */
|
||||
for (int iblk = 0; iblk < cur_grid.type->capacity; ++iblk) {
|
||||
/* For IO_TYPE sides */
|
||||
for (size_t side = 0; side < NUM_SIDES; ++side) {
|
||||
Side side_manager(side);
|
||||
/* skip unwanted sides */
|
||||
if ( (IO_TYPE == cur_grid.type)
|
||||
&& (side != io_side_manager.to_size_t()) ) {
|
||||
continue;
|
||||
}
|
||||
/* Get pin list */
|
||||
for (int height = 0; height < cur_grid.type->height; ++height) {
|
||||
std::vector<int> pin_list = get_grid_side_pins(cur_grid, pin_type, side_manager.get_side(), height);
|
||||
num_pins += pin_list.size();
|
||||
}
|
||||
}
|
||||
/* Get pin list */
|
||||
for (int height = 0; height < cur_grid.type->height; ++height) {
|
||||
std::vector<int> pin_list = get_grid_side_pins(cur_grid, pin_type, side_manager.get_side(), height);
|
||||
num_pins += pin_list.size();
|
||||
}
|
||||
}
|
||||
|
||||
return num_pins;
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* Get the number of pins for a grid (either OPIN or IPIN)
|
||||
* For IO_TYPE, only one side will be used, we consider one side of pins
|
||||
* For others, we consider all the sides
|
||||
***********************************************************************/
|
||||
static
|
||||
size_t get_grid_num_classes(const t_grid_tile& cur_grid, const enum e_pin_type pin_type) {
|
||||
size_t num_classes = 0;
|
||||
|
||||
/* Consider capacity of the grid */
|
||||
for (int iblk = 0; iblk < cur_grid.type->capacity; ++iblk) {
|
||||
for (int iclass = 0; iclass < cur_grid.type->num_class; ++iclass) {
|
||||
/* Bypass unmatched pin_type */
|
||||
if (pin_type != cur_grid.type->class_inf[iclass].type) {
|
||||
continue;
|
||||
}
|
||||
num_classes++;
|
||||
}
|
||||
}
|
||||
|
||||
return num_classes;
|
||||
}
|
||||
|
||||
|
||||
/************************************************************************
|
||||
* Estimate the number of rr_nodes per category:
|
||||
* CHANX, CHANY, IPIN, OPIN, SOURCE, SINK
|
||||
|
@ -444,8 +473,8 @@ std::vector<size_t> estimate_num_rr_nodes_per_type(const DeviceCoordinator& devi
|
|||
* Note that the number of SOURCE nodes are the same as OPINs
|
||||
* and the number of SINK nodes are the same as IPINs
|
||||
***********************************************************************/
|
||||
for (size_t ix = 0; ix < grids.size(); ++ix) {
|
||||
for (size_t iy = 0; iy < grids[ix].size(); ++iy) {
|
||||
for (size_t ix = 0; ix < device_size.get_x(); ++ix) {
|
||||
for (size_t iy = 0; iy < device_size.get_y(); ++iy) {
|
||||
/* Skip EMPTY tiles */
|
||||
if (EMPTY_TYPE == grids[ix][iy].type) {
|
||||
continue;
|
||||
|
@ -465,11 +494,12 @@ std::vector<size_t> estimate_num_rr_nodes_per_type(const DeviceCoordinator& devi
|
|||
num_rr_nodes_per_type[OPIN] += get_grid_num_pins(grids[ix][iy], DRIVER, io_side);
|
||||
/* get the number of IPINs */
|
||||
num_rr_nodes_per_type[IPIN] += get_grid_num_pins(grids[ix][iy], RECEIVER, io_side);
|
||||
/* SOURCE: number of classes whose type is DRIVER */
|
||||
num_rr_nodes_per_type[SOURCE] += get_grid_num_classes(grid[ix][iy], DRIVER);
|
||||
/* SINK: number of classes whose type is RECEIVER */
|
||||
num_rr_nodes_per_type[SINK] += get_grid_num_classes(grid[ix][iy], RECEIVER);
|
||||
}
|
||||
}
|
||||
/* SOURCE and SINK */
|
||||
num_rr_nodes_per_type[SOURCE] = num_rr_nodes_per_type[OPIN];
|
||||
num_rr_nodes_per_type[SINK] = num_rr_nodes_per_type[IPIN];
|
||||
|
||||
/************************************************************************
|
||||
* 2. Assign the segments for each routing channel,
|
||||
|
@ -491,15 +521,18 @@ std::vector<size_t> estimate_num_rr_nodes_per_type(const DeviceCoordinator& devi
|
|||
for (size_t ix = 1; ix < device_size.get_x() - 1; ++ix) {
|
||||
enum e_side chan_side = NUM_SIDES;
|
||||
/* For LEFT side of FPGA */
|
||||
if (0 == ix) {
|
||||
if (1 == ix) {
|
||||
chan_side = LEFT;
|
||||
}
|
||||
/* For RIGHT side of FPGA */
|
||||
if (grids.size() - 2 == ix) {
|
||||
if (device_size.get_x() - 2 == ix) {
|
||||
chan_side = RIGHT;
|
||||
}
|
||||
ChanNodeDetails chanx_details = build_unidir_chan_node_details(chan_width[0], device_size.get_x() - 2, chan_side, segment_infs);
|
||||
num_rr_nodes_per_type[CHANX] += chanx_details.get_num_starting_tracks();
|
||||
/* When an INC_DIRECTION CHANX starts, we need a new rr_node */
|
||||
num_rr_nodes_per_type[CHANX] += chanx_details.get_num_starting_tracks(INC_DIRECTION);
|
||||
/* When an DEC_DIRECTION CHANX ends, we need a new rr_node */
|
||||
num_rr_nodes_per_type[CHANX] += chanx_details.get_num_ending_tracks(DEC_DIRECTION);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -508,18 +541,29 @@ std::vector<size_t> estimate_num_rr_nodes_per_type(const DeviceCoordinator& devi
|
|||
for (size_t iy = 1; iy < device_size.get_y() - 1; ++iy) {
|
||||
enum e_side chan_side = NUM_SIDES;
|
||||
/* For LEFT side of FPGA */
|
||||
if (0 == iy) {
|
||||
if (1 == iy) {
|
||||
chan_side = BOTTOM;
|
||||
}
|
||||
/* For RIGHT side of FPGA */
|
||||
if (grids[ix].size() - 2 == iy) {
|
||||
if (device_size.get_y() - 2 == iy) {
|
||||
chan_side = TOP;
|
||||
}
|
||||
ChanNodeDetails chany_details = build_unidir_chan_node_details(chan_width[1], device_size.get_y() - 2, chan_side, segment_infs);
|
||||
num_rr_nodes_per_type[CHANY] += chany_details.get_num_starting_tracks();
|
||||
/* When an INC_DIRECTION CHANX starts, we need a new rr_node */
|
||||
num_rr_nodes_per_type[CHANY] += chany_details.get_num_starting_tracks(INC_DIRECTION);
|
||||
/* When an DEC_DIRECTION CHANX ends, we need a new rr_node */
|
||||
num_rr_nodes_per_type[CHANY] += chany_details.get_num_ending_tracks(DEC_DIRECTION);
|
||||
}
|
||||
}
|
||||
|
||||
vpr_printf(TIO_MESSAGE_INFO, "Estimate %lu SOURCE nodes.\n", num_rr_nodes_per_type[SOURCE]);
|
||||
vpr_printf(TIO_MESSAGE_INFO, "Estimate %lu SINK nodes.\n", num_rr_nodes_per_type[SINK] );
|
||||
vpr_printf(TIO_MESSAGE_INFO, "Estimate %lu OPIN nodes.\n", num_rr_nodes_per_type[OPIN] );
|
||||
vpr_printf(TIO_MESSAGE_INFO, "Estimate %lu IPIN nodes.\n", num_rr_nodes_per_type[IPIN] );
|
||||
vpr_printf(TIO_MESSAGE_INFO, "Estimate %lu CHANX nodes.\n", num_rr_nodes_per_type[CHANY] );
|
||||
vpr_printf(TIO_MESSAGE_INFO, "Estimate %lu CHANY nodes.\n", num_rr_nodes_per_type[CHANY] );
|
||||
|
||||
|
||||
return num_rr_nodes_per_type;
|
||||
}
|
||||
|
||||
|
@ -554,69 +598,81 @@ void load_one_grid_rr_nodes_basic_info(const DeviceCoordinator& grid_coordinator
|
|||
t_rr_graph* rr_graph,
|
||||
size_t* cur_node_id,
|
||||
const int wire_to_ipin_switch, const int delayless_switch) {
|
||||
Side io_side_manager(io_side);
|
||||
/* Walk through the height of each grid,
|
||||
* get pins and configure the rr_nodes */
|
||||
for (int height = 0; height < cur_grid.type->height; ++height) {
|
||||
/* Walk through sides */
|
||||
for (size_t side = 0; side < NUM_SIDES; ++side) {
|
||||
Side side_manager(side);
|
||||
/* skip unwanted sides */
|
||||
if ( (IO_TYPE == cur_grid.type)
|
||||
&& (side != io_side_manager.to_size_t()) ) {
|
||||
continue;
|
||||
}
|
||||
/* Find OPINs */
|
||||
/* Configure pins by pins */
|
||||
std::vector<int> opin_list = get_grid_side_pins(cur_grid, DRIVER, side_manager.get_side(), height);
|
||||
for (size_t pin = 0; pin < opin_list.size(); ++pin) {
|
||||
/* Configure the rr_node for the OPIN */
|
||||
rr_graph->rr_node[*cur_node_id].type = OPIN;
|
||||
rr_graph->rr_node[*cur_node_id].xlow = grid_coordinator.get_x();
|
||||
rr_graph->rr_node[*cur_node_id].xhigh = grid_coordinator.get_x();
|
||||
rr_graph->rr_node[*cur_node_id].ylow = grid_coordinator.get_y();
|
||||
rr_graph->rr_node[*cur_node_id].yhigh = grid_coordinator.get_y();
|
||||
rr_graph->rr_node[*cur_node_id].ptc_num = opin_list[pin];
|
||||
rr_graph->rr_node[*cur_node_id].capacity = 1;
|
||||
rr_graph->rr_node[*cur_node_id].occ = 0;
|
||||
/* cost index is a FIXED value for OPIN */
|
||||
rr_graph->rr_node[*cur_node_id].cost_index = OPIN_COST_INDEX;
|
||||
/* Switch info */
|
||||
rr_graph->rr_node[*cur_node_id].driver_switch = delayless_switch;
|
||||
/* fill fast look-up table */
|
||||
load_one_node_to_rr_graph_fast_lookup(rr_graph, *cur_node_id,
|
||||
rr_graph->rr_node[*cur_node_id].type,
|
||||
rr_graph->rr_node[*cur_node_id].xlow,
|
||||
rr_graph->rr_node[*cur_node_id].ylow,
|
||||
rr_graph->rr_node[*cur_node_id].ptc_num);
|
||||
/* Update node counter */
|
||||
(*cur_node_id)++;
|
||||
}
|
||||
/* Find IPINs */
|
||||
/* Configure pins by pins */
|
||||
std::vector<int> ipin_list = get_grid_side_pins(cur_grid, RECEIVER, side_manager.get_side(), height);
|
||||
for (size_t pin = 0; pin < ipin_list.size(); ++pin) {
|
||||
rr_graph->rr_node[*cur_node_id].type = IPIN;
|
||||
rr_graph->rr_node[*cur_node_id].xlow = grid_coordinator.get_x();
|
||||
rr_graph->rr_node[*cur_node_id].xhigh = grid_coordinator.get_x();
|
||||
rr_graph->rr_node[*cur_node_id].ylow = grid_coordinator.get_y();
|
||||
rr_graph->rr_node[*cur_node_id].yhigh = grid_coordinator.get_y();
|
||||
rr_graph->rr_node[*cur_node_id].ptc_num = opin_list[pin];
|
||||
rr_graph->rr_node[*cur_node_id].capacity = 1;
|
||||
rr_graph->rr_node[*cur_node_id].occ = 0;
|
||||
/* cost index is a FIXED value for IPIN */
|
||||
rr_graph->rr_node[*cur_node_id].cost_index = IPIN_COST_INDEX;
|
||||
/* Switch info */
|
||||
rr_graph->rr_node[*cur_node_id].driver_switch = wire_to_ipin_switch;
|
||||
/* fill fast look-up table */
|
||||
load_one_node_to_rr_graph_fast_lookup(rr_graph, *cur_node_id,
|
||||
rr_graph->rr_node[*cur_node_id].type,
|
||||
rr_graph->rr_node[*cur_node_id].xlow,
|
||||
rr_graph->rr_node[*cur_node_id].ylow,
|
||||
rr_graph->rr_node[*cur_node_id].ptc_num);
|
||||
/* Update node counter */
|
||||
(*cur_node_id)++;
|
||||
}
|
||||
Side io_side_manager(io_side);
|
||||
|
||||
/* Consider capacity of the grid */
|
||||
for (int iblk = 0; iblk < cur_grid.type->capacity; ++iblk) {
|
||||
/* Walk through the height of each grid,
|
||||
* get pins and configure the rr_nodes */
|
||||
for (int height = 0; height < cur_grid.type->height; ++height) {
|
||||
/* Walk through sides */
|
||||
for (size_t side = 0; side < NUM_SIDES; ++side) {
|
||||
Side side_manager(side);
|
||||
/* skip unwanted sides */
|
||||
if ( (IO_TYPE == cur_grid.type)
|
||||
&& (side != io_side_manager.to_size_t()) ) {
|
||||
continue;
|
||||
}
|
||||
/* Find OPINs */
|
||||
/* Configure pins by pins */
|
||||
std::vector<int> opin_list = get_grid_side_pins(cur_grid, DRIVER, side_manager.get_side(), height);
|
||||
for (size_t pin = 0; pin < opin_list.size(); ++pin) {
|
||||
/* Configure the rr_node for the OPIN */
|
||||
rr_graph->rr_node[*cur_node_id].type = OPIN;
|
||||
rr_graph->rr_node[*cur_node_id].xlow = grid_coordinator.get_x();
|
||||
rr_graph->rr_node[*cur_node_id].xhigh = grid_coordinator.get_x();
|
||||
rr_graph->rr_node[*cur_node_id].ylow = grid_coordinator.get_y();
|
||||
rr_graph->rr_node[*cur_node_id].yhigh = grid_coordinator.get_y();
|
||||
rr_graph->rr_node[*cur_node_id].ptc_num = opin_list[pin];
|
||||
rr_graph->rr_node[*cur_node_id].capacity = 1;
|
||||
rr_graph->rr_node[*cur_node_id].occ = 0;
|
||||
/* cost index is a FIXED value for OPIN */
|
||||
rr_graph->rr_node[*cur_node_id].cost_index = OPIN_COST_INDEX;
|
||||
/* Switch info */
|
||||
rr_graph->rr_node[*cur_node_id].driver_switch = delayless_switch;
|
||||
/* fill fast look-up table */
|
||||
load_one_node_to_rr_graph_fast_lookup(rr_graph, *cur_node_id,
|
||||
rr_graph->rr_node[*cur_node_id].type,
|
||||
rr_graph->rr_node[*cur_node_id].xlow,
|
||||
rr_graph->rr_node[*cur_node_id].ylow,
|
||||
rr_graph->rr_node[*cur_node_id].ptc_num);
|
||||
/* Update node counter */
|
||||
(*cur_node_id)++;
|
||||
} /* End of loading OPIN rr_nodes */
|
||||
/* Find IPINs */
|
||||
/* Configure pins by pins */
|
||||
std::vector<int> ipin_list = get_grid_side_pins(cur_grid, RECEIVER, side_manager.get_side(), height);
|
||||
for (size_t pin = 0; pin < ipin_list.size(); ++pin) {
|
||||
rr_graph->rr_node[*cur_node_id].type = IPIN;
|
||||
rr_graph->rr_node[*cur_node_id].xlow = grid_coordinator.get_x();
|
||||
rr_graph->rr_node[*cur_node_id].xhigh = grid_coordinator.get_x();
|
||||
rr_graph->rr_node[*cur_node_id].ylow = grid_coordinator.get_y();
|
||||
rr_graph->rr_node[*cur_node_id].yhigh = grid_coordinator.get_y();
|
||||
rr_graph->rr_node[*cur_node_id].ptc_num = ipin_list[pin];
|
||||
rr_graph->rr_node[*cur_node_id].capacity = 1;
|
||||
rr_graph->rr_node[*cur_node_id].occ = 0;
|
||||
/* cost index is a FIXED value for IPIN */
|
||||
rr_graph->rr_node[*cur_node_id].cost_index = IPIN_COST_INDEX;
|
||||
/* Switch info */
|
||||
rr_graph->rr_node[*cur_node_id].driver_switch = wire_to_ipin_switch;
|
||||
/* fill fast look-up table */
|
||||
load_one_node_to_rr_graph_fast_lookup(rr_graph, *cur_node_id,
|
||||
rr_graph->rr_node[*cur_node_id].type,
|
||||
rr_graph->rr_node[*cur_node_id].xlow,
|
||||
rr_graph->rr_node[*cur_node_id].ylow,
|
||||
rr_graph->rr_node[*cur_node_id].ptc_num);
|
||||
/* Update node counter */
|
||||
(*cur_node_id)++;
|
||||
} /* End of loading IPIN rr_nodes */
|
||||
} /* End of side enumeration */
|
||||
} /* End of height enumeration */
|
||||
} /* End of capacity enumeration */
|
||||
|
||||
/* Consider capacity of the grid */
|
||||
for (int iblk = 0; iblk < cur_grid.type->capacity; ++iblk) {
|
||||
/* Walk through the height of each grid,
|
||||
* get pins and configure the rr_nodes */
|
||||
for (int height = 0; height < cur_grid.type->height; ++height) {
|
||||
/* Set a SOURCE or a SINK rr_node for each class */
|
||||
for (int iclass = 0; iclass < cur_grid.type->num_class; ++iclass) {
|
||||
/* Set a SINK rr_node for the OPIN */
|
||||
|
@ -815,6 +871,10 @@ void load_rr_nodes_basic_info(t_rr_graph* rr_graph,
|
|||
if (EMPTY_TYPE == grids[ix][iy].type) {
|
||||
continue;
|
||||
}
|
||||
/* We only build rr_nodes for grids with offset=0 */
|
||||
if (0 < grids[ix][iy].offset) {
|
||||
continue;
|
||||
}
|
||||
DeviceCoordinator grid_coordinator(ix, iy);
|
||||
enum e_side io_side = NUM_SIDES;
|
||||
/* If this is the block on borders, we consider IO side */
|
||||
|
@ -829,13 +889,29 @@ void load_rr_nodes_basic_info(t_rr_graph* rr_graph,
|
|||
}
|
||||
}
|
||||
|
||||
/* FIXME: DEBUG CODES TO BE REMOVED
|
||||
std::vector<size_t> node_cnt;
|
||||
node_cnt.resize(NUM_RR_TYPES);
|
||||
for (int inode = 0; inode < rr_graph->num_rr_nodes; ++inode) {
|
||||
node_cnt[rr_graph->rr_node[inode].type]++;
|
||||
}
|
||||
vpr_printf(TIO_MESSAGE_INFO, "Load basic information to %lu SOURCE NODE.\n", node_cnt[SOURCE]);
|
||||
vpr_printf(TIO_MESSAGE_INFO, "Load basic information to %lu SINK NODE.\n", node_cnt[SINK]);
|
||||
vpr_printf(TIO_MESSAGE_INFO, "Load basic information to %lu OPIN NODE.\n", node_cnt[OPIN]);
|
||||
vpr_printf(TIO_MESSAGE_INFO, "Load basic information to %lu IPIN NODE.\n", node_cnt[IPIN]);
|
||||
*/
|
||||
|
||||
/* For X-direction Channel: CHANX */
|
||||
for (size_t iy = 0; iy < device_size.get_y() - 1; ++iy) {
|
||||
/* Keep a vector of node_ids for the channels, because we will rotate them when walking through ix */
|
||||
std::vector<size_t> track_node_ids;
|
||||
/* Make sure a clean start */
|
||||
track_node_ids.clear();
|
||||
for (size_t ix = 1; ix < device_size.get_x() - 1; ++ix) {
|
||||
DeviceCoordinator chan_coordinator(ix, iy);
|
||||
enum e_side chan_side = NUM_SIDES;
|
||||
/* For LEFT side of FPGA */
|
||||
if (0 == ix) {
|
||||
if (1 == ix) {
|
||||
chan_side = LEFT;
|
||||
}
|
||||
/* For RIGHT side of FPGA */
|
||||
|
@ -843,37 +919,47 @@ void load_rr_nodes_basic_info(t_rr_graph* rr_graph,
|
|||
chan_side = RIGHT;
|
||||
}
|
||||
ChanNodeDetails chanx_details = build_unidir_chan_node_details(chan_width[0], device_size.get_x() - 2, chan_side, segment_infs);
|
||||
/* Configure CHANX in this channel */
|
||||
load_one_chan_rr_nodes_basic_info(chan_coordinator, CHANX,
|
||||
&chanx_details,
|
||||
segment_infs,
|
||||
CHANX_COST_INDEX_START,
|
||||
rr_graph, &cur_node_id);
|
||||
/* Rotate the chanx_details by an offset of 1*/
|
||||
/* Force node_ids from the previous chanx */
|
||||
if (0 < track_node_ids.size()) {
|
||||
chanx_details.set_track_node_ids(track_node_ids);
|
||||
}
|
||||
/* Rotate the chanx_details by an offset of ix - 1, the distance to the most left channel */
|
||||
/* For INC_DIRECTION, we use clockwise rotation
|
||||
* node_id A ----> -----> node_id D
|
||||
* node_id B ----> / ----> node_id A
|
||||
* node_id C ----> / ----> node_id B
|
||||
* node_id D ----> ----> node_id C
|
||||
*/
|
||||
chanx_details.rotate_track_node_id(1, INC_DIRECTION, false);
|
||||
chanx_details.rotate_track_node_id(ix - 1, INC_DIRECTION, false);
|
||||
/* For DEC_DIRECTION, we use clockwise rotation
|
||||
* node_id A <----- <----- node_id B
|
||||
* node_id B <----- \ <----- node_id C
|
||||
* node_id C <----- \ <----- node_id D
|
||||
* node_id D <----- <----- node_id A
|
||||
*/
|
||||
chanx_details.rotate_track_node_id(1, DEC_DIRECTION, true);
|
||||
chanx_details.rotate_track_node_id(ix - 1, DEC_DIRECTION, true);
|
||||
/* Configure CHANX in this channel */
|
||||
load_one_chan_rr_nodes_basic_info(chan_coordinator, CHANX,
|
||||
&chanx_details,
|
||||
segment_infs,
|
||||
CHANX_COST_INDEX_START,
|
||||
rr_graph, &cur_node_id);
|
||||
/* Get a copy of node_ids */
|
||||
track_node_ids = chanx_details.get_track_node_ids();
|
||||
}
|
||||
}
|
||||
|
||||
/* For Y-direction Channel: CHANX */
|
||||
for (size_t ix = 0; ix < device_size.get_x() - 1; ++ix) {
|
||||
/* Keep a vector of node_ids for the channels, because we will rotate them when walking through ix */
|
||||
std::vector<size_t> track_node_ids;
|
||||
/* Make sure a clean start */
|
||||
track_node_ids.clear();
|
||||
for (size_t iy = 1; iy < device_size.get_y() - 1; ++iy) {
|
||||
DeviceCoordinator chan_coordinator(ix, iy);
|
||||
enum e_side chan_side = NUM_SIDES;
|
||||
/* For LEFT side of FPGA */
|
||||
if (0 == iy) {
|
||||
if (1 == iy) {
|
||||
chan_side = BOTTOM;
|
||||
}
|
||||
/* For RIGHT side of FPGA */
|
||||
|
@ -881,12 +967,10 @@ void load_rr_nodes_basic_info(t_rr_graph* rr_graph,
|
|||
chan_side = TOP;
|
||||
}
|
||||
ChanNodeDetails chany_details = build_unidir_chan_node_details(chan_width[1], device_size.get_y() - 2, chan_side, segment_infs);
|
||||
/* Configure CHANX in this channel */
|
||||
load_one_chan_rr_nodes_basic_info(chan_coordinator, CHANY,
|
||||
&chany_details,
|
||||
segment_infs,
|
||||
CHANX_COST_INDEX_START + segment_infs.size(),
|
||||
rr_graph, &cur_node_id);
|
||||
/* Force node_ids from the previous chanx */
|
||||
if (0 < track_node_ids.size()) {
|
||||
chany_details.set_track_node_ids(track_node_ids);
|
||||
}
|
||||
/* Rotate the chany_details by an offset of 1*/
|
||||
/* For INC_DIRECTION, we use clockwise rotation
|
||||
* node_id A ----> -----> node_id D
|
||||
|
@ -894,14 +978,22 @@ void load_rr_nodes_basic_info(t_rr_graph* rr_graph,
|
|||
* node_id C ----> / ----> node_id B
|
||||
* node_id D ----> ----> node_id C
|
||||
*/
|
||||
chany_details.rotate_track_node_id(1, INC_DIRECTION, false);
|
||||
chany_details.rotate_track_node_id(iy - 1, INC_DIRECTION, false);
|
||||
/* For DEC_DIRECTION, we use clockwise rotation
|
||||
* node_id A <----- <----- node_id B
|
||||
* node_id B <----- \ <----- node_id C
|
||||
* node_id C <----- \ <----- node_id D
|
||||
* node_id D <----- <----- node_id A
|
||||
*/
|
||||
chany_details.rotate_track_node_id(1, DEC_DIRECTION, true);
|
||||
chany_details.rotate_track_node_id(iy - 1, DEC_DIRECTION, true);
|
||||
/* Configure CHANX in this channel */
|
||||
load_one_chan_rr_nodes_basic_info(chan_coordinator, CHANY,
|
||||
&chany_details,
|
||||
segment_infs,
|
||||
CHANX_COST_INDEX_START + segment_infs.size(),
|
||||
rr_graph, &cur_node_id);
|
||||
/* Get a copy of node_ids */
|
||||
track_node_ids = chany_details.get_track_node_ids();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1005,13 +1097,13 @@ void build_rr_graph_edges(t_rr_graph* rr_graph,
|
|||
/* adapt the track_to_ipin_lookup for the GSB nodes */
|
||||
t_track2pin_map track2ipin_map; /* [0..track_gsb_side][0..num_tracks][ipin_indices] */
|
||||
/* Get the Fc index of the grid */
|
||||
int grid_Fc_in_index = grids[grid_coordinator.get_x()][grid_coordinator.get_x()].type->index;
|
||||
int grid_Fc_in_index = grids[grid_coordinator.get_x()][grid_coordinator.get_y()].type->index;
|
||||
track2ipin_map = build_gsb_track_to_ipin_map(rr_graph, rr_gsb, segment_inf, Fc_in[grid_Fc_in_index]);
|
||||
|
||||
/* adapt the opin_to_track_map for the GSB nodes */
|
||||
t_pin2track_map opin2track_map; /* [0..gsb_side][0..num_opin_node][track_indices] */
|
||||
/* Get the Fc index of the grid */
|
||||
int grid_Fc_out_index = grids[grid_coordinator.get_x()][grid_coordinator.get_x()].type->index;
|
||||
int grid_Fc_out_index = grids[grid_coordinator.get_x()][grid_coordinator.get_y()].type->index;
|
||||
opin2track_map = build_gsb_opin_to_track_map(rr_graph, rr_gsb, segment_inf, Fc_out[grid_Fc_out_index]);
|
||||
|
||||
/* adapt the switch_block_conn for the GSB nodes */
|
||||
|
@ -1019,7 +1111,7 @@ void build_rr_graph_edges(t_rr_graph* rr_graph,
|
|||
sb_conn = build_gsb_track_to_track_map(rr_graph, rr_gsb, sb_type, Fs, segment_inf);
|
||||
|
||||
/* Build edges for a GSB */
|
||||
build_edges_for_one_tileable_rr_gsb(rr_graph, &rr_gsb,
|
||||
build_edges_for_one_tileable_rr_gsb(rr_graph, grids, &rr_gsb,
|
||||
track2ipin_map, opin2track_map,
|
||||
sb_conn);
|
||||
/* Finish this GSB, go to the next*/
|
||||
|
@ -1218,9 +1310,6 @@ void build_tileable_unidir_rr_graph(INP const int L_num_types,
|
|||
*Warnings |= RR_GRAPH_WARN_FC_CLIPPED;
|
||||
}
|
||||
|
||||
vpr_printf(TIO_MESSAGE_INFO,
|
||||
"Actual Fc numbers loaded.\n");
|
||||
|
||||
/************************************************************************
|
||||
* 6. Build the connections tile by tile:
|
||||
* We classify rr_nodes into a general switch block (GSB) data structure
|
||||
|
@ -1235,9 +1324,6 @@ void build_tileable_unidir_rr_graph(INP const int L_num_types,
|
|||
Fc_in, Fc_out,
|
||||
sb_type, Fs);
|
||||
|
||||
vpr_printf(TIO_MESSAGE_INFO,
|
||||
"Regular edges of RR graph built.\n");
|
||||
|
||||
/************************************************************************
|
||||
* 7. Build direction connection lists
|
||||
***********************************************************************/
|
||||
|
@ -1249,8 +1335,12 @@ 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);
|
||||
|
||||
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,
|
||||
"Direct-connection edges of RR graph built.\n");
|
||||
"%lu edges of RR graph built.\n", num_edges);
|
||||
|
||||
/************************************************************************
|
||||
* 8. Allocate external data structures
|
||||
|
|
|
@ -131,8 +131,8 @@ bool is_gsb_in_track_cb_population(const RRGSB& rr_gsb,
|
|||
DeviceCoordinator side_coordinator = rr_gsb.get_side_block_coordinator(gsb_side);
|
||||
|
||||
/* Get the offset */
|
||||
size_t offset = (side_coordinator.get_x() - track_node->xlow)
|
||||
+ (side_coordinator.get_y() - track_node->ylow);
|
||||
size_t offset = std::abs((int)side_coordinator.get_x() - track_node->xlow)
|
||||
+ std::abs((int)side_coordinator.get_y() - track_node->ylow);
|
||||
|
||||
/* Get segment id */
|
||||
size_t seg_id = rr_gsb.get_chan_node_segment(gsb_side, track_id);
|
||||
|
@ -170,8 +170,8 @@ bool is_gsb_in_track_sb_population(const RRGSB& rr_gsb,
|
|||
DeviceCoordinator side_coordinator = rr_gsb.get_side_block_coordinator(gsb_side);
|
||||
|
||||
/* Get the offset */
|
||||
size_t offset = (side_coordinator.get_x() - track_node->xlow)
|
||||
+ (side_coordinator.get_y() - track_node->ylow);
|
||||
size_t offset = std::abs((int)side_coordinator.get_x() - track_node->xlow)
|
||||
+ std::abs((int)side_coordinator.get_y() - track_node->ylow);
|
||||
|
||||
/* Get segment id */
|
||||
size_t seg_id = rr_gsb.get_chan_node_segment(gsb_side, track_id);
|
||||
|
@ -198,9 +198,9 @@ std::vector<size_t> get_to_track_list(const int Fs, const int to_track, const in
|
|||
/* TODO: currently, for Fs > 3, I always search the next from_track until Fs is satisfied
|
||||
* The optimal track selection should be done in a more scientific way!!!
|
||||
*/
|
||||
size_t to_track_i = to_track + i;
|
||||
int to_track_i = to_track + i;
|
||||
/* make sure the track id is still in range */
|
||||
if ( to_track_i > (size_t)num_to_tracks) {
|
||||
if ( to_track_i > num_to_tracks) {
|
||||
to_track_i = to_track_i % num_to_tracks;
|
||||
}
|
||||
/* from track must be connected */
|
||||
|
@ -368,6 +368,9 @@ void build_gsb_one_group_track_to_track_map(const t_rr_graph* rr_graph,
|
|||
size_t from_side_index = side_manager.to_size_t();
|
||||
size_t from_track_index = from_tracks[side][inode];
|
||||
size_t to_track_index = to_tracks[to_side_index][to_track_ids[to_track_id]];
|
||||
printf("from_track(size=%lu): %lu , to_track_ids[%lu]:%lu, to_track_index: %lu in a group of %lu tracks\n",
|
||||
from_tracks[side].size(), inode, to_track_id, to_track_ids[to_track_id],
|
||||
to_track_index, to_tracks[to_side_index].size());
|
||||
t_rr_node* to_track_node = rr_gsb.get_chan_node(to_side, to_track_index);
|
||||
(*track2track_map)[from_side_index][from_track_index].push_back(to_track_node - rr_graph->rr_node);
|
||||
}
|
||||
|
@ -453,11 +456,11 @@ t_track2track_map build_gsb_track_to_track_map(const t_rr_graph* rr_graph,
|
|||
switch (track_status) {
|
||||
case TRACK_START:
|
||||
/* update starting track list */
|
||||
start_tracks[gsb_side].push_back(inode);
|
||||
start_tracks[side].push_back(inode);
|
||||
break;
|
||||
case TRACK_END:
|
||||
/* Update end track list */
|
||||
end_tracks[gsb_side].push_back(inode);
|
||||
end_tracks[side].push_back(inode);
|
||||
break;
|
||||
case TRACK_PASS:
|
||||
/* We need to check Switch block population of this track
|
||||
|
@ -465,7 +468,7 @@ t_track2track_map build_gsb_track_to_track_map(const t_rr_graph* rr_graph,
|
|||
*/
|
||||
if (true == is_gsb_in_track_sb_population(rr_gsb, gsb_side, inode, segment_inf)) {
|
||||
/* Update passing track list */
|
||||
pass_tracks[gsb_side].push_back(inode);
|
||||
pass_tracks[side].push_back(inode);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
@ -917,6 +920,17 @@ void add_one_edge_for_two_rr_nodes(const t_rr_graph* rr_graph,
|
|||
return;
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* Get the class index of a grid pin
|
||||
***********************************************************************/
|
||||
static
|
||||
int get_grid_pin_class_index(const t_grid_tile& cur_grid,
|
||||
const int pin_index) {
|
||||
/* check */
|
||||
assert ( pin_index < cur_grid.type->num_pins);
|
||||
return cur_grid.type->pin_class[pin_index];
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* Create edges for each rr_node of a General Switch Blocks (GSB):
|
||||
* 1. create edges between SOURCE and OPINs
|
||||
|
@ -925,7 +939,9 @@ void add_one_edge_for_two_rr_nodes(const t_rr_graph* rr_graph,
|
|||
* 4. create edges between OPINs, CHANX and CHANY (connections inside switch blocks)
|
||||
* 5. create edges between OPINs and IPINs (direct-connections)
|
||||
***********************************************************************/
|
||||
void build_edges_for_one_tileable_rr_gsb(const t_rr_graph* rr_graph, const RRGSB* rr_gsb,
|
||||
void build_edges_for_one_tileable_rr_gsb(const t_rr_graph* rr_graph,
|
||||
const std::vector< std::vector<t_grid_tile> > grids,
|
||||
const RRGSB* rr_gsb,
|
||||
const t_track2pin_map track2ipin_map,
|
||||
const t_pin2track_map opin2track_map,
|
||||
const t_track2track_map track2track_map) {
|
||||
|
@ -940,9 +956,10 @@ void build_edges_for_one_tileable_rr_gsb(const t_rr_graph* rr_graph, const RRGSB
|
|||
/* Find OPINs */
|
||||
for (size_t inode = 0; inode < rr_gsb->get_num_opin_nodes(gsb_side); ++inode) {
|
||||
t_rr_node* opin_node = rr_gsb->get_opin_node(gsb_side, inode);
|
||||
int src_node_ptc_num = get_grid_pin_class_index(grids[opin_node->xlow][opin_node->ylow], opin_node->ptc_num);
|
||||
/* 1. create edges between SOURCE and OPINs */
|
||||
int src_node_id = get_rr_node_index(opin_node->xlow, opin_node->ylow,
|
||||
SOURCE, opin_node->ptc_num,
|
||||
SOURCE, src_node_ptc_num,
|
||||
rr_graph->rr_node_indices);
|
||||
/* add edges to the src_node */
|
||||
add_one_edge_for_two_rr_nodes(rr_graph, src_node_id, opin_node - rr_graph->rr_node,
|
||||
|
@ -960,27 +977,38 @@ void build_edges_for_one_tileable_rr_gsb(const t_rr_graph* rr_graph, const RRGSB
|
|||
/* Find IPINs */
|
||||
for (size_t inode = 0; inode < rr_gsb->get_num_ipin_nodes(gsb_side); ++inode) {
|
||||
t_rr_node* ipin_node = rr_gsb->get_ipin_node(gsb_side, inode);
|
||||
int sink_node_ptc_num = get_grid_pin_class_index(grids[ipin_node->xlow][ipin_node->ylow], ipin_node->ptc_num);
|
||||
/* 3. create edges between IPINs and SINKs */
|
||||
int sink_node_id = get_rr_node_index(ipin_node->xlow, ipin_node->ylow,
|
||||
SINK, ipin_node->ptc_num,
|
||||
SINK, sink_node_ptc_num,
|
||||
rr_graph->rr_node_indices);
|
||||
/* add edges to connect the IPIN node to SINK nodes */
|
||||
add_one_edge_for_two_rr_nodes(rr_graph, ipin_node - rr_graph->rr_node, sink_node_id,
|
||||
rr_graph->rr_node[sink_node_id].driver_switch);
|
||||
}
|
||||
/* Find CHANX or CHANY */
|
||||
/* For TRACKs to IPINs, we only care LEFT and TOP sides
|
||||
* Skip RIGHT and BOTTOM for the ipin2track_map since they should be handled in other GSBs
|
||||
*/
|
||||
if ( (side_manager.get_side() == rr_gsb->get_cb_chan_side(CHANX))
|
||||
|| (side_manager.get_side() == rr_gsb->get_cb_chan_side(CHANY)) ) {
|
||||
/* 4. create edges between CHANX|CHANY and IPINs, using ipin2track_map */
|
||||
for (size_t inode = 0; inode < rr_gsb->get_chan_width(gsb_side); ++inode) {
|
||||
t_rr_node* chan_node = rr_gsb->get_chan_node(gsb_side, inode);
|
||||
int num_edges = track2ipin_map[side_manager.to_size_t()][inode].size();
|
||||
for (int iedge = 0; iedge < num_edges; ++iedge) {
|
||||
int ipin_node_id = track2ipin_map[side_manager.to_size_t()][inode][iedge];
|
||||
/* add edges to the chan_node */
|
||||
add_one_edge_for_two_rr_nodes(rr_graph, chan_node - rr_graph->rr_node, ipin_node_id,
|
||||
rr_graph->rr_node[ipin_node_id].driver_switch);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 5. create edges between CHANX|CHANY and CHANX|CHANY, using track2track_map */
|
||||
for (size_t inode = 0; inode < rr_gsb->get_chan_width(gsb_side); ++inode) {
|
||||
t_rr_node* chan_node = rr_gsb->get_chan_node(gsb_side, inode);
|
||||
/* 4. create edges between CHANX|CHANY and IPINs, using ipin2track_map */
|
||||
int num_edges = track2ipin_map[side_manager.to_size_t()][inode].size();
|
||||
for (int iedge = 0; iedge < num_edges; ++iedge) {
|
||||
int ipin_node_id = track2ipin_map[side_manager.to_size_t()][inode][iedge];
|
||||
/* add edges to the chan_node */
|
||||
add_one_edge_for_two_rr_nodes(rr_graph, chan_node - rr_graph->rr_node, ipin_node_id,
|
||||
rr_graph->rr_node[ipin_node_id].driver_switch);
|
||||
}
|
||||
/* 5. create edges between CHANX|CHANY and CHANX|CHANY, using track2track_map */
|
||||
num_edges = track2track_map[side_manager.to_size_t()][inode].size();
|
||||
int num_edges = track2track_map[side_manager.to_size_t()][inode].size();
|
||||
for (int iedge = 0; iedge < num_edges; ++iedge) {
|
||||
int track_node_id = track2track_map[side_manager.to_size_t()][inode][iedge];
|
||||
/* add edges to the chan_node */
|
||||
|
@ -1015,6 +1043,7 @@ void build_gsb_one_ipin_track2pin_map(const t_rr_graph* rr_graph,
|
|||
t_track2pin_map* track2ipin_map) {
|
||||
/* Get a list of segment_ids*/
|
||||
enum e_side chan_side = rr_gsb.get_cb_chan_side(ipin_side);
|
||||
Side chan_side_manager(chan_side);
|
||||
std::vector<size_t> seg_list = rr_gsb.get_chan_segment_ids(chan_side);
|
||||
size_t chan_width = rr_gsb.get_chan_width(chan_side);
|
||||
Side ipin_side_manager(ipin_side);
|
||||
|
@ -1058,11 +1087,11 @@ void build_gsb_one_ipin_track2pin_map(const t_rr_graph* rr_graph,
|
|||
/* Assign tracks: since we assign 2 track per round, we increment itrack by 2* step */
|
||||
for (size_t itrack = 0; itrack < actual_track_list.size(); itrack = itrack + 2 * track_step) {
|
||||
/* Update pin2track map */
|
||||
size_t ipin_side_index = ipin_side_manager.to_size_t();
|
||||
size_t chan_side_index = chan_side_manager.to_size_t();
|
||||
size_t track_index = actual_track_list[itrack];
|
||||
size_t ipin_index = ipin_node - rr_graph->rr_node;
|
||||
(*track2ipin_map)[ipin_side_index][track_index].push_back(ipin_index);
|
||||
(*track2ipin_map)[ipin_side_index][track_index + 1].push_back(ipin_index);
|
||||
(*track2ipin_map)[chan_side_index][track_index].push_back(ipin_index);
|
||||
(*track2ipin_map)[chan_side_index][track_index + 1].push_back(ipin_index);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1181,14 +1210,15 @@ t_track2pin_map build_gsb_track_to_ipin_map(t_rr_graph* rr_graph,
|
|||
/* This track2pin mapping is for Connection Blocks, so we only care two sides! */
|
||||
/* Get channel width and resize the matrix */
|
||||
size_t chan_width = rr_gsb.get_chan_width(chan_side);
|
||||
track2ipin_map[side].resize(chan_width);
|
||||
track2ipin_map[chan_side_manager.to_size_t()].resize(chan_width);
|
||||
/* Find the ipin/opin nodes */
|
||||
for (size_t inode = 0; inode < rr_gsb.get_num_ipin_nodes(ipin_side); ++inode) {
|
||||
t_rr_node* ipin_node = rr_gsb.get_ipin_node(ipin_side, inode);
|
||||
/* Get Fc of the ipin */
|
||||
int ipin_Fc = Fc_in[ipin_node->ptc_num];
|
||||
/* skip Fc = 0 */
|
||||
if (0 == ipin_Fc) {
|
||||
if ( (-1 == ipin_Fc)
|
||||
|| (0 == ipin_Fc) ) {
|
||||
continue;
|
||||
}
|
||||
/* Build track2ipin_map for this IPIN */
|
||||
|
@ -1249,7 +1279,9 @@ t_pin2track_map build_gsb_opin_to_track_map(t_rr_graph* rr_graph,
|
|||
/* Get Fc of the ipin */
|
||||
int opin_Fc = Fc_out[opin_node->ptc_num];
|
||||
/* skip Fc = 0 */
|
||||
if (0 == opin_Fc) {
|
||||
printf("opin_Fc[%d]=%d\n", opin_node->ptc_num, opin_Fc);
|
||||
if ( (-1 == opin_Fc)
|
||||
|| (0 == opin_Fc) ) {
|
||||
continue;
|
||||
}
|
||||
/* Build track2ipin_map for this IPIN */
|
||||
|
|
|
@ -31,7 +31,9 @@ RRGSB build_one_tileable_rr_gsb(const DeviceCoordinator& device_range,
|
|||
const DeviceCoordinator& gsb_coordinator,
|
||||
t_rr_graph* rr_graph);
|
||||
|
||||
void build_edges_for_one_tileable_rr_gsb(const t_rr_graph* rr_graph, const RRGSB* rr_gsb,
|
||||
void build_edges_for_one_tileable_rr_gsb(const t_rr_graph* rr_graph,
|
||||
const std::vector< std::vector<t_grid_tile> > grids,
|
||||
const RRGSB* rr_gsb,
|
||||
const t_track2pin_map track2ipin_map,
|
||||
const t_pin2track_map opin2track_map,
|
||||
const t_track2track_map track2track_map);
|
||||
|
|
|
@ -692,6 +692,9 @@ alloc_and_load_actual_fc(INP int L_num_types, INP t_type_ptr types,
|
|||
float *Fc = (float *) my_malloc(sizeof(float) * types[i].num_pins); /* [0..num_pins-1] */
|
||||
for (j = 0; j < types[i].num_pins; ++j) {
|
||||
Fc[j] = types[i].Fc[j];
|
||||
|
||||
/* Xifan Tang: give an initial value! */
|
||||
/* Result[i][j] = 0; */
|
||||
|
||||
if(Fc[j] == 0 && ignore_Fc_0 == FALSE) {
|
||||
/* Special case indicating that this pin does not connect to general-purpose routing */
|
||||
|
|
Loading…
Reference in New Issue