diff --git a/fpga_flow/arch/template/k6_N10_sram_chain_HC_template.xml b/fpga_flow/arch/template/k6_N10_sram_chain_HC_template.xml
index a56d6b3cb..06e75d911 100644
--- a/fpga_flow/arch/template/k6_N10_sram_chain_HC_template.xml
+++ b/fpga_flow/arch/template/k6_N10_sram_chain_HC_template.xml
@@ -150,7 +150,7 @@
-
+
diff --git a/vpr7_x2p/vpr/SRC/device/rr_graph/rr_graph_builder_utils.cpp b/vpr7_x2p/vpr/SRC/device/rr_graph/rr_graph_builder_utils.cpp
index aa08c67fd..ecab27502 100644
--- a/vpr7_x2p/vpr/SRC/device/rr_graph/rr_graph_builder_utils.cpp
+++ b/vpr7_x2p/vpr/SRC/device/rr_graph/rr_graph_builder_utils.cpp
@@ -255,6 +255,91 @@ void add_one_edge_for_two_rr_nodes(const t_rr_graph* rr_graph,
return;
}
+
+/************************************************************************
+ * Add a set of edges for a source rr_node
+ * For src rr_node, update the edge list and update switch_id,
+ * For des rr_node, update the fan_in
+ ***********************************************************************/
+void add_edges_for_two_rr_nodes(const t_rr_graph* rr_graph,
+ const int src_rr_node_id,
+ const std::vector des_rr_node_ids,
+ const std::vector driver_switches) {
+ /* Check src_rr_node id is in range */
+ assert ( (-1 < src_rr_node_id) && (src_rr_node_id < rr_graph->num_rr_nodes) );
+
+ t_rr_node* src_rr_node = &(rr_graph->rr_node[src_rr_node_id]);
+
+ /* Check des_rr_node and driver_switches should match in size */
+ assert ( des_rr_node_ids.size() == driver_switches.size() );
+
+ /* Get a stamp of the current num_edges of src_rr_node */
+ int start_edge_id = src_rr_node->num_edges;
+
+ /* To avoid adding redundant edges,
+ * we will search the edge list and
+ * check if each des_rr_node_id already exists
+ * We rebuild a vector des_rr_node_ids_to_add where redundancy is removed
+ */
+ std::vector des_rr_node_ids_to_add;
+ std::vector driver_switches_to_add;
+ for (size_t inode = 0; inode < des_rr_node_ids.size(); ++inode) {
+ /* search */
+ bool is_redundant = false;
+ for (int iedge = 0; iedge < src_rr_node->num_edges; ++iedge) {
+ if (des_rr_node_ids[inode] == src_rr_node->edges[iedge]) {
+ is_redundant = true;
+ break;
+ }
+ }
+ /* add or skip */
+ if (true == is_redundant) {
+ continue; /* go to the next */
+ }
+ assert (false == is_redundant);
+ /* add to the list */
+ des_rr_node_ids_to_add.push_back(des_rr_node_ids[inode]);
+ driver_switches_to_add.push_back(driver_switches[inode]);
+ }
+
+ /* Allocate edge and switch to src_rr_node */
+ src_rr_node->num_edges += des_rr_node_ids_to_add.size();
+ if (NULL == src_rr_node->edges) {
+ /* calloc */
+ src_rr_node->edges = (int*) my_calloc( src_rr_node->num_edges, sizeof(int) );
+ src_rr_node->switches = (short*) my_calloc( src_rr_node->num_edges, sizeof(short) );
+ } else {
+ /* realloc */
+ src_rr_node->edges = (int*) my_realloc(src_rr_node->edges,
+ src_rr_node->num_edges * sizeof(int));
+ src_rr_node->switches = (short*) my_realloc(src_rr_node->switches,
+ src_rr_node->num_edges * sizeof(short));
+ }
+
+ for (size_t inode = 0; inode < des_rr_node_ids_to_add.size(); ++inode) {
+ /* Check des_rr_node id is in range */
+ int des_rr_node_id = des_rr_node_ids_to_add[inode];
+ assert ( (-1 < des_rr_node_id) && (des_rr_node_id < rr_graph->num_rr_nodes) );
+
+ t_rr_node* des_rr_node = &(rr_graph->rr_node[des_rr_node_id]);
+
+ /* Fill edge and switch info */
+ src_rr_node->edges[start_edge_id] = des_rr_node_id;
+ src_rr_node->switches[start_edge_id] = driver_switches_to_add[inode];
+
+ /* Update the des_rr_node */
+ des_rr_node->fan_in++;
+ /* Increment the start_edge_id */
+ start_edge_id++;
+ }
+
+ /* Check */
+ assert( start_edge_id == src_rr_node->num_edges );
+
+ return;
+
+}
+
/************************************************************************
* Get the coordinator of a starting point of a routing track
* For routing tracks in INC_DIRECTION
diff --git a/vpr7_x2p/vpr/SRC/device/rr_graph/rr_graph_builder_utils.h b/vpr7_x2p/vpr/SRC/device/rr_graph/rr_graph_builder_utils.h
index 07ed2f543..6c5471b5c 100644
--- a/vpr7_x2p/vpr/SRC/device/rr_graph/rr_graph_builder_utils.h
+++ b/vpr7_x2p/vpr/SRC/device/rr_graph/rr_graph_builder_utils.h
@@ -30,6 +30,11 @@ void add_one_edge_for_two_rr_nodes(const t_rr_graph* rr_graph,
const int des_rr_node_id,
const short switch_id);
+void add_edges_for_two_rr_nodes(const t_rr_graph* rr_graph,
+ const int src_rr_node_id,
+ const std::vector des_rr_node,
+ const std::vector driver_switches);
+
DeviceCoordinator get_track_rr_node_start_coordinator(const t_rr_node* track_rr_node);
DeviceCoordinator get_track_rr_node_end_coordinator(const t_rr_node* track_rr_node);
diff --git a/vpr7_x2p/vpr/SRC/device/rr_graph/tileable_rr_graph_gsb.cpp b/vpr7_x2p/vpr/SRC/device/rr_graph/tileable_rr_graph_gsb.cpp
index c784ad1d2..f039a687f 100755
--- a/vpr7_x2p/vpr/SRC/device/rr_graph/tileable_rr_graph_gsb.cpp
+++ b/vpr7_x2p/vpr/SRC/device/rr_graph/tileable_rr_graph_gsb.cpp
@@ -209,6 +209,9 @@ bool is_gsb_in_track_sb_population(const RRGSB& rr_gsb,
static
std::vector get_to_track_list(const int Fs, const int to_track, const int num_to_tracks) {
std::vector to_tracks;
+ /* Ensure a clear start */
+ to_tracks.clear();
+
for (int i = 0; i < Fs; i = i + 3) {
/* TODO: currently, for Fs > 3, I always search the next from_track until Fs is satisfied
* The optimal track selection should be done in a more scientific way!!!
@@ -244,6 +247,8 @@ std::vector get_switch_block_to_track_id(const enum e_switch_block_type
* connect. It supports any Fs % 3 == 0, switch blocks.
*/
std::vector to_tracks;
+ /* Ensure a clear start */
+ to_tracks.clear();
/* TODO: currently, for Fs > 3, I always search the next from_track until Fs is satisfied
* The optimal track selection should be done in a more scientific way!!!
@@ -251,9 +256,12 @@ std::vector get_switch_block_to_track_id(const enum e_switch_block_type
assert (0 == Fs % 3);
+ /* Adapt from_track to fit in the range of num_to_tracks */
+ size_t actual_from_track = from_track % num_to_tracks;
+
switch (switch_block_type) {
case SUBSET: /* NB: Global routing uses SUBSET too */
- to_tracks = get_to_track_list(Fs, from_track, num_to_tracks);
+ to_tracks = get_to_track_list(Fs, actual_from_track, num_to_tracks);
/* Finish, we return */
return to_tracks;
case UNIVERSAL:
@@ -266,9 +274,9 @@ std::vector get_switch_block_to_track_id(const enum e_switch_block_type
Side side_manager(from_side);
if ( (to_side == side_manager.get_opposite())
|| (to_side == side_manager.get_rotate_counterclockwise()) ) {
- to_tracks = get_to_track_list(Fs, from_track, num_to_tracks);
+ to_tracks = get_to_track_list(Fs, actual_from_track, num_to_tracks);
} else if (to_side == side_manager.get_rotate_clockwise()) {
- to_tracks = get_to_track_list(Fs, num_to_tracks - 1 - from_track, num_to_tracks);
+ to_tracks = get_to_track_list(Fs, num_to_tracks - 1 - actual_from_track, num_to_tracks);
}
}
@@ -281,9 +289,9 @@ std::vector get_switch_block_to_track_id(const enum e_switch_block_type
Side side_manager(from_side);
if ( (to_side == side_manager.get_opposite())
|| (to_side == side_manager.get_rotate_clockwise()) ) {
- to_tracks = get_to_track_list(Fs, from_track, num_to_tracks);
+ to_tracks = get_to_track_list(Fs, actual_from_track, num_to_tracks);
} else if (to_side == side_manager.get_rotate_counterclockwise()) {
- to_tracks = get_to_track_list(Fs, num_to_tracks - 1 - from_track, num_to_tracks);
+ to_tracks = get_to_track_list(Fs, num_to_tracks - 1 - actual_from_track, num_to_tracks);
}
}
/* Finish, we return */
@@ -293,35 +301,35 @@ std::vector get_switch_block_to_track_id(const enum e_switch_block_type
/* See S. Wilton Phd thesis, U of T, 1996 p. 103 for details on following. */
if (from_side == LEFT) {
if (to_side == RIGHT) { /* CHANX to CHANX */
- to_tracks = get_to_track_list(Fs, from_track, num_to_tracks);
+ to_tracks = get_to_track_list(Fs, actual_from_track, num_to_tracks);
} else if (to_side == TOP) { /* from CHANX to CHANY */
- to_tracks = get_to_track_list(Fs, (num_to_tracks - (from_track % num_to_tracks)) % num_to_tracks, num_to_tracks);
+ to_tracks = get_to_track_list(Fs, (num_to_tracks - actual_from_track ) % num_to_tracks, num_to_tracks);
} else if (to_side == BOTTOM) {
- to_tracks = get_to_track_list(Fs, (num_to_tracks + from_track - 1) % num_to_tracks, num_to_tracks);
+ to_tracks = get_to_track_list(Fs, (num_to_tracks + actual_from_track - 1) % num_to_tracks, num_to_tracks);
}
} else if (from_side == RIGHT) {
if (to_side == LEFT) { /* CHANX to CHANX */
- to_tracks = get_to_track_list(Fs, from_track, num_to_tracks);
+ to_tracks = get_to_track_list(Fs, actual_from_track, num_to_tracks);
} else if (to_side == TOP) { /* from CHANX to CHANY */
- to_tracks = get_to_track_list(Fs, (num_to_tracks + from_track - 1) % num_to_tracks, num_to_tracks);
+ to_tracks = get_to_track_list(Fs, (num_to_tracks + actual_from_track - 1) % num_to_tracks, num_to_tracks);
} else if (to_side == BOTTOM) {
- to_tracks = get_to_track_list(Fs, (num_to_tracks - 2 - from_track) % num_to_tracks, num_to_tracks);
+ to_tracks = get_to_track_list(Fs, (2 * num_to_tracks - 2 - actual_from_track) % num_to_tracks, num_to_tracks);
}
} else if (from_side == BOTTOM) {
if (to_side == TOP) { /* CHANY to CHANY */
- to_tracks = get_to_track_list(Fs, from_track, num_to_tracks);
+ to_tracks = get_to_track_list(Fs, actual_from_track, num_to_tracks);
} else if (to_side == LEFT) { /* from CHANY to CHANX */
- to_tracks = get_to_track_list(Fs, (from_track + 1) % num_to_tracks, num_to_tracks);
+ to_tracks = get_to_track_list(Fs, (actual_from_track + 1) % num_to_tracks, num_to_tracks);
} else if (to_side == RIGHT) {
- to_tracks = get_to_track_list(Fs, (2 * num_to_tracks - 2 - from_track) % num_to_tracks, num_to_tracks);
+ to_tracks = get_to_track_list(Fs, (2 * num_to_tracks - 2 - actual_from_track) % num_to_tracks, num_to_tracks);
}
} else if (from_side == TOP) {
if (to_side == BOTTOM) { /* CHANY to CHANY */
to_tracks = get_to_track_list(Fs, from_track, num_to_tracks);
} else if (to_side == LEFT) { /* from CHANY to CHANX */
- to_tracks = get_to_track_list(Fs, (num_to_tracks - (from_track % num_to_tracks)) % num_to_tracks, num_to_tracks);
+ to_tracks = get_to_track_list(Fs, (num_to_tracks - actual_from_track) % num_to_tracks, num_to_tracks);
} else if (to_side == RIGHT) {
- to_tracks = get_to_track_list(Fs, (from_track + 1) % num_to_tracks, num_to_tracks);
+ to_tracks = get_to_track_list(Fs, (actual_from_track + 1) % num_to_tracks, num_to_tracks);
}
}
/* Finish, we return */
@@ -388,11 +396,22 @@ void build_gsb_one_group_track_to_track_map(const t_rr_graph* rr_graph,
for (size_t to_track_id = 0; to_track_id < to_track_ids.size(); ++to_track_id) {
size_t from_side_index = side_manager.to_size_t();
size_t from_track_index = from_tracks[side][inode];
+ /* Check the id is still in the range !*/
+ assert ( to_track_ids[to_track_id] < to_tracks[to_side_index].size() );
size_t to_track_index = to_tracks[to_side_index][to_track_ids[to_track_id]];
//printf("from_track(size=%lu): %lu , to_track_ids[%lu]:%lu, to_track_index: %lu in a group of %lu tracks\n",
// from_tracks[side].size(), inode, to_track_id, to_track_ids[to_track_id],
// to_track_index, to_tracks[to_side_index].size());
t_rr_node* to_track_node = rr_gsb.get_chan_node(to_side, to_track_index);
+
+ /* Check if the to_track_node is already in the list ! */
+ std::vector::iterator it = std::find((*track2track_map)[from_side_index][from_track_index].begin(),
+ (*track2track_map)[from_side_index][from_track_index].end(),
+ to_track_node - rr_graph->rr_node);
+ if (it != (*track2track_map)[from_side_index][from_track_index].end()) {
+ continue; /* the node_id is already in the list, go for the next */
+ }
+ /* Clear, we should add to the list */
(*track2track_map)[from_side_index][from_track_index].push_back(to_track_node - rr_graph->rr_node);
}
}
@@ -927,13 +946,15 @@ void build_edges_for_one_tileable_rr_gsb(const t_rr_graph* rr_graph,
t_rr_node* opin_node = rr_gsb->get_opin_node(gsb_side, inode);
/* 1. create edges between OPINs and CHANX|CHANY, using opin2track_map */
- int num_edges = opin2track_map[side_manager.to_size_t()][inode].size();
+ std::vector driver_switches;
+ int num_edges = opin2track_map[gsb_side][inode].size();
for (int iedge = 0; iedge < num_edges; ++iedge) {
int track_node_id = opin2track_map[side_manager.to_size_t()][inode][iedge];
- /* add edges to the chan_node */
- add_one_edge_for_two_rr_nodes(rr_graph, opin_node - rr_graph->rr_node, track_node_id,
- rr_graph->rr_node[track_node_id].driver_switch);
+ driver_switches.push_back(rr_graph->rr_node[track_node_id].driver_switch);
}
+ /* add edges to the opin_node */
+ add_edges_for_two_rr_nodes(rr_graph, opin_node - rr_graph->rr_node,
+ opin2track_map[gsb_side][inode], driver_switches);
}
/* Find CHANX or CHANY */
@@ -945,26 +966,30 @@ void build_edges_for_one_tileable_rr_gsb(const t_rr_graph* rr_graph,
/* 2. create edges between CHANX|CHANY and IPINs, using ipin2track_map */
for (size_t inode = 0; inode < rr_gsb->get_chan_width(gsb_side); ++inode) {
t_rr_node* chan_node = rr_gsb->get_chan_node(gsb_side, inode);
- int num_edges = track2ipin_map[side_manager.to_size_t()][inode].size();
+ std::vector driver_switches;
+ int num_edges = track2ipin_map[gsb_side][inode].size();
for (int iedge = 0; iedge < num_edges; ++iedge) {
- int ipin_node_id = track2ipin_map[side_manager.to_size_t()][inode][iedge];
- /* add edges to the chan_node */
- add_one_edge_for_two_rr_nodes(rr_graph, chan_node - rr_graph->rr_node, ipin_node_id,
- rr_graph->rr_node[ipin_node_id].driver_switch);
+ int ipin_node_id = track2ipin_map[gsb_side][inode][iedge];
+ driver_switches.push_back(rr_graph->rr_node[ipin_node_id].driver_switch);
}
+ /* add edges to the chan_node */
+ add_edges_for_two_rr_nodes(rr_graph, chan_node - rr_graph->rr_node,
+ track2ipin_map[gsb_side][inode], driver_switches);
}
}
/* 3. create edges between CHANX|CHANY and CHANX|CHANY, using track2track_map */
for (size_t inode = 0; inode < rr_gsb->get_chan_width(gsb_side); ++inode) {
t_rr_node* chan_node = rr_gsb->get_chan_node(gsb_side, inode);
- int num_edges = track2track_map[side_manager.to_size_t()][inode].size();
+ std::vector driver_switches;
+ int num_edges = track2track_map[gsb_side][inode].size();
for (int iedge = 0; iedge < num_edges; ++iedge) {
- int track_node_id = track2track_map[side_manager.to_size_t()][inode][iedge];
- /* add edges to the chan_node */
- add_one_edge_for_two_rr_nodes(rr_graph, chan_node - rr_graph->rr_node, track_node_id,
- rr_graph->rr_node[track_node_id].driver_switch);
+ int track_node_id = track2track_map[gsb_side][inode][iedge];
+ driver_switches.push_back(rr_graph->rr_node[track_node_id].driver_switch);
}
+ /* add edges to the chan_node */
+ add_edges_for_two_rr_nodes(rr_graph, chan_node - rr_graph->rr_node,
+ track2track_map[gsb_side][inode], driver_switches);
}
}
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 11a15bdea..f82d740dc 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
@@ -1,7 +1,46 @@
-/***********************************/
-/* SPICE Modeling for VPR */
-/* Xifan TANG, EPFL/LSI */
-/***********************************/
+/**********************************************************
+ * MIT License
+ *
+ * Copyright (c) 2018 LNIS - The University of Utah
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ ***********************************************************************/
+
+/************************************************************************
+ * Filename: fpga_x2p_unique_routing.c
+ * Created by: Xifan Tang
+ * Change history:
+ * +-------------------------------------+
+ * | Date | Author | Notes
+ * +-------------------------------------+
+ * | 2019/06/25 | Xifan Tang | Created
+ * +-------------------------------------+
+ ***********************************************************************/
+/************************************************************************
+ * This file contains builders for the data structures
+ * 1. RRGSB: General Switch Block (GSB).
+ * 2. RRChan: Generic routing channels
+ * We also include functions to identify unique modules of
+ * Switch Blocks and Connection Blocks based on the data structures
+ * t_sb and t_cb
+ ***********************************************************************/
+
#include
#include
#include
@@ -1096,157 +1135,6 @@ RRGSB build_rr_gsb(DeviceCoordinator& device_range,
return rr_gsb;
}
-/* Rotate the Switch block and try to add to rotatable mirrors */
-static
-RRGSB rotate_rr_switch_block_for_mirror(DeviceCoordinator& device_range,
- const RRGSB& rr_switch_block) {
- RRGSB 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:
- * nothing to do. This is the base we like
- */
- if ( ( 0 == rotated_rr_switch_block.get_sb_x())
- && ( 0 == rotated_rr_switch_block.get_sb_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_sb_x())
- && (device_range.get_y() == rotated_rr_switch_block.get_sb_y()) ) {
- rotated_rr_switch_block.swap_opin_node(TOP, BOTTOM);
- rotated_rr_switch_block.swap_chan_node(TOP, 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_sb_x())
- && (device_range.get_y() == rotated_rr_switch_block.get_sb_y()) ) {
- rotated_rr_switch_block.swap_opin_node(TOP, BOTTOM);
- rotated_rr_switch_block.swap_chan_node(TOP, BOTTOM);
- rotated_rr_switch_block.swap_opin_node(LEFT, RIGHT);
- rotated_rr_switch_block.swap_chan_node(LEFT, 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_sb_x())
- && (0 == rotated_rr_switch_block.get_sb_y()) ) {
- rotated_rr_switch_block.swap_opin_node(LEFT, RIGHT);
- rotated_rr_switch_block.swap_chan_node(LEFT, 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_sb_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_sb_y() ) {
-
- /* 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_sb_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_sb_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_sb_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_sb_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:
- * 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_sb_x() ) {
-
- /* 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_sb_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_sb_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_sb_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_sb_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:
- * nothing to do. This is the base we like
- */
- if (0 == rotated_rr_switch_block.get_sb_x() ) {
- return rotated_rr_switch_block;
- }
-
- /* SB[1][1] is the baseline, we do not modify */
- if ( (1 == rotated_rr_switch_block.get_sb_x())
- && (1 == rotated_rr_switch_block.get_sb_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 */
- if (1 < rotated_rr_switch_block.get_sb_y()) {
- rotated_rr_switch_block.rotate_side_chan_node_by_direction(TOP, INC_DIRECTION, Fco_offset * (rotated_rr_switch_block.get_sb_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_sb_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_sb_x()) {
- rotated_rr_switch_block.rotate_side_chan_node_by_direction(RIGHT, INC_DIRECTION, Fco_offset * (rotated_rr_switch_block.get_sb_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_sb_x() - 1));
- }
-
- /* For BOTTOM SIDE: Y-channel in DEC_DIRECTION, rotate by an offset of its y-coordinator */
- if ( 1 < rotated_rr_switch_block.get_sb_y()) {
- rotated_rr_switch_block.counter_rotate_side_chan_node_by_direction(BOTTOM, DEC_DIRECTION, Fco_offset * (rotated_rr_switch_block.get_sb_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_sb_y() - 1));
- }
-
- /* For LEFT SIDE: X-channel in DEC_DIRECTION, rotate by an offset of its x-coordinator */
- if ( 1 < rotated_rr_switch_block.get_sb_x()) {
- rotated_rr_switch_block.counter_rotate_side_chan_node_by_direction(LEFT, DEC_DIRECTION, Fco_offset * (rotated_rr_switch_block.get_sb_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_sb_x() - 1));
- }
-
- return rotated_rr_switch_block;
-}
-
/* sort drive_rr_nodes of a rr_node inside rr_gsb subject to the index of rr_gsb array */
static
void sort_rr_gsb_one_ipin_node_drive_rr_nodes(const RRGSB& rr_gsb,
@@ -1504,33 +1392,9 @@ DeviceRRGSB build_device_rr_gsb(boolean output_sb_xml, char* sb_xml_dir,
}
}
- /* Create directory if needed */
- if (TRUE == output_sb_xml) {
- create_dir_path(sb_xml_dir);
- }
-
- for (size_t ix = 0; ix <= sb_range.get_x(); ++ix) {
- for (size_t iy = 0; iy <= sb_range.get_y(); ++iy) {
- RRGSB rr_gsb = LL_device_rr_gsb.get_gsb(ix, iy);
- RRGSB rotated_rr_sb = rotate_rr_switch_block_for_mirror(sb_range, rr_gsb);
- if (TRUE == output_sb_xml) {
- std::string fname_prefix(sb_xml_dir);
- /* Add slash if needed */
- //if ('/' != fname_prefix.back()) {
- // fname_prefix += "/";
- //}
- //fname_prefix += "rotated_";
- //write_rr_switch_block_to_xml(fname_prefix, rotated_rr_sb);
- write_rr_switch_block_to_xml(fname_prefix, rr_gsb);
- }
- }
- }
-
return LL_device_rr_gsb;
}
-
-/* Rotatable will be done in the next step
-void identify_rotatable_switch_blocks();
-void identify_rotatable_connection_blocks();
-*/
+/************************************************************************
+ * End of file : fpga_x2p_unique_routing.c
+ ***********************************************************************/
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 2669e2e0a..d789b1154 100644
--- a/vpr7_x2p/vpr/SRC/fpga_x2p/base/rr_blocks.cpp
+++ b/vpr7_x2p/vpr/SRC/fpga_x2p/base/rr_blocks.cpp
@@ -1447,7 +1447,7 @@ const char* RRGSB::gen_gsb_verilog_module_name() const {
std::string y_str = std::to_string(get_sb_y());
char* ret = (char*)my_malloc(sizeof(char)*
- ( 2 + 1
+ ( 3 + 1
+ x_str.length() + 2
+ y_str.length() + 1
+ 1));
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
index 2357bfd50..e203bc75f 100644
--- a/vpr7_x2p/vpr/SRC/fpga_x2p/base/write_rr_blocks.cpp
+++ b/vpr7_x2p/vpr/SRC/fpga_x2p/base/write_rr_blocks.cpp
@@ -31,7 +31,7 @@ void write_rr_switch_block_to_xml(std::string fname_prefix, RRGSB& rr_gsb) {
/* Output each side */
for (size_t side = 0; side < rr_gsb.get_num_sides(); ++side) {
Side gsb_side_manager(side);
- enum e_side gsb_side = gsb_side;
+ enum e_side gsb_side = gsb_side_manager.get_side();
/* Output IPIN nodes */
for (size_t inode = 0; inode < rr_gsb.get_num_ipin_nodes(gsb_side); ++inode) {
@@ -117,7 +117,9 @@ void write_rr_switch_block_to_xml(std::string fname_prefix, RRGSB& rr_gsb) {
enum e_side drive_node_side = NUM_SIDES;
int drive_node_index = -1;
rr_gsb.get_node_side_and_index(drive_rr_nodes[jnode], IN_PORT, &drive_node_side, &drive_node_index);
+ assert(-1 != drive_node_index);
Side drive_side(drive_node_side);
+
if (OPIN == drive_rr_nodes[jnode]->type) {
Side grid_side(rr_gsb.get_opin_node_grid_side(drive_node_side, drive_node_index));
fp << "\t\t