Add rotate one side of switch block functionality
This commit is contained in:
parent
858a323228
commit
22e71f5847
|
@ -916,33 +916,40 @@ void RRSwitchBlock::set_conf_bits_msb(size_t conf_bits_msb) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* rotate all the channel nodes by a given offset */
|
/* rotate all the channel nodes by a given offset */
|
||||||
void RRSwitchBlock::rotate_full_chan_node(size_t offset) {
|
void RRSwitchBlock::rotate_side_chan_node(enum e_side side, size_t offset) {
|
||||||
/* Rotate chan nodes on each side */
|
|
||||||
for (size_t side = 0; side < get_num_sides(); ++side) {
|
|
||||||
Side side_manager(side);
|
Side side_manager(side);
|
||||||
/* Partition the chan nodes on this side, depending on its length */
|
/* Partition the chan nodes on this side, depending on its length */
|
||||||
/* skip this side if there is no nodes */
|
/* skip this side if there is no nodes */
|
||||||
if (0 == get_chan_width(side_manager.get_side())) {
|
if (0 == get_chan_width(side)) {
|
||||||
continue;
|
return;
|
||||||
}
|
}
|
||||||
size_t adapt_offset = offset % get_chan_width(side_manager.get_side());
|
size_t adapt_offset = offset % get_chan_width(side);
|
||||||
assert(adapt_offset < get_chan_width(side_manager.get_side()));
|
assert(adapt_offset < get_chan_width(side));
|
||||||
/* Find a group split, rotate */
|
/* Find a group split, rotate */
|
||||||
chan_node_[side].rotate(adapt_offset);
|
chan_node_[side_manager.to_size_t()].rotate(adapt_offset);
|
||||||
std::rotate(chan_node_direction_[side].begin(),
|
std::rotate(chan_node_direction_[side_manager.to_size_t()].begin(),
|
||||||
chan_node_direction_[side].begin() + adapt_offset,
|
chan_node_direction_[side_manager.to_size_t()].begin() + adapt_offset,
|
||||||
chan_node_direction_[side].end());
|
chan_node_direction_[side_manager.to_size_t()].end());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* rotate all the channel nodes by a given offset */
|
||||||
|
void RRSwitchBlock::rotate_chan_node(size_t offset) {
|
||||||
|
/* Rotate chan nodes on each side */
|
||||||
|
for (size_t side = 0; side < get_num_sides(); ++side) {
|
||||||
|
Side side_manager(side);
|
||||||
|
rotate_side_chan_node(side_manager.get_side(), offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* rotate all the channel nodes by a given offset:
|
/* rotate all the channel nodes by a given offset:
|
||||||
* Routing Channel nodes are divided into different groups using segment ids
|
* Routing Channel nodes are divided into different groups using segment ids
|
||||||
* each group is rotated separatedly
|
* each group is rotated separatedly
|
||||||
*/
|
*/
|
||||||
void RRSwitchBlock::rotate_chan_node(size_t offset) {
|
void RRSwitchBlock::rotate_chan_node_in_group(size_t offset) {
|
||||||
/* Rotate chan nodes on each side */
|
/* Rotate chan nodes on each side */
|
||||||
for (size_t side = 0; side < get_num_sides(); ++side) {
|
for (size_t side = 0; side < get_num_sides(); ++side) {
|
||||||
Side side_manager(side);
|
Side side_manager(side);
|
||||||
|
@ -985,28 +992,30 @@ void RRSwitchBlock::rotate_chan_node(size_t offset) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* rotate all the opin nodes by a given offset */
|
/* rotate one side of the opin nodes by a given offset
|
||||||
void RRSwitchBlock::rotate_opin_node(size_t offset) {
|
* OPIN nodes are divided into different groups depending on their grid
|
||||||
|
* each group is rotated separatedly
|
||||||
|
*/
|
||||||
|
void RRSwitchBlock::rotate_side_opin_node_in_group(enum e_side side, size_t offset) {
|
||||||
/* Rotate opin nodes on each side */
|
/* Rotate opin nodes on each side */
|
||||||
for (size_t side = 0; side < get_num_sides(); ++side) {
|
|
||||||
Side side_manager(side);
|
Side side_manager(side);
|
||||||
size_t rotate_begin = 0;
|
size_t rotate_begin = 0;
|
||||||
size_t rotate_end = 0;
|
size_t rotate_end = 0;
|
||||||
/* skip this side if there is no nodes */
|
/* skip this side if there is no nodes */
|
||||||
if (0 == get_num_opin_nodes(side_manager.get_side())) {
|
if (0 == get_num_opin_nodes(side)) {
|
||||||
continue;
|
return;
|
||||||
}
|
}
|
||||||
/* Partition the opin nodes on this side, depending on grids */
|
/* Partition the opin nodes on this side, depending on grids */
|
||||||
for (size_t inode = 0; inode < get_num_opin_nodes(side_manager.get_side()) - 1; ++inode) {
|
for (size_t inode = 0; inode < get_num_opin_nodes(side) - 1; ++inode) {
|
||||||
if ( ( (opin_node_[side][inode]->xlow != opin_node_[side][inode + 1]->xlow)
|
if ( ( (opin_node_[side_manager.to_size_t()][inode]->xlow != opin_node_[side_manager.to_size_t()][inode + 1]->xlow)
|
||||||
|| (opin_node_[side][inode]->ylow != opin_node_[side][inode + 1]->ylow)
|
|| (opin_node_[side_manager.to_size_t()][inode]->ylow != opin_node_[side_manager.to_size_t()][inode + 1]->ylow)
|
||||||
|| (opin_node_[side][inode]->xhigh != opin_node_[side][inode + 1]->xhigh)
|
|| (opin_node_[side_manager.to_size_t()][inode]->xhigh != opin_node_[side_manager.to_size_t()][inode + 1]->xhigh)
|
||||||
|| (opin_node_[side][inode]->yhigh != opin_node_[side][inode + 1]->yhigh)
|
|| (opin_node_[side_manager.to_size_t()][inode]->yhigh != opin_node_[side_manager.to_size_t()][inode + 1]->yhigh)
|
||||||
|| (opin_node_grid_side_[side][inode] != opin_node_grid_side_[side][inode + 1]))
|
|| (opin_node_grid_side_[side_manager.to_size_t()][inode] != opin_node_grid_side_[side_manager.to_size_t()][inode + 1]))
|
||||||
|| ( inode == get_num_opin_nodes(side_manager.get_side()) - 2) ) {
|
|| ( inode == get_num_opin_nodes(side) - 2) ) {
|
||||||
/* Record the upper bound */
|
/* Record the upper bound */
|
||||||
if ( inode == get_num_opin_nodes(side_manager.get_side()) - 2) {
|
if ( inode == get_num_opin_nodes(side) - 2) {
|
||||||
rotate_end = get_num_opin_nodes(side_manager.get_side()) - 1;
|
rotate_end = get_num_opin_nodes(side) - 1;
|
||||||
} else {
|
} else {
|
||||||
rotate_end = inode;
|
rotate_end = inode;
|
||||||
}
|
}
|
||||||
|
@ -1020,16 +1029,30 @@ void RRSwitchBlock::rotate_opin_node(size_t offset) {
|
||||||
/* Make sure offset is in range */
|
/* Make sure offset is in range */
|
||||||
assert (adapt_offset < rotate_end - rotate_begin + 1);
|
assert (adapt_offset < rotate_end - rotate_begin + 1);
|
||||||
/* Find a group split, rotate */
|
/* Find a group split, rotate */
|
||||||
std::rotate(opin_node_[side].begin() + rotate_begin,
|
std::rotate(opin_node_[side_manager.to_size_t()].begin() + rotate_begin,
|
||||||
opin_node_[side].begin() + rotate_begin + adapt_offset,
|
opin_node_[side_manager.to_size_t()].begin() + rotate_begin + adapt_offset,
|
||||||
opin_node_[side].begin() + rotate_end);
|
opin_node_[side_manager.to_size_t()].begin() + rotate_end);
|
||||||
std::rotate(opin_node_grid_side_[side].begin() + rotate_begin,
|
std::rotate(opin_node_grid_side_[side_manager.to_size_t()].begin() + rotate_begin,
|
||||||
opin_node_grid_side_[side].begin() + rotate_begin + adapt_offset,
|
opin_node_grid_side_[side_manager.to_size_t()].begin() + rotate_begin + adapt_offset,
|
||||||
opin_node_grid_side_[side].begin() + rotate_end);
|
opin_node_grid_side_[side_manager.to_size_t()].begin() + rotate_end);
|
||||||
/* Update the lower bound */
|
/* Update the lower bound */
|
||||||
rotate_begin = inode + 1;
|
rotate_begin = inode + 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* rotate all the opin nodes by a given offset
|
||||||
|
* OPIN nodes are divided into different groups depending on their grid
|
||||||
|
* each group is rotated separatedly
|
||||||
|
*/
|
||||||
|
void RRSwitchBlock::rotate_opin_node_in_group(size_t offset) {
|
||||||
|
/* Rotate opin nodes on each side */
|
||||||
|
for (size_t side = 0; side < get_num_sides(); ++side) {
|
||||||
|
Side side_manager(side);
|
||||||
|
rotate_side_opin_node_in_group(side_manager.get_side(), offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
@ -1037,8 +1060,15 @@ void RRSwitchBlock::rotate_opin_node(size_t offset) {
|
||||||
|
|
||||||
/* rotate all the channel and opin nodes by a given offset */
|
/* rotate all the channel and opin nodes by a given offset */
|
||||||
void RRSwitchBlock::rotate(size_t offset) {
|
void RRSwitchBlock::rotate(size_t offset) {
|
||||||
rotate_full_chan_node(offset);
|
rotate_chan_node(offset);
|
||||||
rotate_opin_node(offset);
|
rotate_opin_node_in_group(offset);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* rotate one side of the channel and opin nodes by a given offset */
|
||||||
|
void RRSwitchBlock::rotate_side(enum e_side side, size_t offset) {
|
||||||
|
rotate_side_chan_node(side, offset);
|
||||||
|
rotate_side_opin_node_in_group(side, offset);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1426,6 +1456,38 @@ void DeviceRRSwitchBlock::add_rr_switch_block(DeviceCoordinator& coordinator,
|
||||||
rr_switch_block_rotatable_mirror_id_[coordinator.get_x()][coordinator.get_y()] = mirror_id;
|
rr_switch_block_rotatable_mirror_id_[coordinator.get_x()][coordinator.get_y()] = mirror_id;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
/* For the copy, try 3 types of rotation and examine is_mirror
|
||||||
|
* Rotate only the X-direction nodes: LEFT and RIGHT
|
||||||
|
* Rotate only the Y-direction nodes: TOP and BOTTOM
|
||||||
|
* Rotate both X- and Y-direction nodes
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Rotate LEFT and RIGHT only */
|
||||||
|
RRSwitchBlock rotate_x_mirror = rotate_mirror;
|
||||||
|
rotate_x_mirror.rotate_side(LEFT, 1);
|
||||||
|
rotate_x_mirror.rotate_side(RIGHT, 1);
|
||||||
|
if (true == get_switch_block(rotatable_mirror_[mirror_id]).is_mirror(rotate_x_mirror)) {
|
||||||
|
/* This is a mirror, raise the flag and we finish */
|
||||||
|
is_rotatable_mirror = false;
|
||||||
|
/* Record the id of unique mirror */
|
||||||
|
rr_switch_block_rotatable_mirror_id_[coordinator.get_x()][coordinator.get_y()] = mirror_id;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Rotate TOP and BOTTOM only */
|
||||||
|
RRSwitchBlock rotate_y_mirror = rotate_mirror;
|
||||||
|
rotate_y_mirror.rotate_side(TOP, 1);
|
||||||
|
rotate_y_mirror.rotate_side(BOTTOM, 1);
|
||||||
|
|
||||||
|
if (true == get_switch_block(rotatable_mirror_[mirror_id]).is_mirror(rotate_y_mirror)) {
|
||||||
|
/* This is a mirror, raise the flag and we finish */
|
||||||
|
is_rotatable_mirror = false;
|
||||||
|
/* Record the id of unique mirror */
|
||||||
|
rr_switch_block_rotatable_mirror_id_[coordinator.get_x()][coordinator.get_y()] = mirror_id;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Rotate all sides */
|
||||||
rotate_mirror.rotate(1);
|
rotate_mirror.rotate(1);
|
||||||
}
|
}
|
||||||
if (false == is_rotatable_mirror) {
|
if (false == is_rotatable_mirror) {
|
||||||
|
|
|
@ -167,9 +167,12 @@ class RRSwitchBlock {
|
||||||
void set_num_reserved_conf_bits(size_t num_reserved_conf_bits);
|
void set_num_reserved_conf_bits(size_t num_reserved_conf_bits);
|
||||||
void set_conf_bits_lsb(size_t conf_bits_lsb);
|
void set_conf_bits_lsb(size_t conf_bits_lsb);
|
||||||
void set_conf_bits_msb(size_t conf_bits_msb);
|
void set_conf_bits_msb(size_t conf_bits_msb);
|
||||||
void rotate_full_chan_node(size_t offset); /* rotate all the channel nodes by a given offset */
|
void rotate_side_chan_node(enum e_side side, size_t offset); /* rotate all the channel nodes by a given offset */
|
||||||
void rotate_chan_node(size_t offset); /* rotate all the channel nodes by a given offset */
|
void rotate_chan_node(size_t offset); /* rotate all the channel nodes by a given offset */
|
||||||
void rotate_opin_node(size_t offset); /* rotate all the opin nodes by a given offset */
|
void rotate_chan_node_in_group(size_t offset); /* rotate all the channel nodes by a given offset */
|
||||||
|
void rotate_side_opin_node_in_group(enum e_side side, size_t offset); /* rotate all the opin nodes by a given offset */
|
||||||
|
void rotate_opin_node_in_group(size_t offset); /* rotate all the opin nodes by a given offset */
|
||||||
|
void rotate_side(enum e_side side, size_t offset); /* rotate all the channel and opin nodes by a given offset */
|
||||||
void rotate(size_t offset); /* rotate all the channel and opin nodes by a given offset */
|
void rotate(size_t offset); /* rotate all the channel and opin nodes by a given offset */
|
||||||
void clear();
|
void clear();
|
||||||
void clear_chan_nodes(enum e_side node_side); /* Clean the chan_width of a side */
|
void clear_chan_nodes(enum e_side node_side); /* Clean the chan_width of a side */
|
||||||
|
|
Loading…
Reference in New Issue