keep debugging on Switch Block rotation

This commit is contained in:
tangxifan 2019-05-27 21:10:30 -06:00
parent 5720217cfd
commit eece161d58
5 changed files with 239 additions and 130 deletions

View File

@ -73,11 +73,6 @@ void print_mirror_switch_block_stats();
void print_mirror_connection_block_stats();
RRChan build_one_rr_chan(t_rr_type chan_type, size_t chan_x, size_t chan_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);
void print_device_rr_chan_stats(DeviceRRChan& device_rr_chan);
/***** subroutines *****/
@ -696,6 +691,7 @@ void identify_mirror_connection_blocks() {
}
/* Build a RRChan Object with the given channel type and coorindators */
static
RRChan build_one_rr_chan(t_rr_type chan_type, size_t chan_x, size_t chan_y,
int LL_num_rr_nodes, t_rr_node* LL_rr_node,
t_ivec*** LL_rr_node_indices, int num_segments,
@ -847,6 +843,7 @@ RRSwitchBlock build_rr_switch_block(DeviceCoordinator device_range,
for (size_t side = 0; side < rr_switch_block.get_num_sides(); ++side) {
/* Local variables inside this for loop */
Side side_manager(side);
DeviceCoordinator coordinator;
size_t ix = 0;
size_t iy = 0;
RRChan rr_chan;
@ -862,15 +859,16 @@ RRSwitchBlock build_rr_switch_block(DeviceCoordinator device_range,
break;
}
/* Routing channels*/
ix = sb_x;
iy = sb_y + 1;
coordinator = rr_switch_block.get_side_block_coordinator(side_manager.get_side());
ix = coordinator.get_x();
iy = coordinator.get_y();
/* Side: TOP => 0, RIGHT => 1, BOTTOM => 2, LEFT => 3 */
/* Create a rr_chan object and check if it is unique in the graph */
rr_chan = build_one_rr_chan(CHANY, ix, iy,
LL_num_rr_nodes, LL_rr_node, LL_rr_node_indices,
num_segments, LL_rr_indexed_data);
chan_dir_to_port_dir_mapping[0] = OUT_PORT;
chan_dir_to_port_dir_mapping[1] = IN_PORT;
chan_dir_to_port_dir_mapping[0] = OUT_PORT; /* INC_DIRECTION => OUT_PORT */
chan_dir_to_port_dir_mapping[1] = IN_PORT; /* DEC_DIRECTION => IN_PORT */
/* Include Grid[x][y+1] RIGHT side outputs pins */
temp_opin_rr_node[0] = get_grid_side_pin_rr_nodes(&temp_num_opin_rr_nodes[0],
@ -894,16 +892,17 @@ RRSwitchBlock build_rr_switch_block(DeviceCoordinator device_range,
break;
}
/* Routing channels*/
ix = sb_x + 1;
iy = sb_y;
coordinator = rr_switch_block.get_side_block_coordinator(side_manager.get_side());
ix = coordinator.get_x();
iy = coordinator.get_y();
/* Side: TOP => 0, RIGHT => 1, BOTTOM => 2, LEFT => 3 */
/* Collect rr_nodes for Tracks for top: chany[x][y+1] */
/* Create a rr_chan object and check if it is unique in the graph */
rr_chan = build_one_rr_chan(CHANX, ix, iy,
LL_num_rr_nodes, LL_rr_node, LL_rr_node_indices,
num_segments, LL_rr_indexed_data);
chan_dir_to_port_dir_mapping[0] = OUT_PORT;
chan_dir_to_port_dir_mapping[1] = IN_PORT;
chan_dir_to_port_dir_mapping[0] = OUT_PORT; /* INC_DIRECTION => OUT_PORT */
chan_dir_to_port_dir_mapping[1] = IN_PORT; /* DEC_DIRECTION => IN_PORT */
/* include Grid[x+1][y+1] Bottom side output pins */
temp_opin_rr_node[0] = get_grid_side_pin_rr_nodes(&temp_num_opin_rr_nodes[0],
@ -926,16 +925,17 @@ RRSwitchBlock build_rr_switch_block(DeviceCoordinator device_range,
break;
}
/* Routing channels*/
ix = sb_x;
iy = sb_y;
coordinator = rr_switch_block.get_side_block_coordinator(side_manager.get_side());
ix = coordinator.get_x();
iy = coordinator.get_y();
/* Side: TOP => 0, RIGHT => 1, BOTTOM => 2, LEFT => 3 */
/* Collect rr_nodes for Tracks for bottom: chany[x][y] */
/* Create a rr_chan object and check if it is unique in the graph */
rr_chan = build_one_rr_chan(CHANY, ix, iy,
LL_num_rr_nodes, LL_rr_node, LL_rr_node_indices,
num_segments, LL_rr_indexed_data);
chan_dir_to_port_dir_mapping[0] = IN_PORT;
chan_dir_to_port_dir_mapping[1] = OUT_PORT;
chan_dir_to_port_dir_mapping[0] = IN_PORT; /* INC_DIRECTION => IN_PORT */
chan_dir_to_port_dir_mapping[1] = OUT_PORT; /* DEC_DIRECTION => OUT_PORT */
/* TODO: include Grid[x+1][y] Left side output pins */
temp_opin_rr_node[0] = get_grid_side_pin_rr_nodes(&temp_num_opin_rr_nodes[0],
@ -958,16 +958,17 @@ RRSwitchBlock build_rr_switch_block(DeviceCoordinator device_range,
break;
}
/* Routing channels*/
ix = sb_x;
iy = sb_y;
coordinator = rr_switch_block.get_side_block_coordinator(side_manager.get_side());
ix = coordinator.get_x();
iy = coordinator.get_y();
/* Side: TOP => 0, RIGHT => 1, BOTTOM => 2, LEFT => 3 */
/* Collect rr_nodes for Tracks for left: chanx[x][y] */
/* Create a rr_chan object and check if it is unique in the graph */
rr_chan = build_one_rr_chan(CHANX, ix, iy,
LL_num_rr_nodes, LL_rr_node, LL_rr_node_indices,
num_segments, LL_rr_indexed_data);
chan_dir_to_port_dir_mapping[0] = IN_PORT;
chan_dir_to_port_dir_mapping[1] = OUT_PORT;
chan_dir_to_port_dir_mapping[0] = IN_PORT; /* INC_DIRECTION => IN_PORT */
chan_dir_to_port_dir_mapping[1] = OUT_PORT; /* DEC_DIRECTION => OUT_PORT */
/* include Grid[x][y+1] Bottom side outputs pins */
temp_opin_rr_node[0] = get_grid_side_pin_rr_nodes(&temp_num_opin_rr_nodes[0],
@ -1040,8 +1041,9 @@ RRSwitchBlock build_rr_switch_block(DeviceCoordinator device_range,
/* 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;
const RRSwitchBlock& rr_switch_block) {
RRSwitchBlock rotated_rr_switch_block;
rotated_rr_switch_block.set(rr_switch_block);
/* For the 4 Switch Blocks at the four corners */
/* 1. BOTTOM-LEFT corner:
@ -1051,18 +1053,21 @@ RRSwitchBlock rotate_rr_switch_block_for_mirror(DeviceCoordinator& device_range,
&& ( 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);
//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,
@ -1071,14 +1076,14 @@ RRSwitchBlock rotate_rr_switch_block_for_mirror(DeviceCoordinator& device_range,
*/
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);
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);
//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);
//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:
@ -1087,10 +1092,10 @@ RRSwitchBlock rotate_rr_switch_block_for_mirror(DeviceCoordinator& device_range,
*/
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);
//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;
}
@ -1108,6 +1113,8 @@ RRSwitchBlock rotate_rr_switch_block_for_mirror(DeviceCoordinator& device_range,
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.reverse_opin_node(TOP);
rotated_rr_switch_block.reverse_opin_node(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;
@ -1119,6 +1126,8 @@ RRSwitchBlock rotate_rr_switch_block_for_mirror(DeviceCoordinator& device_range,
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.reverse_opin_node(LEFT);
rotated_rr_switch_block.reverse_opin_node(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;
@ -1130,26 +1139,40 @@ RRSwitchBlock rotate_rr_switch_block_for_mirror(DeviceCoordinator& device_range,
return rotated_rr_switch_block;
}
/* SB[1][1] is the baseline, we do not modify */
if ( (1 == rotated_rr_switch_block.get_x())
&& (1 == rotated_rr_switch_block.get_y()) ) {
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);
if (1 < rotated_rr_switch_block.get_y()) {
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);
if (1 < rotated_rr_switch_block.get_x()) {
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());
if (device_range.get_y() - 1 > rotated_rr_switch_block.get_y()) {
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());
if (device_range.get_x() - 1 > rotated_rr_switch_block.get_x()) {
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;
}
@ -1167,25 +1190,42 @@ DeviceRRSwitchBlock build_device_rr_switch_blocks(int LL_num_rr_nodes, t_rr_node
/* Initialize */
DeviceCoordinator sb_range((size_t)nx, (size_t)ny);
LL_device_rr_switch_block.reserve(sb_range);
DeviceCoordinator reserve_range((size_t)nx + 1, (size_t)ny + 1);
LL_device_rr_switch_block.reserve(reserve_range);
/* For each switch block, determine the size of array */
for (size_t ix = 0; ix <= sb_range.get_x(); ++ix) {
for (size_t iy = 0; iy <= sb_range.get_y(); ++iy) {
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);
RRSwitchBlock rotated_switch_block = rotate_rr_switch_block_for_mirror(sb_range, rotated_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);
RRSwitchBlock rr_sb = 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 = rr_sb.get_coordinator();
LL_device_rr_switch_block.add_rr_switch_block(sb_coordinator, rr_sb);
}
}
/* Report number of unique mirrors */
vpr_printf(TIO_MESSAGE_INFO,
"Backannotated %d switch blocks.\n",
(nx + 1) * (ny + 1) );
LL_device_rr_switch_block.build_unique_mirror();
/* Report number of unique mirrors */
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) );
for (size_t ix = 0; ix <= sb_range.get_x(); ++ix) {
for (size_t iy = 0; iy <= sb_range.get_y(); ++iy) {
RRSwitchBlock rr_sb = LL_device_rr_switch_block.get_switch_block(ix, iy);
RRSwitchBlock rotated_rr_sb = rotate_rr_switch_block_for_mirror(sb_range, rr_sb);
DeviceCoordinator sb_coordinator = rr_sb.get_coordinator();
LL_device_rr_switch_block.add_rotatable_mirror(sb_coordinator, rotated_rr_sb);
}
}
/* Skip rotating mirror searching */
vpr_printf(TIO_MESSAGE_INFO,
"Detect %d rotatable unique switch blocks from %d switch blocks.\n",

View File

@ -1738,6 +1738,7 @@ int rr_node_drive_switch_box(t_rr_node* src_rr_node,
* \
*/
/* The destination rr_node only have one condition!!! */
if (!((DEC_DIRECTION == des_rr_node->direction)&&(CHANX == des_rr_node->type)))
assert((DEC_DIRECTION == des_rr_node->direction)&&(CHANX == des_rr_node->type));
/* depend on the type of src_rr_node */
switch (src_rr_node->type) {

View File

@ -10,13 +10,7 @@
/* Copy Constructor */
RRChan::RRChan(const RRChan& rr_chan) {
this->type_ = rr_chan.get_type();
/* Copy node and node_segments */
this->reserve_node(rr_chan.get_chan_width());
for (size_t inode = 0; inode < rr_chan.get_chan_width(); ++inode) {
this->nodes_.push_back(rr_chan.get_node(inode));
this->node_segments_.push_back(rr_chan.get_node_segment(inode));
}
this->set(rr_chan);
return;
}
@ -109,6 +103,17 @@ bool RRChan::is_mirror(RRChan& cand) const {
/* Mutators */
void RRChan::set(const RRChan& rr_chan) {
this->type_ = rr_chan.get_type();
/* Copy node and node_segments */
this->reserve_node(rr_chan.get_chan_width());
for (size_t inode = 0; inode < rr_chan.get_chan_width(); ++inode) {
this->nodes_.push_back(rr_chan.get_node(inode));
this->node_segments_.push_back(rr_chan.get_node_segment(inode));
}
return;
}
/* modify type */
void RRChan::set_type(t_rr_type type) {
assert(valid_type(type));
@ -471,41 +476,7 @@ RRSwitchBlock::RRSwitchBlock() {
/* Copy constructor */
RRSwitchBlock::RRSwitchBlock(const RRSwitchBlock& src) {
/* Copy coordinator */
this->set_coordinator(src.get_coordinator().get_x(), src.get_coordinator().get_y());
/* Initialize sides */
this->init_num_sides(src.get_num_sides());
/* Copy vectors */
for (size_t side = 0; side < src.get_num_sides(); ++side) {
Side side_manager(side);
/* Copy chan_nodes */
this->chan_node_[side_manager.get_side()] = src.get_chan(side_manager.get_side());
/* Copy chan_node_direction_*/
for (size_t inode = 0; inode < src.get_chan_width(side_manager.get_side()); ++inode) {
this->chan_node_direction_[side_manager.get_side()].push_back(src.get_chan_node_direction(side_manager.get_side(), inode));
}
/* Copy opin_node and opin_node_grid_side_ */
for (size_t inode = 0; inode < src.get_num_opin_nodes(side_manager.get_side()); ++inode) {
this->opin_node_[side_manager.get_side()].push_back(src.get_opin_node(side_manager.get_side(), inode));
this->opin_node_grid_side_[side_manager.get_side()].push_back(src.get_opin_node_grid_side(side_manager.get_side(), inode));
}
/* Copy ipin_node and ipin_node_grid_side_ */
for (size_t inode = 0; inode < src.get_num_ipin_nodes(side_manager.get_side()); ++inode) {
this->ipin_node_[side_manager.get_side()].push_back(src.get_ipin_node(side_manager.get_side(), inode));
this->ipin_node_grid_side_[side_manager.get_side()].push_back(src.get_ipin_node_grid_side(side_manager.get_side(), inode));
}
}
/* Copy conf_bits
* TODO: this will be recovered when num_conf_bits etc will be initialized during FPGA-X2P setup
this->set_num_reserved_conf_bits(src.get_num_reserved_conf_bits());
this->set_conf_bits_lsb(src.get_conf_bits_lsb());
this->set_conf_bits_msb(src.get_conf_bits_msb());
*/
this->set(src);
return;
}
@ -746,7 +717,6 @@ int RRSwitchBlock::get_node_index(t_rr_node* node,
assert((0 == cnt)||(1 == cnt));
return ret; /* Return an invalid value: nonthing is found*/
}
/* Check if the node exist in the opposite side of this Switch Block */
@ -1064,6 +1034,52 @@ char* RRSwitchBlock::gen_verilog_instance_name() const {
/* Public mutators */
/* get a copy from a source */
void RRSwitchBlock::set(const RRSwitchBlock& src) {
/* Copy coordinator */
this->set_coordinator(src.get_coordinator().get_x(), src.get_coordinator().get_y());
/* Initialize sides */
this->init_num_sides(src.get_num_sides());
/* Copy vectors */
for (size_t side = 0; side < src.get_num_sides(); ++side) {
Side side_manager(side);
/* Copy chan_nodes */
this->chan_node_[side_manager.get_side()].set(src.get_chan(side_manager.get_side()));
/* Copy chan_node_direction_*/
this->chan_node_direction_[side_manager.get_side()].clear();
for (size_t inode = 0; inode < src.get_chan_width(side_manager.get_side()); ++inode) {
this->chan_node_direction_[side_manager.get_side()].push_back(src.get_chan_node_direction(side_manager.get_side(), inode));
}
/* Copy opin_node and opin_node_grid_side_ */
this->opin_node_[side_manager.get_side()].clear();
this->opin_node_grid_side_[side_manager.get_side()].clear();
for (size_t inode = 0; inode < src.get_num_opin_nodes(side_manager.get_side()); ++inode) {
this->opin_node_[side_manager.get_side()].push_back(src.get_opin_node(side_manager.get_side(), inode));
this->opin_node_grid_side_[side_manager.get_side()].push_back(src.get_opin_node_grid_side(side_manager.get_side(), inode));
}
/* Copy ipin_node and ipin_node_grid_side_ */
this->ipin_node_[side_manager.get_side()].clear();
this->ipin_node_grid_side_[side_manager.get_side()].clear();
for (size_t inode = 0; inode < src.get_num_ipin_nodes(side_manager.get_side()); ++inode) {
this->ipin_node_[side_manager.get_side()].push_back(src.get_ipin_node(side_manager.get_side(), inode));
this->ipin_node_grid_side_[side_manager.get_side()].push_back(src.get_ipin_node_grid_side(side_manager.get_side(), inode));
}
}
/* Copy conf_bits
* TODO: this will be recovered when num_conf_bits etc will be initialized during FPGA-X2P setup
this->set_num_reserved_conf_bits(src.get_num_reserved_conf_bits());
this->set_conf_bits_lsb(src.get_conf_bits_lsb());
this->set_conf_bits_msb(src.get_conf_bits_msb());
*/
return;
}
/* Set the coordinator (x,y) for the switch block */
void RRSwitchBlock::set_coordinator(size_t x, size_t y) {
coordinator_.set(x, y);
@ -1073,8 +1089,8 @@ void RRSwitchBlock::set_coordinator(size_t x, size_t y) {
/* Allocate the vectors with the given number of sides */
void RRSwitchBlock::init_num_sides(size_t num_sides) {
/* Initialize the vectors */
chan_node_direction_.resize(num_sides);
chan_node_.resize(num_sides);
chan_node_direction_.resize(num_sides);
ipin_node_.resize(num_sides);
ipin_node_grid_side_.resize(num_sides);
opin_node_.resize(num_sides);
@ -1083,13 +1099,13 @@ void RRSwitchBlock::init_num_sides(size_t num_sides) {
}
/* Add a node to the chan_node_ list and also assign its direction in chan_node_direction_ */
void RRSwitchBlock::add_chan_node(enum e_side node_side, RRChan rr_chan, std::vector<enum PORTS> rr_chan_dir) {
void RRSwitchBlock::add_chan_node(enum e_side node_side, RRChan& rr_chan, std::vector<enum PORTS> rr_chan_dir) {
Side side_manager(node_side);
/* Validate: 1. side is valid, the type of node is valid */
assert(validate_side(node_side));
/* fill the dedicated element in the vector */
chan_node_[side_manager.to_size_t()] = rr_chan;
chan_node_[side_manager.to_size_t()].set(rr_chan);
chan_node_direction_[side_manager.to_size_t()] = rr_chan_dir;
return;
@ -1353,6 +1369,31 @@ void RRSwitchBlock::swap_opin_node(enum e_side src_side, enum e_side des_side) {
return;
}
/* swap the IPIN rr_nodes on two sides */
void RRSwitchBlock::swap_ipin_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(ipin_node_[src_side_manager.to_size_t()], ipin_node_[des_side_manager.to_size_t()]);
std::swap(ipin_node_grid_side_[src_side_manager.to_size_t()], ipin_node_grid_side_[des_side_manager.to_size_t()]);
return;
}
/* Reverse the vector of the OPIN rr_nodes on a side */
void RRSwitchBlock::reverse_opin_node(enum e_side side) {
Side side_manager(side);
std::reverse(opin_node_[side_manager.to_size_t()].begin(), opin_node_[side_manager.to_size_t()].end());
std::reverse(opin_node_grid_side_[side_manager.to_size_t()].begin(), opin_node_grid_side_[side_manager.to_size_t()].end());
return;
}
/* Reverse the vector of the OPIN rr_nodes on a side */
void RRSwitchBlock::reverse_ipin_node(enum e_side side) {
Side side_manager(side);
std::reverse(ipin_node_[side_manager.to_size_t()].begin(), ipin_node_[side_manager.to_size_t()].end());
std::reverse(ipin_node_grid_side_[side_manager.to_size_t()].begin(), ipin_node_grid_side_[side_manager.to_size_t()].end());
return;
}
void RRSwitchBlock::clear() {
/* Clean all the vectors */
assert(validate_num_sides());
@ -1703,43 +1744,62 @@ 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,
RRSwitchBlock& rotated_rr_switch_block) {
RRSwitchBlock& rr_sb) {
/* Resize upon needs*/
resize_upon_need(coordinator);
/* Add the switch block into array */
rr_switch_block_[coordinator.get_x()][coordinator.get_y()] = rr_switch_block;
rr_switch_block_[coordinator.get_x()][coordinator.get_y()] = rr_sb;
bool is_unique_mirror = true;
return;
}
/* 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)) {
/* This is a mirror, raise the flag and we finish */
is_unique_mirror = false;
/* Record the id of unique mirror */
rr_switch_block_mirror_id_[coordinator.get_x()][coordinator.get_y()] = mirror_id;
break;
/* Add a switch block to the array, which will automatically identify and update the lists of unique mirrors and rotatable mirrors */
void DeviceRRSwitchBlock::build_unique_mirror() {
for (size_t ix = 0; ix < rr_switch_block_.size(); ++ix) {
for (size_t iy = 0; iy < rr_switch_block_[ix].size(); ++iy) {
bool is_unique_mirror = true;
RRSwitchBlock* rr_sb = &(rr_switch_block_[ix][iy]);
/* 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 we have the same coordinator, this is already not unique_mirror */
if ( (ix == unique_mirror_[mirror_id].get_x())
&& (iy == unique_mirror_[mirror_id].get_y()) ) {
is_unique_mirror = false;
break;
}
if (true == get_switch_block(unique_mirror_[mirror_id]).is_mirror(*rr_sb)) {
/* This is a mirror, raise the flag and we finish */
is_unique_mirror = false;
/* Record the id of unique mirror */
rr_switch_block_mirror_id_[ix][iy] = mirror_id;
break;
}
}
/* Add to list if this is a unique mirror*/
if (true == is_unique_mirror) {
DeviceCoordinator coordinator(ix, iy);
unique_mirror_.push_back(coordinator);
/* Record the id of unique mirror */
rr_switch_block_mirror_id_[ix][iy] = unique_mirror_.size() - 1;
}
}
}
/* Add to list if this is a unique mirror*/
if (true == is_unique_mirror) {
unique_mirror_.push_back(coordinator);
/* Record the id of unique mirror */
rr_switch_block_mirror_id_[coordinator.get_x()][coordinator.get_y()] = unique_mirror_.size() - 1;
}
return;
}
void DeviceRRSwitchBlock::add_rotatable_mirror(DeviceCoordinator& coordinator,
RRSwitchBlock& rotated_rr_sb) {
bool is_rotatable_mirror = true;
/* add rotatable mirror support */
for (size_t mirror_id = 0; mirror_id < get_num_rotatable_mirror(); ++mirror_id) {
/* Skip if these may never match as a mirror (violation in basic requirements */
if (false == get_switch_block(rotatable_mirror_[mirror_id]).is_mirrorable(rotated_rr_switch_block)) {
if (false == get_switch_block(rotatable_mirror_[mirror_id]).is_mirrorable(rotated_rr_sb)) {
continue;
}
if (true == get_switch_block(rotatable_mirror_[mirror_id]).is_mirror(rotated_rr_switch_block)) {
if (true == get_switch_block(rotatable_mirror_[mirror_id]).is_mirror(rotated_rr_sb)) {
/* This is a mirror, raise the flag and we finish */
is_rotatable_mirror = false;
/* Record the id of unique mirror */

View File

@ -48,6 +48,7 @@ class RRChan {
int get_node_segment(size_t track_num) const;
bool is_mirror(RRChan& cand) const; /* evaluate if two RR_chan is mirror to each other */
public: /* Mutators */
void set(const RRChan&); /* copy */
void set_type(t_rr_type type); /* modify type */
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 */
@ -169,9 +170,10 @@ class RRSwitchBlock {
char* gen_verilog_module_name() const;
char* gen_verilog_instance_name() const;
public: /* Mutators */
void set(const RRSwitchBlock& src); /* get a copy from a source */
void set_coordinator(size_t x, size_t y);
void init_num_sides(size_t num_sides); /* Allocate the vectors with the given number of sides */
void add_chan_node(enum e_side node_side, RRChan rr_chan, std::vector<enum PORTS> rr_chan_dir); /* Add a node to the chan_rr_node_ list and also assign its direction in chan_rr_node_direction_ */
void add_chan_node(enum e_side node_side, RRChan& rr_chan, std::vector<enum PORTS> rr_chan_dir); /* Add a node to the chan_rr_node_ list and also assign its direction in chan_rr_node_direction_ */
void add_ipin_node(t_rr_node* node, enum e_side node_side, enum e_side grid_side); /* Add a node to the chan_rr_node_ list and also assign its direction in chan_rr_node_direction_ */
void add_opin_node(t_rr_node* node, enum e_side node_side, enum e_side grid_side); /* Add a node to the chan_rr_node_ list and also assign its direction in chan_rr_node_direction_ */
void set_num_reserved_conf_bits(size_t num_reserved_conf_bits);
@ -189,6 +191,9 @@ class RRSwitchBlock {
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 swap_ipin_node(enum e_side src_side, enum e_side des_side); /* swap the IPIN rr_nodes on two sides */
void reverse_opin_node(enum e_side side); /* reverse the OPIN rr_nodes on two sides */
void reverse_ipin_node(enum e_side side); /* reverse the IPIN 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 */
@ -244,7 +249,9 @@ 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, 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 add_rr_switch_block(DeviceCoordinator& coordinator, RRSwitchBlock& rr_sb); /* Add a switch block to the array, which will automatically identify and update the lists of unique mirrors and rotatable mirrors */
void build_unique_mirror(); /* Add a switch block to the array, which will automatically identify and update the lists of unique mirrors and rotatable mirrors */
void add_rotatable_mirror(DeviceCoordinator& coordinator, RRSwitchBlock& rr_sb); /* 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

@ -736,8 +736,9 @@ void dump_verilog_unique_switch_box_short_interc(FILE* fp,
if (0 == actual_fan_in) {
assert(drive_rr_node == cur_rr_node);
} else {
Side side_manager(chan_side);
/* drive_rr_node = &(rr_node[cur_rr_node->prev_node]); */
assert(1 == rr_node_drive_switch_box(drive_rr_node, cur_rr_node, rr_sb.get_coordinator().get_x(), rr_sb.get_coordinator().get_y(), chan_side));
assert(1 == rr_node_drive_switch_box(drive_rr_node, cur_rr_node, rr_sb.get_coordinator().get_x(), rr_sb.get_coordinator().get_y(), side_manager.get_side()));
}
int grid_x = drive_rr_node->xlow;