developed new rotating methods for RRSwitchBlocks, debugging ongoing

This commit is contained in:
tangxifan 2019-05-26 23:35:30 -06:00
parent 4b852afeac
commit 1bea9870fc
5 changed files with 334 additions and 89 deletions

View File

@ -81,6 +81,7 @@ int get_spice_model_num_tedges_per_pin(t_spice_model* cur_spice_model,
continue; /* ALL output ports requires a tedge */
}
num_tedges += cur_spice_model->ports[iport].size;
break;
case OUT_PORT:
if (SPICE_MODEL_PORT_OUTPUT == cur_spice_model->ports[iport].type) {
continue; /* ALL non-output ports requires a tedge */

View File

@ -80,12 +80,6 @@ RRChan build_one_rr_chan(t_rr_type chan_type, size_t chan_x, size_t chan_y,
void print_device_rr_chan_stats(DeviceRRChan& device_rr_chan);
static
RRSwitchBlock build_rr_switch_block(int sb_x, int sb_y,
int LL_num_rr_nodes, t_rr_node* LL_rr_node,
t_ivec*** LL_rr_node_indices, int num_segments,
t_rr_indexed_data* LL_rr_indexed_data);
/***** subroutines *****/
void assign_switch_block_mirror(t_sb* src, t_sb* des) {
assert ( (NULL != src) && (NULL != des) );
@ -830,7 +824,8 @@ DeviceRRChan build_device_rr_chan(int LL_num_rr_nodes, t_rr_node* LL_rr_node,
* For channels chanX with DEC_DIRECTION on the right side, they should be marked as inputs
*/
static
RRSwitchBlock build_rr_switch_block(int sb_x, int sb_y,
RRSwitchBlock build_rr_switch_block(DeviceCoordinator device_range,
size_t sb_x, size_t sb_y,
int LL_num_rr_nodes, t_rr_node* LL_rr_node,
t_ivec*** LL_rr_node_indices, int num_segments,
t_rr_indexed_data* LL_rr_indexed_data) {
@ -838,11 +833,11 @@ RRSwitchBlock build_rr_switch_block(int sb_x, int sb_y,
RRSwitchBlock rr_switch_block;
/* Check */
assert((!(0 > sb_x))&&(!(sb_x > (nx + 1))));
assert((!(0 > sb_y))&&(!(sb_y > (ny + 1))));
assert(sb_x <= device_range.get_x());
assert(sb_y <= device_range.get_y());
/* Coordinator initialization */
rr_switch_block.set_coordinator(size_t(sb_x), size_t(sb_y));
rr_switch_block.set_coordinator(sb_x, sb_y);
/* Basic information*/
rr_switch_block.init_num_sides(4); /* Fixed number of sides */
@ -852,8 +847,8 @@ RRSwitchBlock build_rr_switch_block(int sb_x, int sb_y,
for (size_t side = 0; side < rr_switch_block.get_num_sides(); ++side) {
/* Local variables inside this for loop */
Side side_manager(side);
int ix = 0;
int iy = 0;
size_t ix = 0;
size_t iy = 0;
RRChan rr_chan;
int temp_num_opin_rr_nodes[2] = {0,0};
t_rr_node** temp_opin_rr_node[2] = {NULL, NULL};
@ -862,7 +857,7 @@ RRSwitchBlock build_rr_switch_block(int sb_x, int sb_y,
switch (side) {
case 0: /* TOP */
/* For the bording, we should take special care */
if (sb_y == ny) {
if (sb_y == device_range.get_y()) {
rr_switch_block.clear_one_side(side_manager.get_side());
break;
}
@ -894,7 +889,7 @@ RRSwitchBlock build_rr_switch_block(int sb_x, int sb_y,
break;
case 1: /* RIGHT */
/* For the bording, we should take special care */
if (sb_x == nx) {
if (sb_x == device_range.get_x()) {
rr_switch_block.clear_one_side(side_manager.get_side());
break;
}
@ -1042,6 +1037,123 @@ RRSwitchBlock build_rr_switch_block(int sb_x, int sb_y,
return rr_switch_block;
}
/* Rotate the Switch block and try to add to rotatable mirrors */
static
RRSwitchBlock rotate_rr_switch_block_for_mirror(DeviceCoordinator& device_range,
RRSwitchBlock& rr_switch_block) {
RRSwitchBlock rotated_rr_switch_block = rr_switch_block;
/* For the 4 Switch Blocks at the four corners */
/* 1. BOTTOM-LEFT corner:
* nothing to do. This is the base we like
*/
if ( ( 0 == rotated_rr_switch_block.get_x())
|| ( 0 == rotated_rr_switch_block.get_y()) ) {
return rotated_rr_switch_block;
}
/* 2. TOP-LEFT corner:
* swap the opin_node between TOP and BOTTOM,
* swap the chan_node between TOP and BOTTOM,
*/
if ( ( 0 == rotated_rr_switch_block.get_x())
|| (device_range.get_y() == rotated_rr_switch_block.get_y()) ) {
rotated_rr_switch_block.swap_opin_node(TOP, BOTTOM);
rotated_rr_switch_block.swap_chan_node(TOP, BOTTOM);
rotated_rr_switch_block.mirror_side_chan_node_direction(TOP);
rotated_rr_switch_block.mirror_side_chan_node_direction(BOTTOM);
return rotated_rr_switch_block;
}
/* 3. TOP-RIGHT corner:
* swap the opin_node between TOP and BOTTOM,
* swap the chan_node between TOP and BOTTOM,
* swap the opin_node between LEFT and RIGHT,
* swap the chan_node between LEFT and RIGHT,
*/
if ( (device_range.get_x() == rotated_rr_switch_block.get_x())
|| (device_range.get_y() == rotated_rr_switch_block.get_y()) ) {
rotated_rr_switch_block.swap_opin_node(TOP, BOTTOM);
rotated_rr_switch_block.swap_chan_node(TOP, BOTTOM);
return rotated_rr_switch_block;
rotated_rr_switch_block.mirror_side_chan_node_direction(TOP);
rotated_rr_switch_block.mirror_side_chan_node_direction(BOTTOM);
rotated_rr_switch_block.swap_opin_node(LEFT, RIGHT);
rotated_rr_switch_block.swap_chan_node(LEFT, RIGHT);
rotated_rr_switch_block.mirror_side_chan_node_direction(LEFT);
rotated_rr_switch_block.mirror_side_chan_node_direction(RIGHT);
return rotated_rr_switch_block;
}
/* 4. BOTTOM-RIGHT corner:
* swap the opin_node between LEFT and RIGHT,
* swap the chan_node between LEFT and RIGHT,
*/
if ( (device_range.get_x() == rotated_rr_switch_block.get_x())
|| (0 == rotated_rr_switch_block.get_y()) ) {
rotated_rr_switch_block.swap_opin_node(LEFT, RIGHT);
rotated_rr_switch_block.swap_chan_node(LEFT, RIGHT);
rotated_rr_switch_block.mirror_side_chan_node_direction(LEFT);
rotated_rr_switch_block.mirror_side_chan_node_direction(RIGHT);
return rotated_rr_switch_block;
}
/* For Switch blocks on the borders */
/* 1. BOTTOM side:
* nothing to do. This is the base we like
*/
if ( 0 == rotated_rr_switch_block.get_y()) {
return rotated_rr_switch_block;
}
/* 2. TOP side:
* swap the opin_node between TOP and BOTTOM,
* swap the chan_node between TOP and BOTTOM,
*/
if (device_range.get_y() == rotated_rr_switch_block.get_y() ) {
rotated_rr_switch_block.swap_opin_node(TOP, BOTTOM);
rotated_rr_switch_block.swap_chan_node(TOP, BOTTOM);
rotated_rr_switch_block.mirror_side_chan_node_direction(TOP);
rotated_rr_switch_block.mirror_side_chan_node_direction(BOTTOM);
return rotated_rr_switch_block;
}
/* 3. RIGHT side:
* swap the opin_node between LEFT and RIGHT,
* swap the chan_node between LEFT and RIGHT,
*/
if (device_range.get_x() == rotated_rr_switch_block.get_x() ) {
rotated_rr_switch_block.swap_opin_node(LEFT, RIGHT);
rotated_rr_switch_block.swap_chan_node(LEFT, RIGHT);
rotated_rr_switch_block.mirror_side_chan_node_direction(LEFT);
rotated_rr_switch_block.mirror_side_chan_node_direction(RIGHT);
return rotated_rr_switch_block;
}
/* 4. LEFT side:
* nothing to do. This is the base we like
*/
if (0 == rotated_rr_switch_block.get_x() ) {
return rotated_rr_switch_block;
}
/* Reach here, it means we have a SB at the center region */
/* For TOP SIDE: Y-channel in INC_DIRECTION, rotate by an offset of its y-coordinator */
rotated_rr_switch_block.rotate_side_chan_node_by_direction(TOP, INC_DIRECTION, rotated_rr_switch_block.get_y() - 1);
/* Rotate the same nodes on the opposite side */
rotated_rr_switch_block.rotate_side_chan_node_by_direction(BOTTOM, INC_DIRECTION, rotated_rr_switch_block.get_y() - 1);
/* For RIGHT SIDE: X-channel in INC_DIRECTION, rotate by an offset of its x-coordinator */
rotated_rr_switch_block.rotate_side_chan_node_by_direction(RIGHT, INC_DIRECTION, rotated_rr_switch_block.get_x() - 1);
/* Rotate the same nodes on the opposite side */
rotated_rr_switch_block.rotate_side_chan_node_by_direction(LEFT, INC_DIRECTION, rotated_rr_switch_block.get_x() - 1);
/* For BOTTOM SIDE: Y-channel in DEC_DIRECTION, rotate by an offset of its y-coordinator */
rotated_rr_switch_block.counter_rotate_side_chan_node_by_direction(BOTTOM, DEC_DIRECTION, device_range.get_y() - 1 - rotated_rr_switch_block.get_y());
/* Rotate the same nodes on the opposite side */
rotated_rr_switch_block.counter_rotate_side_chan_node_by_direction(TOP, DEC_DIRECTION, device_range.get_y() - 1 - rotated_rr_switch_block.get_y());
/* For LEFT SIDE: X-channel in DEC_DIRECTION, rotate by an offset of its x-coordinator */
rotated_rr_switch_block.counter_rotate_side_chan_node_by_direction(LEFT, DEC_DIRECTION, device_range.get_x() - 1 - rotated_rr_switch_block.get_x());
/* Rotate the same nodes on the opposite side */
rotated_rr_switch_block.counter_rotate_side_chan_node_by_direction(RIGHT, DEC_DIRECTION, device_range.get_x() - 1 - rotated_rr_switch_block.get_x());
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
@ -1055,18 +1167,20 @@ DeviceRRSwitchBlock build_device_rr_switch_blocks(int LL_num_rr_nodes, t_rr_node
DeviceRRSwitchBlock LL_device_rr_switch_block;
/* Initialize */
DeviceCoordinator device_coordinator(size_t(nx + 1), size_t(ny + 1));
DeviceCoordinator device_coordinator((size_t)nx + 1, (size_t)ny + 1);
LL_device_rr_switch_block.reserve(device_coordinator);
/* For each switch block, determine the size of array */
for (int ix = 0; ix < nx + 1; ++ix) {
for (int iy = 0; iy < ny + 1; ++iy) {
RRSwitchBlock rr_switch_block = build_rr_switch_block(ix, iy,
for (size_t ix = 0; ix < device_coordinator.get_x(); ++ix) {
for (size_t iy = 0; iy < device_coordinator.get_y(); ++iy) {
DeviceCoordinator sb_range((size_t)nx, (size_t)ny);
RRSwitchBlock rr_switch_block = build_rr_switch_block(sb_range, ix, iy,
LL_num_rr_nodes, LL_rr_node,
LL_rr_node_indices,
num_segments, LL_rr_indexed_data);
DeviceCoordinator sb_coordinator((size_t)ix, (size_t)iy);
LL_device_rr_switch_block.add_rr_switch_block(sb_coordinator, rr_switch_block);
RRSwitchBlock rotated_switch_block = rotate_rr_switch_block_for_mirror(sb_range, rr_switch_block);
DeviceCoordinator sb_coordinator = rr_switch_block.get_coordinator();
LL_device_rr_switch_block.add_rr_switch_block(sb_coordinator, rr_switch_block, rotated_switch_block);
}
}
@ -1074,11 +1188,10 @@ DeviceRRSwitchBlock build_device_rr_switch_blocks(int LL_num_rr_nodes, t_rr_node
vpr_printf(TIO_MESSAGE_INFO,
"Detect %d independent switch blocks from %d switch blocks.\n",
LL_device_rr_switch_block.get_num_unique_mirror(), (nx + 1) * (ny + 1) );
/* Skip rotating mirror searching
/* Skip rotating mirror searching */
vpr_printf(TIO_MESSAGE_INFO,
"Detect %d rotatable unique switch blocks from %d switch blocks.\n",
LL_device_rr_switch_block.get_num_rotatable_mirror(), (nx + 1) * (ny + 1) );
*/
return LL_device_rr_switch_block;
}

View File

@ -141,6 +141,111 @@ void RRChan::rotate(size_t rotate_begin, size_t rotate_end, size_t offset) {
return;
}
/* rotate all the channel nodes by a given offset:
* Routing Channel nodes are divided into different groups using segment ids
* each group is rotated separatedly
*/
void RRChan::rotate_by_node_direction(enum e_direction node_direction, size_t offset) {
/* skip if there are no nodes */
if (0 == get_chan_width()) {
return;
}
/* Get the channel nodes of a given direction */
std::vector<t_rr_node*> nodes;
std::vector<size_t> node_segments;
for (size_t inode = 0; inode < get_chan_width(); ++inode) {
if (node_direction == get_node(inode)->direction) {
nodes.push_back(get_node(inode));
node_segments.push_back(get_node_segment(inode));
}
}
size_t adapt_offset = offset % nodes.size();
assert(adapt_offset < nodes.size());
/* Rotate the chan_nodes */
std::rotate(nodes.begin(), nodes.begin() + adapt_offset, nodes.end());
std::rotate(node_segments.begin(), node_segments.begin() + adapt_offset, node_segments.end());
/* back-annotate to to the original chan nodes*/
for (size_t inode = 0; inode < get_chan_width(); ++inode) {
if (node_direction == get_node(inode)->direction) {
nodes_[inode] = nodes.front();
node_segments_[inode] = node_segments.front();
/* pop up temp vectors */
nodes.erase(nodes.begin());
node_segments.erase(node_segments.begin());
}
}
/* Make sure temp vectors are all poped out */
assert ( 0 == nodes.size());
assert ( 0 == node_segments.size());
return;
}
/* rotate all the channel nodes by a given offset:
* Routing Channel nodes are divided into different groups using segment ids
* each group is rotated separatedly
*/
void RRChan::counter_rotate_by_node_direction(enum e_direction node_direction, size_t offset) {
/* skip if there are no nodes */
if (0 == get_chan_width()) {
return;
}
/* Get the channel nodes of a given direction */
std::vector<t_rr_node*> nodes;
std::vector<size_t> node_segments;
for (size_t inode = 0; inode < get_chan_width(); ++inode) {
if (node_direction == get_node(inode)->direction) {
nodes.push_back(get_node(inode));
node_segments.push_back(get_node_segment(inode));
}
}
size_t adapt_offset = offset % nodes.size();
assert(adapt_offset < nodes.size());
/* Rotate the chan_nodes */
std::rotate(nodes.begin(), nodes.begin() + nodes.size() - adapt_offset, nodes.end());
std::rotate(node_segments.begin(), node_segments.begin() + node_segments.size() - adapt_offset, node_segments.end());
/* back-annotate to to the original chan nodes*/
for (size_t inode = 0; inode < get_chan_width(); ++inode) {
if (node_direction == get_node(inode)->direction) {
nodes_[inode] = nodes.front();
node_segments_[inode] = node_segments.front();
/* pop up temp vectors */
nodes.erase(nodes.begin());
node_segments.erase(node_segments.begin());
}
}
/* Make sure temp vectors are all poped out */
assert ( 0 == nodes.size());
assert ( 0 == node_segments.size());
return;
}
/* Mirror the node direction of routing track nodes on a side */
void RRChan::mirror_node_direction() {
for (size_t inode = 0; inode < get_chan_width(); ++inode) {
if (INC_DIRECTION == get_node(inode)->direction) {
nodes_[inode]->direction = DEC_DIRECTION;
} else {
assert (DEC_DIRECTION == get_node(inode)->direction);
nodes_[inode]->direction = INC_DIRECTION;
}
}
return;
}
/* Clear content */
void RRChan::clear() {
nodes_.clear();
@ -915,6 +1020,42 @@ void RRSwitchBlock::set_conf_bits_msb(size_t conf_bits_msb) {
return;
}
/* rotate the channel nodes with the same direction on one side by a given offset */
void RRSwitchBlock::rotate_side_chan_node_by_direction(enum e_side side, enum e_direction chan_dir, size_t offset) {
Side side_manager(side);
assert(validate_side(side));
/* Partition the chan nodes on this side, depending on its length */
/* skip this side if there is no nodes */
if (0 == get_chan_width(side)) {
return;
}
/* Rotate the chan_nodes */
chan_node_[side_manager.to_size_t()].rotate_by_node_direction(chan_dir, offset);
return;
}
/* rotate the channel nodes with the same direction on one side by a given offset */
void RRSwitchBlock::counter_rotate_side_chan_node_by_direction(enum e_side side, enum e_direction chan_dir, size_t offset) {
Side side_manager(side);
assert(validate_side(side));
/* Partition the chan nodes on this side, depending on its length */
/* skip this side if there is no nodes */
if (0 == get_chan_width(side)) {
return;
}
/* Rotate the chan_nodes */
chan_node_[side_manager.to_size_t()].counter_rotate_by_node_direction(chan_dir, offset);
return;
}
/* rotate all the channel nodes by a given offset */
void RRSwitchBlock::rotate_side_chan_node(enum e_side side, size_t offset) {
Side side_manager(side);
@ -1072,6 +1213,33 @@ void RRSwitchBlock::rotate_side(enum e_side side, size_t offset) {
return;
}
/* Mirror the node direction and port direction of routing track nodes on a side */
void RRSwitchBlock::mirror_side_chan_node_direction(enum e_side side) {
assert(validate_side(side));
Side side_manager(side);
chan_node_[side_manager.to_size_t()].mirror_node_direction();
return;
}
/* swap the chan rr_nodes on two sides */
void RRSwitchBlock::swap_chan_node(enum e_side src_side, enum e_side des_side) {
Side src_side_manager(src_side);
Side des_side_manager(des_side);
std::swap(chan_node_[src_side_manager.to_size_t()], chan_node_[des_side_manager.to_size_t()]);
std::swap(chan_node_direction_[src_side_manager.to_size_t()], chan_node_direction_[des_side_manager.to_size_t()]);
return;
}
/* swap the OPIN rr_nodes on two sides */
void RRSwitchBlock::swap_opin_node(enum e_side src_side, enum e_side des_side) {
Side src_side_manager(src_side);
Side des_side_manager(des_side);
std::swap(opin_node_[src_side_manager.to_size_t()], opin_node_[des_side_manager.to_size_t()]);
std::swap(opin_node_grid_side_[src_side_manager.to_size_t()], opin_node_grid_side_[des_side_manager.to_size_t()]);
return;
}
void RRSwitchBlock::clear() {
/* Clean all the vectors */
assert(validate_num_sides());
@ -1390,13 +1558,13 @@ void DeviceRRSwitchBlock::reserve(DeviceCoordinator& coordinator) {
/* Resize rr_switch_block array is needed*/
void DeviceRRSwitchBlock::resize_upon_need(DeviceCoordinator& coordinator) {
if (coordinator.get_x() + 1 > rr_switch_block_.capacity()) {
if (coordinator.get_x() + 1 > rr_switch_block_.size()) {
rr_switch_block_.resize(coordinator.get_x());
rr_switch_block_mirror_id_.resize(coordinator.get_x());
rr_switch_block_rotatable_mirror_id_.resize(coordinator.get_x());
}
if (coordinator.get_y() + 1 > rr_switch_block_[coordinator.get_x()].capacity()) {
if (coordinator.get_y() + 1 > rr_switch_block_[coordinator.get_x()].size()) {
rr_switch_block_[coordinator.get_x()].resize(coordinator.get_y());
rr_switch_block_mirror_id_[coordinator.get_x()].resize(coordinator.get_y());
rr_switch_block_rotatable_mirror_id_[coordinator.get_x()].resize(coordinator.get_y());
@ -1407,9 +1575,8 @@ void DeviceRRSwitchBlock::resize_upon_need(DeviceCoordinator& coordinator) {
/* Add a switch block to the array, which will automatically identify and update the lists of unique mirrors and rotatable mirrors */
void DeviceRRSwitchBlock::add_rr_switch_block(DeviceCoordinator& coordinator,
RRSwitchBlock& rr_switch_block) {
bool is_unique_mirror = true;
bool is_rotatable_mirror = true;
RRSwitchBlock& rr_switch_block,
RRSwitchBlock& rotated_rr_switch_block) {
/* Resize upon needs*/
resize_upon_need(coordinator);
@ -1417,6 +1584,8 @@ void DeviceRRSwitchBlock::add_rr_switch_block(DeviceCoordinator& coordinator,
/* Add the switch block into array */
rr_switch_block_[coordinator.get_x()][coordinator.get_y()] = rr_switch_block;
bool is_unique_mirror = true;
/* Traverse the unique_mirror list and check it is an mirror of another */
for (size_t mirror_id = 0; mirror_id < get_num_unique_mirror(); ++mirror_id) {
if (true == get_switch_block(unique_mirror_[mirror_id]).is_mirror(rr_switch_block)) {
@ -1434,68 +1603,26 @@ void DeviceRRSwitchBlock::add_rr_switch_block(DeviceCoordinator& coordinator,
rr_switch_block_mirror_id_[coordinator.get_x()][coordinator.get_y()] = unique_mirror_.size() - 1;
}
return; /* skip rotable mirror searching...*/
bool is_rotatable_mirror = true;
/* add rotatable mirror support */
for (size_t mirror_id = 0; mirror_id < get_num_rotatable_mirror(); ++mirror_id) {
RRSwitchBlock rotate_mirror = rr_switch_block;
is_rotatable_mirror = true;
/* Try to rotate as many times as the maximum channel width in this switch block
* This may not fully cover all the rotation possibility but may be enough now
*/
/* Skip if these may never match as a mirror (violation in basic requirements */
if (false == get_switch_block(rotatable_mirror_[mirror_id]).is_mirrorable(rotate_mirror)) {
if (false == get_switch_block(rotatable_mirror_[mirror_id]).is_mirrorable(rotated_rr_switch_block)) {
continue;
}
/* Give an initial rotation to accelerate the prediction */
//size_t hint_offset = get_switch_block(rotatable_mirror_[mirror_id]).get_hint_rotate_offset(rotate_mirror);
//rotate_mirror.rotate(hint_offset - 1);
for (size_t offset = 0; offset < rr_switch_block.get_max_chan_width(); ++offset) {
if (true == get_switch_block(rotatable_mirror_[mirror_id]).is_mirror(rotate_mirror)) {
if (true == get_switch_block(rotatable_mirror_[mirror_id]).is_mirror(rotated_rr_switch_block)) {
/* 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;
}
/* 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, 2);
rotate_y_mirror.rotate_side(BOTTOM, 2);
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(2);
}
if (false == is_rotatable_mirror) {
break;
}
}
/* Add to list if this is a unique mirror*/
if (true == is_rotatable_mirror) {
rotatable_mirror_.push_back(coordinator);
@ -1503,7 +1630,6 @@ void DeviceRRSwitchBlock::add_rr_switch_block(DeviceCoordinator& coordinator,
rr_switch_block_rotatable_mirror_id_[coordinator.get_x()][coordinator.get_y()] = rotatable_mirror_.size() - 1;
}
return;
}

View File

@ -51,7 +51,10 @@ class RRChan {
void reserve_node(size_t node_size); /* reseve a number of nodes to the array */
void add_node(t_rr_node* node, size_t node_segment); /* add a node to the array */
void rotate(size_t rotate_begin, size_t rotate_end, size_t offset); /* rotate the nodes and node_segments with a given offset */
void rotate_by_node_direction(enum e_direction node_direction, size_t offset);
void counter_rotate_by_node_direction(enum e_direction node_direction, size_t offset);
void rotate(size_t offset); /* rotate the nodes and node_segments with a given offset */
void mirror_node_direction(); /* mirror node direction */
void clear(); /* clear the content */
private: /* internal functions */
bool valid_type(t_rr_type type) const;
@ -167,6 +170,8 @@ class RRSwitchBlock {
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_msb(size_t conf_bits_msb);
void rotate_side_chan_node_by_direction(enum e_side side, enum e_direction chan_dir, size_t offset); /* rotate all the channel nodes by a given offset */
void counter_rotate_side_chan_node_by_direction(enum e_side side, enum e_direction chan_dir, 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_in_group(size_t offset); /* rotate all the channel nodes by a given offset */
@ -174,6 +179,9 @@ class RRSwitchBlock {
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 mirror_side_chan_node_direction(enum e_side side); /* Mirror the node direction and port direction of routing track nodes on a side */
void swap_chan_node(enum e_side src_side, enum e_side des_side); /* swap the chan rr_nodes on two sides */
void swap_opin_node(enum e_side src_side, enum e_side des_side); /* swap the OPIN rr_nodes on two sides */
void clear();
void clear_chan_nodes(enum e_side node_side); /* Clean the chan_width of a side */
void clear_ipin_nodes(enum e_side node_side); /* Clean the number of IPINs of a side */
@ -228,7 +236,7 @@ class DeviceRRSwitchBlock {
void set_rr_switch_block_conf_bits_msb(DeviceCoordinator& coordinator, size_t conf_bits_msb); /* TODO: TOBE DEPRECATED!!! conf_bits should be initialized when creating a switch block!!! */
void reserve(DeviceCoordinator& coordinator); /* Pre-allocate the rr_switch_block array that the device requires */
void resize_upon_need(DeviceCoordinator& coordinator); /* Resize the rr_switch_block array if needed */
void add_rr_switch_block(DeviceCoordinator& coordinator, RRSwitchBlock& rr_switch_block); /* Add a switch block to the array, which will automatically identify and update the lists of unique mirrors and rotatable mirrors */
void add_rr_switch_block(DeviceCoordinator& coordinator, RRSwitchBlock& rr_switch_block, RRSwitchBlock& rotated_rr_switch_block); /* Add a switch block to the array, which will automatically identify and update the lists of unique mirrors and rotatable mirrors */
void clear(); /* clean the content */
private: /* Validators */
bool validate_coordinator(DeviceCoordinator& coordinator) const; /* Validate if the (x,y) is the range of this device */

View File

@ -633,10 +633,8 @@ int get_unidir_opin_connections(INP int chan, INP int seg, INP int Fc,
/* get_rr_node_indices needs x and y coords. */
/* Original VPR */
/*
x = ((CHANX == chan_type) ? seg : chan);
y = ((CHANX == chan_type) ? chan : seg);
*/
//x = ((CHANX == chan_type) ? seg : chan);
//y = ((CHANX == chan_type) ? chan : seg);
/* end */
/* mrFPGA : Xifan TANG */
x = (((is_stack ? CHANY : CHANX) == chan_type) ? seg : chan);
@ -1160,12 +1158,11 @@ int get_track_to_tracks(INP int from_chan, INP int from_seg, INP int from_track,
assert(
from_seg == get_seg_start(seg_details, from_track, from_chan, from_seg));
from_switch = seg_details[from_track].wire_switch;
from_end = get_seg_end(seg_details, from_track, from_seg, from_chan,
chan_len);
/* end */
from_switch = seg_details[from_track].wire_switch;
/* mrFPGA : Xifan TANG*/
if (is_stack) {
from_end = from_end + 1;