Add rotate one side of switch block functionality

This commit is contained in:
tangxifan 2019-05-25 22:48:07 -06:00
parent 858a323228
commit 22e71f5847
2 changed files with 126 additions and 61 deletions

View File

@ -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) {

View File

@ -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 */