From 4d3b5f12b4bab4ed501ca885e978181e12c7b95d Mon Sep 17 00:00:00 2001 From: tangxifan Date: Tue, 25 Jun 2019 14:15:29 -0600 Subject: [PATCH] fixed bugs for UNIVERSAL and WILTON switch blocks --- .../k6_N10_sram_chain_HC_template.xml | 2 +- .../rr_graph/rr_graph_builder_utils.cpp | 85 +++++++ .../device/rr_graph/rr_graph_builder_utils.h | 5 + .../device/rr_graph/tileable_rr_graph_gsb.cpp | 85 ++++--- .../fpga_x2p/base/fpga_x2p_unique_routing.c | 228 ++++-------------- vpr7_x2p/vpr/SRC/fpga_x2p/base/rr_blocks.cpp | 2 +- .../vpr/SRC/fpga_x2p/base/write_rr_blocks.cpp | 4 +- 7 files changed, 196 insertions(+), 215 deletions(-) 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