From eece161d58604384c58f7c000b7fd1e38d891896 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Mon, 27 May 2019 21:10:30 -0600 Subject: [PATCH] keep debugging on Switch Block rotation --- .../fpga_x2p/base/fpga_x2p_unique_routing.c | 158 ++++++++------ .../vpr/SRC/fpga_x2p/base/fpga_x2p_utils.c | 1 + vpr7_x2p/vpr/SRC/fpga_x2p/base/rr_blocks.cpp | 196 ++++++++++++------ vpr7_x2p/vpr/SRC/fpga_x2p/base/rr_blocks.h | 11 +- .../SRC/fpga_x2p/verilog/verilog_routing.c | 3 +- 5 files changed, 239 insertions(+), 130 deletions(-) diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_unique_routing.c b/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_unique_routing.c index 284552acc..a4783b429 100644 --- a/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_unique_routing.c +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_unique_routing.c @@ -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", diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_utils.c b/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_utils.c index 9ff5e0a78..c49bd6653 100644 --- a/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_utils.c +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_utils.c @@ -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) { diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/base/rr_blocks.cpp b/vpr7_x2p/vpr/SRC/fpga_x2p/base/rr_blocks.cpp index 1a48df015..bd13188d8 100644 --- a/vpr7_x2p/vpr/SRC/fpga_x2p/base/rr_blocks.cpp +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/base/rr_blocks.cpp @@ -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 rr_chan_dir) { +void RRSwitchBlock::add_chan_node(enum e_side node_side, RRChan& rr_chan, std::vector 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 */ diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/base/rr_blocks.h b/vpr7_x2p/vpr/SRC/fpga_x2p/base/rr_blocks.h index be1fbea35..2c5db6fa0 100644 --- a/vpr7_x2p/vpr/SRC/fpga_x2p/base/rr_blocks.h +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/base/rr_blocks.h @@ -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 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 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 */ diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_routing.c b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_routing.c index 3ecaece46..19305c5f6 100644 --- a/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_routing.c +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_routing.c @@ -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;