From 1bea9870fc9c6aea937524e8463fb0bd816a7b11 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Sun, 26 May 2019 23:35:30 -0600 Subject: [PATCH] developed new rotating methods for RRSwitchBlocks, debugging ongoing --- .../SRC/fpga_x2p/base/fpga_x2p_timing_utils.c | 1 + .../fpga_x2p/base/fpga_x2p_unique_routing.c | 157 ++++++++++-- vpr7_x2p/vpr/SRC/fpga_x2p/base/rr_blocks.cpp | 238 +++++++++++++----- vpr7_x2p/vpr/SRC/fpga_x2p/base/rr_blocks.h | 10 +- vpr7_x2p/vpr/SRC/route/rr_graph2.c | 17 +- 5 files changed, 334 insertions(+), 89 deletions(-) diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_timing_utils.c b/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_timing_utils.c index 9682bf120..fbed0d29f 100644 --- a/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_timing_utils.c +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_timing_utils.c @@ -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 */ 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 3004cc179..ac8f5c2f2 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 @@ -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; } 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 0ae320958..693bc8be3 100644 --- a/vpr7_x2p/vpr/SRC/fpga_x2p/base/rr_blocks.cpp +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/base/rr_blocks.cpp @@ -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 nodes; + std::vector 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 nodes; + std::vector 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; } 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 072daad0f..661854181 100644 --- a/vpr7_x2p/vpr/SRC/fpga_x2p/base/rr_blocks.h +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/base/rr_blocks.h @@ -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 */ diff --git a/vpr7_x2p/vpr/SRC/route/rr_graph2.c b/vpr7_x2p/vpr/SRC/route/rr_graph2.c index 1012d3670..b60b5357d 100755 --- a/vpr7_x2p/vpr/SRC/route/rr_graph2.c +++ b/vpr7_x2p/vpr/SRC/route/rr_graph2.c @@ -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) {