From 6f30d3ad0594c15ab79f28ab8e7d9222813efcc3 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Tue, 28 May 2019 11:25:16 -0600 Subject: [PATCH 1/3] 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*/ From 3da216f297eeb78a3ac716140153e834667b89cc Mon Sep 17 00:00:00 2001 From: Baudouin Chauviere Date: Tue, 28 May 2019 14:15:24 -0600 Subject: [PATCH 2/3] correction Null issue for the flat model --- vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_sdc.c | 10 ++++++++-- vpr7_x2p/vpr/go_fpga_verilog.sh | 1 + 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_sdc.c b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_sdc.c index 9785170b4..5b36b0b37 100644 --- a/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_sdc.c +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_sdc.c @@ -1033,10 +1033,13 @@ void verilog_generate_sdc_disable_unused_sbs_muxs(FILE* fp) { } t_rr_node* cur_rr_node = rr_sb.get_chan_node(side_manager.get_side(), itrack); for (int imux = 0 ; imux < cur_rr_node->fan_in; ++imux) { + if (1 == cur_rr_node->fan_in) { + continue; + } if (imux == cur_rr_node->id_path) { fprintf(fp, "#"); // comments out if the node is active } -//if(cur_rr_node->name_mux == NULL) assert (NULL != cur_rr_node->name_mux); + //if(cur_rr_node->name_mux == NULL) assert (NULL != cur_rr_node->name_mux); fprintf(fp, "set_disable_timing %s[%d]\n", cur_rr_node->name_mux, imux); } @@ -1070,10 +1073,13 @@ void verilog_generate_sdc_disable_unused_sbs_muxs(FILE* fp, int LL_nx, int LL_ny if (OUT_PORT == cur_sb_info->chan_rr_node_direction[side][itrack]) { cur_rr_node = cur_sb_info->chan_rr_node[side][itrack]; for (imux = 0 ; imux < cur_rr_node-> fan_in; imux++) { + if (1 == cur_rr_node->fan_in) { + continue; + } if (imux == cur_rr_node->id_path) { fprintf(fp, "#"); // comments out if the node is active } -//if(cur_rr_node->name_mux == NULL) assert (NULL != cur_rr_node->name_mux); + //if(cur_rr_node->name_mux == NULL) assert (NULL != cur_rr_node->name_mux); fprintf(fp, "set_disable_timing %s[%d]\n", cur_rr_node->name_mux, imux); } diff --git a/vpr7_x2p/vpr/go_fpga_verilog.sh b/vpr7_x2p/vpr/go_fpga_verilog.sh index 969ebceb3..cd1955b62 100755 --- a/vpr7_x2p/vpr/go_fpga_verilog.sh +++ b/vpr7_x2p/vpr/go_fpga_verilog.sh @@ -34,6 +34,7 @@ set vpr_route_chan_width = 200 #make -j32 # Remove previous designs rm -rf $verilog_output_dirpath/$verilog_output_dirname +rm -rf $verilog_output_dirpath/$verilog_output_dirname\_compact # Run VPR #valgrind From af91fca1e0de913fcba88e65d29650b4b17021ec Mon Sep 17 00:00:00 2001 From: tangxifan Date: Tue, 28 May 2019 14:52:44 -0600 Subject: [PATCH 3/3] add rr_blocks XML writer to help debugging Switch Block Rotation --- .../fpga_x2p/base/fpga_x2p_unique_routing.c | 75 ++++++++---- vpr7_x2p/vpr/SRC/fpga_x2p/base/rr_blocks.cpp | 12 +- .../vpr/SRC/fpga_x2p/base/write_rr_blocks.cpp | 111 ++++++++++++++++++ .../vpr/SRC/fpga_x2p/base/write_rr_blocks.h | 8 ++ 4 files changed, 177 insertions(+), 29 deletions(-) create mode 100644 vpr7_x2p/vpr/SRC/fpga_x2p/base/write_rr_blocks.cpp create mode 100644 vpr7_x2p/vpr/SRC/fpga_x2p/base/write_rr_blocks.h 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 9b27f7aab..ab98aca19 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 @@ -32,6 +32,7 @@ #include "fpga_x2p_globals.h" #include "fpga_x2p_utils.h" #include "fpga_x2p_backannotate_utils.h" +#include "write_rr_blocks.h" #include "fpga_x2p_unique_routing.h" /***** subroutines declaration *****/ @@ -820,7 +821,7 @@ 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(DeviceCoordinator device_range, +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, @@ -1044,6 +1045,7 @@ RRSwitchBlock rotate_rr_switch_block_for_mirror(DeviceCoordinator& device_range, const RRSwitchBlock& rr_switch_block) { RRSwitchBlock rotated_rr_switch_block; rotated_rr_switch_block.set(rr_switch_block); + size_t Fco_offset = 1; /* For the 4 Switch Blocks at the four corners */ /* 1. BOTTOM-LEFT corner: @@ -1103,10 +1105,22 @@ RRSwitchBlock rotate_rr_switch_block_for_mirror(DeviceCoordinator& device_range, * 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.reverse_opin_node(TOP); - rotated_rr_switch_block.reverse_opin_node(BOTTOM); + + /* 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, Fco_offset * (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, Fco_offset * (rotated_rr_switch_block.get_x() - 1)); + + /* 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, Fco_offset * (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, Fco_offset * (rotated_rr_switch_block.get_x() - 1)); + + //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); + return rotated_rr_switch_block; } /* 3. RIGHT side: @@ -1114,10 +1128,22 @@ RRSwitchBlock rotate_rr_switch_block_for_mirror(DeviceCoordinator& device_range, * 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.reverse_opin_node(LEFT); - rotated_rr_switch_block.reverse_opin_node(RIGHT); + + /* 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, Fco_offset * (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, Fco_offset * (rotated_rr_switch_block.get_y() - 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, Fco_offset * (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, Fco_offset * (rotated_rr_switch_block.get_y() - 1)); + + //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); + return rotated_rr_switch_block; } /* 4. LEFT side: @@ -1136,35 +1162,36 @@ RRSwitchBlock rotate_rr_switch_block_for_mirror(DeviceCoordinator& device_range, /* 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 */ 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); + rotated_rr_switch_block.rotate_side_chan_node_by_direction(TOP, INC_DIRECTION, Fco_offset * (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); + rotated_rr_switch_block.rotate_side_chan_node_by_direction(BOTTOM, INC_DIRECTION, Fco_offset * (rotated_rr_switch_block.get_y() - 1)); } /* For RIGHT SIDE: X-channel in INC_DIRECTION, rotate by an offset of its x-coordinator */ 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); + rotated_rr_switch_block.rotate_side_chan_node_by_direction(RIGHT, INC_DIRECTION, Fco_offset * (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); + rotated_rr_switch_block.rotate_side_chan_node_by_direction(LEFT, INC_DIRECTION, Fco_offset * (rotated_rr_switch_block.get_x() - 1)); } /* 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, rotated_rr_switch_block.get_y() - 1); + if ( 1 < rotated_rr_switch_block.get_y()) { + rotated_rr_switch_block.counter_rotate_side_chan_node_by_direction(BOTTOM, DEC_DIRECTION, Fco_offset * (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, rotated_rr_switch_block.get_y() - 1); + rotated_rr_switch_block.counter_rotate_side_chan_node_by_direction(TOP, DEC_DIRECTION, Fco_offset * (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, rotated_rr_switch_block.get_x() - 1); + if ( 1 < rotated_rr_switch_block.get_x()) { + rotated_rr_switch_block.counter_rotate_side_chan_node_by_direction(LEFT, DEC_DIRECTION, Fco_offset * (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, rotated_rr_switch_block.get_x() - 1); + rotated_rr_switch_block.counter_rotate_side_chan_node_by_direction(RIGHT, DEC_DIRECTION, Fco_offset * (rotated_rr_switch_block.get_x() - 1)); } 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 * Each switch block in the FPGA fabric will be an instance of these modules. @@ -1184,7 +1211,7 @@ DeviceRRSwitchBlock build_device_rr_switch_blocks(int LL_num_rr_nodes, t_rr_node /* 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_sb = build_rr_switch_block(sb_range, ix, iy, + 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); @@ -1206,11 +1233,7 @@ DeviceRRSwitchBlock build_device_rr_switch_blocks(int LL_num_rr_nodes, t_rr_node 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 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); + 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); @@ -1223,6 +1246,8 @@ DeviceRRSwitchBlock build_device_rr_switch_blocks(int LL_num_rr_nodes, t_rr_node "Detect %d rotatable unique switch blocks from %d switch blocks.\n", LL_device_rr_switch_block.get_num_rotatable_mirror(), (nx + 1) * (ny + 1) ); + write_device_rr_switch_block_to_xml(LL_device_rr_switch_block); + 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 c67e746e1..d1242c4e6 100644 --- a/vpr7_x2p/vpr/SRC/fpga_x2p/base/rr_blocks.cpp +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/base/rr_blocks.cpp @@ -203,7 +203,7 @@ void RRChan::rotate_by_node_direction(enum e_direction node_direction, size_t of 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)) ) { + && (seg_ids[iseg] == (size_t)get_node_segment(inode)) ) { nodes.push_back(get_node(inode)); node_segments.push_back(get_node_segment(inode)); } @@ -219,7 +219,7 @@ void RRChan::rotate_by_node_direction(enum e_direction node_direction, size_t of /* 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)) ) { + && (seg_ids[iseg] == (size_t)get_node_segment(inode)) ) { nodes_[inode] = nodes.front(); node_segments_[inode] = node_segments.front(); /* pop up temp vectors */ @@ -255,7 +255,7 @@ void RRChan::counter_rotate_by_node_direction(enum e_direction node_direction, s 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)) ) { + && (seg_ids[iseg] == (size_t)get_node_segment(inode)) ) { nodes.push_back(get_node(inode)); node_segments.push_back(get_node_segment(inode)); } @@ -271,7 +271,7 @@ void RRChan::counter_rotate_by_node_direction(enum e_direction node_direction, s /* 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)) ) { + && (seg_ids[iseg] == (size_t)get_node_segment(inode)) ) { nodes_[inode] = nodes.front(); node_segments_[inode] = node_segments.front(); /* pop up temp vectors */ @@ -1118,6 +1118,7 @@ void RRSwitchBlock::set(const RRSwitchBlock& src) { return; } + /* Set the coordinator (x,y) for the switch block */ void RRSwitchBlock::set_coordinator(size_t x, size_t y) { coordinator_.set(x, y); @@ -1857,6 +1858,9 @@ void DeviceRRSwitchBlock::add_rotatable_mirror(DeviceCoordinator& coordinator, rotatable_mirror_.push_back(coordinator); /* Record the id of unique mirror */ rr_switch_block_rotatable_mirror_id_[coordinator.get_x()][coordinator.get_y()] = rotatable_mirror_.size() - 1; + /* + printf("Detect a rotatable mirror: SB[%lu][%lu]\n", coordinator.get_x(), coordinator.get_y()); + */ } return; diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/base/write_rr_blocks.cpp b/vpr7_x2p/vpr/SRC/fpga_x2p/base/write_rr_blocks.cpp new file mode 100644 index 000000000..3aeb59755 --- /dev/null +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/base/write_rr_blocks.cpp @@ -0,0 +1,111 @@ +/* + * Output internal structure of classes defined in rr_blocks.h to XML format + */ +#include +#include +#include + +#include "rr_blocks.h" +#include "write_rr_blocks.h" + +#include "fpga_x2p_utils.h" + +void write_rr_switch_block_to_xml(std::string fname_prefix, RRSwitchBlock& rr_sb) { + /* Create a file handler*/ + std::fstream fp; + std::string fname = fname_prefix; + fname += rr_sb.gen_verilog_instance_name(); + fname += ".xml"; + + printf("Output SB XML: %s\n", fname.c_str()); + + /* Open a file */ + fp.open(fname, std::fstream::out | std::fstream::trunc); + + /* Output location of the Switch Block */ + fp << "" << std::endl; + + /* Output each side */ + for (size_t side = 0; side < rr_sb.get_num_sides(); ++side) { + Side side_manager(side); + /* Output chan nodes */ + for (size_t inode = 0; inode < rr_sb.get_chan_width(side_manager.get_side()); ++inode) { + /* We only care OUT_PORT */ + if (OUT_PORT != rr_sb.get_chan_node_direction(side_manager.get_side(), inode)) { + continue; + } + /* Output drivers */ + size_t num_drive_rr_nodes = 0; + t_rr_node** drive_rr_nodes = 0; + t_rr_node* cur_rr_node = rr_sb.get_chan_node(side_manager.get_side(), inode); + + /* Output node information: location, index, side */ + fp << "\t<" << convert_chan_type_to_string(cur_rr_node->type) + << " side=\"" << side_manager.to_string() + << "\" index=\"" << inode << "\">" + << std::endl; + + /* Check if this node is directly connected to the node on the opposite side */ + if (true == rr_sb.is_node_imply_short_connection(cur_rr_node)) { + /* Double check if the interc lies inside a channel wire, that is interc between segments */ + assert(true == rr_sb.is_node_exist_opposite_side(cur_rr_node, side_manager.get_side())); + num_drive_rr_nodes = 0; + drive_rr_nodes = NULL; + } else { + num_drive_rr_nodes = cur_rr_node->num_drive_rr_nodes; + drive_rr_nodes = cur_rr_node->drive_rr_nodes; + } + /* Direct connection: output the node on the opposite side */ + if (0 == num_drive_rr_nodes) { + Side oppo_side = side_manager.get_opposite(); + fp << "\t\ttype) + << "\" side=\"" << oppo_side.to_string() + << "\" index=\"" << rr_sb.get_node_index(cur_rr_node, oppo_side.get_side(), IN_PORT) << "\"/>" + << std::endl; + } else { + for (size_t jnode = 0; jnode < num_drive_rr_nodes; ++jnode) { + enum e_side drive_node_side = NUM_SIDES; + int drive_node_index = -1; + rr_sb.get_node_side_and_index(drive_rr_nodes[jnode], IN_PORT, &drive_node_side, &drive_node_index); + Side drive_side(drive_node_side); + std::string node_type_str; + if (OPIN == drive_rr_nodes[jnode]->type) { + node_type_str = "opin"; + } else { + node_type_str = convert_chan_type_to_string(drive_rr_nodes[jnode]->type); + } + fp << "\t\t" + << std::endl; + } + } + fp << "\ttype) << ">" << std::endl; + } + } + + fp << "" << std::endl; + + /* close a file */ + fp.close(); + + return; +} + +/* Output each rr_switch_block to a XML file */ +void write_device_rr_switch_block_to_xml(DeviceRRSwitchBlock& LL_device_rr_switch_block) { + std::string fname_prefix("/var/tmp/xtang/sb_xml/"); + DeviceCoordinator sb_range = LL_device_rr_switch_block.get_switch_block_range(); + + /* For each switch block, an XML file will be outputted */ + 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); + write_rr_switch_block_to_xml(fname_prefix, rr_sb); + } + } + + return; +} + diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/base/write_rr_blocks.h b/vpr7_x2p/vpr/SRC/fpga_x2p/base/write_rr_blocks.h new file mode 100644 index 000000000..dd00ffb79 --- /dev/null +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/base/write_rr_blocks.h @@ -0,0 +1,8 @@ +#ifndef WRITE_RR_BLOCKS_H +#define WRITE_RR_BLOCKS_H + +void write_rr_switch_block_to_xml(std::string fname_prefix, RRSwitchBlock& rr_sb) { + +void write_device_rr_switch_block_to_xml(DeviceRRSwitchBlock& LL_device_rr_switch_block); + +#endif