developed new rotating methods for RRSwitchBlocks, debugging ongoing
This commit is contained in:
parent
4b852afeac
commit
1bea9870fc
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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)) {
|
||||
/* 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) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
|
@ -1156,15 +1154,14 @@ int get_track_to_tracks(INP int from_chan, INP int from_seg, INP int from_track,
|
|||
/* mrFPGA: Xifan TANG */
|
||||
//int true_from_start, true_from_end;
|
||||
|
||||
/* Original VPR */
|
||||
assert(
|
||||
/* Original VPR */
|
||||
assert(
|
||||
from_seg == get_seg_start(seg_details, from_track, from_chan, from_seg));
|
||||
|
||||
from_end = get_seg_end(seg_details, from_track, from_seg, from_chan,
|
||||
chan_len);
|
||||
/* end */
|
||||
|
||||
from_switch = seg_details[from_track].wire_switch;
|
||||
from_end = get_seg_end(seg_details, from_track, from_seg, from_chan,
|
||||
chan_len);
|
||||
/* end */
|
||||
|
||||
/* mrFPGA : Xifan TANG*/
|
||||
if (is_stack) {
|
||||
|
|
Loading…
Reference in New Issue