From 6f30d3ad0594c15ab79f28ab8e7d9222813efcc3 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Tue, 28 May 2019 11:25:16 -0600 Subject: [PATCH] support rotation on segment groups inside RRChan and improve rotatable mirror searching --- .../fpga_x2p/base/fpga_x2p_pbtypes_utils.h | 5 + .../fpga_x2p/base/fpga_x2p_unique_routing.c | 8 +- vpr7_x2p/vpr/SRC/fpga_x2p/base/rr_blocks.cpp | 172 ++++++++++++------ vpr7_x2p/vpr/SRC/fpga_x2p/base/rr_blocks.h | 3 + 4 files changed, 126 insertions(+), 62 deletions(-) diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_pbtypes_utils.h b/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_pbtypes_utils.h index 05bcd003b..1413b0c41 100644 --- a/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_pbtypes_utils.h +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_pbtypes_utils.h @@ -1,3 +1,6 @@ +#ifndef FPGA_X2P_PBTYPES_UTILS_H +#define FPGA_X2P_PBTYPES_UTILS_H + void check_pb_graph_edge(t_pb_graph_edge pb_graph_edge); void check_pb_graph_pin_edges(t_pb_graph_pin pb_graph_pin); @@ -236,3 +239,5 @@ boolean is_pb_used_for_wiring(t_pb_graph_node* cur_pb_graph_node, t_rr_node* pb_rr_graph); char* get_pb_graph_full_name_in_hierarchy(t_pb_graph_node* cur_pb_graph_node); + +#endif 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 8920fc8f7..9b27f7aab 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 @@ -1150,16 +1150,16 @@ RRSwitchBlock rotate_rr_switch_block_for_mirror(DeviceCoordinator& device_range, /* For BOTTOM SIDE: Y-channel in DEC_DIRECTION, rotate by an offset of its y-coordinator */ 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()); + rotated_rr_switch_block.counter_rotate_side_chan_node_by_direction(BOTTOM, DEC_DIRECTION, rotated_rr_switch_block.get_y() - 1); /* 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()); + rotated_rr_switch_block.counter_rotate_side_chan_node_by_direction(TOP, DEC_DIRECTION, rotated_rr_switch_block.get_y() - 1); } /* For LEFT SIDE: X-channel in DEC_DIRECTION, rotate by an offset of its x-coordinator */ 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()); + rotated_rr_switch_block.counter_rotate_side_chan_node_by_direction(LEFT, DEC_DIRECTION, rotated_rr_switch_block.get_x() - 1); /* 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()); + rotated_rr_switch_block.counter_rotate_side_chan_node_by_direction(RIGHT, DEC_DIRECTION, rotated_rr_switch_block.get_x() - 1); } return rotated_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 95365149b..c67e746e1 100644 --- a/vpr7_x2p/vpr/SRC/fpga_x2p/base/rr_blocks.cpp +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/base/rr_blocks.cpp @@ -101,6 +101,26 @@ bool RRChan::is_mirror(RRChan& cand) const { return true; } +/* Get a list of segments used in this routing channel */ +std::vector RRChan::get_segment_ids() const { + std::vector seg_list; + + /* make sure a clean start */ + seg_list.clear(); + + /* Traverse node_segments */ + for (size_t inode = 0; inode < get_chan_width(); ++inode) { + std::vector::iterator it; + /* Try to find the node_segment id in the list */ + it = find(seg_list.begin(), seg_list.end(), node_segments_[inode]); + if ( it != seg_list.end() ) { + /* Not found, add it to the list */ + seg_list.push_back(node_segments_[inode]); + } + } + + return seg_list; +} /* Mutators */ void RRChan::set(const RRChan& rr_chan) { @@ -166,46 +186,53 @@ void RRChan::rotate(size_t rotate_begin, size_t rotate_end, size_t offset) { /* 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 + * each group should be 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 a list of segment_ids existing in the routing channel */ + std::vector seg_ids = get_segment_ids(); + + for (size_t iseg = 0; iseg < seg_ids.size(); ++iseg) { + /* 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) + && (seg_ids[iseg] == get_node_segment(inode)) ) { + nodes.push_back(get_node(inode)); + node_segments.push_back(get_node_segment(inode)); + } + } - /* 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) + && (seg_ids[iseg] == get_node_segment(inode)) ) { + 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()); } - 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; } @@ -218,38 +245,45 @@ void RRChan::counter_rotate_by_node_direction(enum e_direction node_direction, s 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)); + + /* get a list of segment_ids existing in the routing channel */ + std::vector seg_ids = get_segment_ids(); + + for (size_t iseg = 0; iseg < seg_ids.size(); ++iseg) { + /* 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) + && (seg_ids[iseg] == get_node_segment(inode)) ) { + 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()); + 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()); + /* 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()); + /* 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) + && (seg_ids[iseg] == get_node_segment(inode)) ) { + 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()); + /* Make sure temp vectors are all poped out */ + assert ( 0 == nodes.size()); + assert ( 0 == node_segments.size()); + } return; } @@ -1763,6 +1797,9 @@ void DeviceRRSwitchBlock::add_rr_switch_block(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::build_unique_mirror() { + /* Make sure a clean start */ + clear_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; @@ -1830,18 +1867,37 @@ void DeviceRRSwitchBlock::clear() { /* clean rr_switch_block array */ for (size_t x = 0; x < rr_switch_block_.size(); ++x) { rr_switch_block_[x].clear(); + rr_switch_block_mirror_id_[x].clear(); + rr_switch_block_rotatable_mirror_id_[x].clear(); } rr_switch_block_.clear(); + rr_switch_block_mirror_id_.clear(); + rr_switch_block_rotatable_mirror_id_.clear(); /* clean unique mirror */ - unique_mirror_.clear(); + clear_mirror(); /* clean unique mirror */ - rotatable_mirror_.clear(); + clear_rotatable_mirror(); return; } +/* clean the content related to unique_mirrors */ +void DeviceRRSwitchBlock::clear_mirror() { + /* clean unique mirror */ + unique_mirror_.clear(); + + return; +} + +/* clean the content related to rotatable_mirrors */ +void DeviceRRSwitchBlock::clear_rotatable_mirror() { + /* clean unique mirror */ + rotatable_mirror_.clear(); + return; +} + /* Validate if the (x,y) is the range of this device */ bool DeviceRRSwitchBlock::validate_coordinator(DeviceCoordinator& coordinator) const { if (coordinator.get_x() >= rr_switch_block_.capacity()) { 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 7d318ec14..835238738 100644 --- a/vpr7_x2p/vpr/SRC/fpga_x2p/base/rr_blocks.h +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/base/rr_blocks.h @@ -47,6 +47,7 @@ class RRChan { int get_node_segment(t_rr_node* node) const; 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 */ + std::vector get_segment_ids() const; /* Get a list of segments used in this routing channel */ public: /* Mutators */ void set(const RRChan&); /* copy */ void set_type(t_rr_type type); /* modify type */ @@ -253,6 +254,8 @@ class DeviceRRSwitchBlock { 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 */ + void clear_mirror(); /* clean the content */ + void clear_rotatable_mirror(); /* clean the content */ private: /* Validators */ bool validate_coordinator(DeviceCoordinator& coordinator) const; /* Validate if the (x,y) is the range of this device */ bool validate_unique_mirror_index(size_t index) const; /* Validate if the index in the range of unique_mirror vector*/