fixed the bug in determine passing wires for rr_gsb
This commit is contained in:
parent
a3670bb752
commit
d50fb7ee19
|
@ -1197,18 +1197,19 @@ void sort_rr_gsb_one_ipin_node_drive_rr_nodes(const RRGSB& rr_gsb,
|
|||
/* 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_chan_node_drive_rr_nodes(const RRGSB& rr_gsb,
|
||||
t_rr_node* chan_node,
|
||||
enum e_side chan_side) {
|
||||
enum e_side chan_side,
|
||||
size_t track_id) {
|
||||
|
||||
/* If this is a passing wire, we return directly.
|
||||
* The passing wire will be handled in other GSBs
|
||||
*/
|
||||
if (true == rr_gsb.is_sb_node_imply_short_connection(chan_node)) {
|
||||
/* Double check if the interc lies inside a channel wire, that is interc between segments */
|
||||
assert(true == rr_gsb.is_sb_node_exist_opposite_side(chan_node, chan_side));
|
||||
if (true == rr_gsb.is_sb_node_passing_wire(chan_side, track_id)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Get the chan_node */
|
||||
t_rr_node* chan_node = rr_gsb.get_chan_node(chan_side, track_id);
|
||||
|
||||
/* Create a copy of the edges and switches of this node */
|
||||
std::vector<t_rr_node*> sorted_drive_nodes;
|
||||
std::vector<int> sorted_drive_switches;
|
||||
|
@ -1301,8 +1302,8 @@ void sort_rr_gsb_drive_rr_nodes(const RRGSB& rr_gsb) {
|
|||
}
|
||||
/* Get the chan side, so we have the routing tracks */
|
||||
sort_rr_gsb_one_chan_node_drive_rr_nodes(rr_gsb,
|
||||
rr_gsb.get_chan_node(gsb_side, inode),
|
||||
gsb_side);
|
||||
gsb_side,
|
||||
inode);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,3 +1,42 @@
|
|||
/**********************************************************
|
||||
* 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: rr_blocks.cpp
|
||||
* Created by: Xifan Tang
|
||||
* Change history:
|
||||
* +-------------------------------------+
|
||||
* | Date | Author | Notes
|
||||
* +-------------------------------------+
|
||||
* | 2019/06/26 | Xifan Tang | Created
|
||||
* +-------------------------------------+
|
||||
***********************************************************************/
|
||||
/************************************************************************
|
||||
* This file contains member function for the data structures defined
|
||||
* in rr_block.h
|
||||
***********************************************************************/
|
||||
|
||||
#include <cassert>
|
||||
#include <string.h>
|
||||
#include <algorithm>
|
||||
|
@ -7,6 +46,8 @@
|
|||
|
||||
#include "rr_blocks.h"
|
||||
|
||||
#include "rr_graph_builder_utils.h"
|
||||
|
||||
|
||||
/* Member Functions of Class RRChan */
|
||||
/* Constructors */
|
||||
|
@ -1003,24 +1044,53 @@ size_t RRGSB::get_cb_conf_bits_msb(t_rr_type cb_type) const {
|
|||
}
|
||||
}
|
||||
|
||||
/* Check if the node imply a short connection inside the SB, which happens to long wires across a FPGA fabric */
|
||||
bool RRGSB::is_sb_node_imply_short_connection(t_rr_node* src_node) const {
|
||||
/************************************************************************
|
||||
* Check if the node indicates a passing wire across the Switch Block part of the GSB
|
||||
* Therefore, we actually do the following check
|
||||
* Check if a track starts from this GSB or not
|
||||
* For INC_DIRECTION
|
||||
* (xlow, ylow) should be same as the GSB side coordinator
|
||||
* For DEC_DIRECTION
|
||||
* (xhigh, yhigh) should be same as the GSB side coordinator
|
||||
***********************************************************************/
|
||||
bool RRGSB::is_sb_node_passing_wire(const enum e_side node_side,
|
||||
const size_t track_id) const {
|
||||
|
||||
assert((CHANX == src_node->type) || (CHANY == src_node->type));
|
||||
|
||||
for (size_t inode = 0; inode < size_t(src_node->num_drive_rr_nodes); ++inode) {
|
||||
enum e_side side;
|
||||
int index;
|
||||
get_node_side_and_index(src_node->drive_rr_nodes[inode], IN_PORT, &side, &index);
|
||||
/* We need to be sure that drive_rr_node is part of the SB */
|
||||
if ( ((-1 == index) || (NUM_SIDES == side))
|
||||
&& ( (CHANX == src_node->drive_rr_nodes[inode]->type)
|
||||
|| (CHANY == src_node->drive_rr_nodes[inode]->type) ) ) {
|
||||
return true;
|
||||
}
|
||||
/* Get the rr_node */
|
||||
t_rr_node* track_node = get_chan_node(node_side, track_id);
|
||||
/* Get the coordinators */
|
||||
DeviceCoordinator side_coordinator = get_side_block_coordinator(node_side);
|
||||
|
||||
/* Get the coordinator of where the track starts */
|
||||
DeviceCoordinator track_start = get_track_rr_node_start_coordinator(track_node);
|
||||
|
||||
/* INC_DIRECTION start_track: (xlow, ylow) should be same as the GSB side coordinator */
|
||||
/* DEC_DIRECTION start_track: (xhigh, yhigh) should be same as the GSB side coordinator */
|
||||
if ( (track_start.get_x() == side_coordinator.get_x())
|
||||
&& (track_start.get_y() == side_coordinator.get_y())
|
||||
&& (OUT_PORT == get_chan_node_direction(node_side, track_id)) ) {
|
||||
/* Double check: start track should be an OUTPUT PORT of the GSB */
|
||||
return false; /* This is a starting point */
|
||||
}
|
||||
|
||||
return false;
|
||||
/* Get the coordinator of where the track ends */
|
||||
DeviceCoordinator track_end = get_track_rr_node_end_coordinator(track_node);
|
||||
|
||||
/* INC_DIRECTION end_track: (xhigh, yhigh) should be same as the GSB side coordinator */
|
||||
/* DEC_DIRECTION end_track: (xlow, ylow) should be same as the GSB side coordinator */
|
||||
if ( (track_end.get_x() == side_coordinator.get_x())
|
||||
&& (track_end.get_y() == side_coordinator.get_y())
|
||||
&& (IN_PORT == get_chan_node_direction(node_side, track_id)) ) {
|
||||
/* Double check: end track should be an INPUT PORT of the GSB */
|
||||
return false; /* This is an ending point */
|
||||
}
|
||||
|
||||
/* Reach here it means that this will be a passing wire,
|
||||
* we should be able to find the node on the opposite side of the GSB!
|
||||
*/
|
||||
assert (true == is_sb_node_exist_opposite_side(track_node, node_side));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* check if the candidate SB satisfy the basic requirements on being a mirror of the current one */
|
||||
|
@ -2050,18 +2120,10 @@ bool RRGSB::is_sb_node_mirror(const RRGSB& cand,
|
|||
/* Ensure rr_nodes are either the output of short-connection or multiplexer */
|
||||
t_rr_node* node = this->get_chan_node(node_side, track_id);
|
||||
t_rr_node* cand_node = cand.get_chan_node(node_side, track_id);
|
||||
bool is_short_conkt = this->is_sb_node_imply_short_connection(node);
|
||||
bool is_short_conkt = this->is_sb_node_passing_wire(node_side, track_id);
|
||||
|
||||
if (is_short_conkt != cand.is_sb_node_imply_short_connection(cand_node)) {
|
||||
if (is_short_conkt != cand.is_sb_node_passing_wire(node_side, track_id)) {
|
||||
return false;
|
||||
}
|
||||
/* Find the driving rr_node in this sb */
|
||||
if (true == is_short_conkt) {
|
||||
/* Ensure we have the same track id for the driving nodes */
|
||||
if ( this->is_sb_node_exist_opposite_side(node, node_side)
|
||||
!= cand.is_sb_node_exist_opposite_side(cand_node, node_side)) {
|
||||
return false;
|
||||
}
|
||||
} else { /* check driving rr_nodes */
|
||||
if ( node->num_drive_rr_nodes != cand_node->num_drive_rr_nodes ) {
|
||||
return false;
|
||||
|
@ -2156,7 +2218,7 @@ size_t RRGSB::get_track_id_first_short_connection(enum e_side node_side) const {
|
|||
|
||||
/* Walk through chan_nodes and find the first short connection */
|
||||
for (size_t inode = 0; inode < get_chan_width(node_side); ++inode) {
|
||||
if (true == is_sb_node_imply_short_connection(get_chan_node(node_side, inode))) {
|
||||
if (true == is_sb_node_passing_wire(node_side, inode)) {
|
||||
return inode;
|
||||
}
|
||||
}
|
||||
|
@ -2989,3 +3051,6 @@ bool DeviceRRGSB::validate_cb_type(t_rr_type cb_type) const {
|
|||
return false;
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* End of file : rr_blocks.cpp
|
||||
***********************************************************************/
|
||||
|
|
|
@ -219,7 +219,7 @@ class RRGSB {
|
|||
size_t get_cb_num_conf_bits(t_rr_type cb_type) const;
|
||||
size_t get_cb_conf_bits_lsb(t_rr_type cb_type) const;
|
||||
size_t get_cb_conf_bits_msb(t_rr_type cb_type) const;
|
||||
bool is_sb_node_imply_short_connection(t_rr_node* src_node) const; /* Check if the node imply a short connection inside the SB, which happens to long wires across a FPGA fabric */
|
||||
bool is_sb_node_passing_wire(const enum e_side node_side, const size_t track_id) const; /* Check if the node imply a short connection inside the SB, which happens to long wires across a FPGA fabric */
|
||||
bool is_sb_side_mirror(const RRGSB& cand, enum e_side side) const; /* check if a side of candidate SB is a mirror of the current one */
|
||||
bool is_sb_side_segment_mirror(const RRGSB& cand, enum e_side side, size_t seg_id) const; /* check if all the routing segments of a side of candidate SB is a mirror of the current one */
|
||||
bool is_sb_mirror(const RRGSB& cand) const; /* check if the candidate SB is a mirror of the current one */
|
||||
|
|
|
@ -85,9 +85,7 @@ void write_rr_switch_block_to_xml(std::string fname_prefix, RRGSB& rr_gsb) {
|
|||
size_t src_segment_id = rr_gsb.get_chan_node_segment(gsb_side, inode);
|
||||
|
||||
/* Check if this node is directly connected to the node on the opposite side */
|
||||
if (true == rr_gsb.is_sb_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_gsb.is_sb_node_exist_opposite_side(cur_rr_node, gsb_side));
|
||||
if (true == rr_gsb.is_sb_node_passing_wire(gsb_side, inode)) {
|
||||
num_drive_rr_nodes = 0;
|
||||
drive_rr_nodes = NULL;
|
||||
} else {
|
||||
|
|
|
@ -216,7 +216,7 @@ void fpga_spice_generate_bitstream_switch_box_interc(FILE* fp,
|
|||
const RRGSB& rr_sb,
|
||||
t_sram_orgz_info* cur_sram_orgz_info,
|
||||
enum e_side chan_side,
|
||||
t_rr_node* cur_rr_node) {
|
||||
size_t chan_node_id) {
|
||||
int num_drive_rr_nodes = 0;
|
||||
t_rr_node** drive_rr_nodes = NULL;
|
||||
|
||||
|
@ -227,12 +227,12 @@ void fpga_spice_generate_bitstream_switch_box_interc(FILE* fp,
|
|||
__FILE__, __LINE__);
|
||||
exit(1);
|
||||
}
|
||||
/* Get the rr_node */
|
||||
t_rr_node* cur_rr_node = rr_sb.get_chan_node(chan_side, chan_node_id);
|
||||
|
||||
/* Determine if the interc lies inside a channel wire, that is interc between segments */
|
||||
/* Check each num_drive_rr_nodes, see if they appear in the cur_sb_info */
|
||||
if (true == rr_sb.is_sb_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_sb_node_exist_opposite_side(cur_rr_node, chan_side));
|
||||
if (true == rr_sb.is_sb_node_passing_wire(chan_side, chan_node_id)) {
|
||||
num_drive_rr_nodes = 0;
|
||||
drive_rr_nodes = NULL;
|
||||
} else {
|
||||
|
@ -364,7 +364,7 @@ void fpga_spice_generate_bitstream_routing_switch_box_subckt(FILE* fp,
|
|||
if (OUT_PORT == rr_sb.get_chan_node_direction(side_manager.get_side(), itrack)) {
|
||||
fpga_spice_generate_bitstream_switch_box_interc(fp, rr_sb, cur_sram_orgz_info,
|
||||
side_manager.get_side(),
|
||||
rr_sb.get_chan_node(side_manager.get_side(), itrack));
|
||||
itrack);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -255,7 +255,7 @@ void vpr_fpga_verilog(t_vpr_setup vpr_setup,
|
|||
/* Dump routing resources: switch blocks, connection blocks and channel tracks */
|
||||
dump_verilog_routing_resources(sram_verilog_orgz_info, src_dir_path, rr_dir_path, Arch, &vpr_setup.RoutingArch,
|
||||
num_rr_nodes, rr_node, rr_node_indices, rr_indexed_data,
|
||||
vpr_setup.FPGA_SPICE_Opts.SynVerilogOpts, vpr_setup.FPGA_SPICE_Opts.compact_routing_hierarchy);
|
||||
vpr_setup.FPGA_SPICE_Opts.compact_routing_hierarchy);
|
||||
|
||||
/* Dump logic blocks
|
||||
* Branches to go:
|
||||
|
|
|
@ -2764,7 +2764,7 @@ void verilog_generate_routing_wires_report_timing(FILE* fp,
|
|||
||(CHANY == rr_sb.get_chan_node(side_manager.get_side(), itrack)->type));
|
||||
/* We only care the output port and it should indicate a SB mux */
|
||||
if ( (OUT_PORT != rr_sb.get_chan_node_direction(side_manager.get_side(), itrack))
|
||||
|| (true == rr_sb.is_sb_node_imply_short_connection(rr_sb.get_chan_node(side_manager.get_side(), itrack)))) {
|
||||
|| (true == rr_sb.is_sb_node_passing_wire(side_manager.get_side(), itrack))) {
|
||||
continue;
|
||||
}
|
||||
/* Bypass if we have only 1 driving node */
|
||||
|
@ -3169,7 +3169,7 @@ void verilog_generate_routing_wire_report_timing(t_trpt_opts trpt_opts,
|
|||
||(CHANY == rr_sb.get_chan_node(side_manager.get_side(), itrack)->type));
|
||||
/* We only care the output port and it should indicate a SB mux */
|
||||
if ( (OUT_PORT != rr_sb.get_chan_node_direction(side_manager.get_side(), itrack))
|
||||
|| (false != rr_sb.is_sb_node_imply_short_connection(rr_sb.get_chan_node(side_manager.get_side(), itrack)))) {
|
||||
|| (false != rr_sb.is_sb_node_passing_wire(side_manager.get_side(), itrack))) {
|
||||
continue;
|
||||
}
|
||||
/* Bypass if we have only 1 driving node */
|
||||
|
|
|
@ -308,68 +308,6 @@ void dump_verilog_routing_chan_subckt(char* verilog_dir,
|
|||
return;
|
||||
}
|
||||
|
||||
static
|
||||
t_rr_node** verilog_get_grid_side_pin_rr_nodes(int* num_pin_rr_nodes,
|
||||
t_rr_type pin_type,
|
||||
int x,
|
||||
int y,
|
||||
int side,
|
||||
t_ivec*** LL_rr_node_indices) {
|
||||
int height, ipin, class_id, inode;
|
||||
t_type_ptr type = NULL;
|
||||
t_rr_node** ret = NULL;
|
||||
enum e_pin_type pin_class_type;
|
||||
int cur;
|
||||
|
||||
/* Check */
|
||||
assert((!(0 > x))&&(!(x > (nx + 1))));
|
||||
assert((!(0 > y))&&(!(y > (ny + 1))));
|
||||
type = grid[x][y].type;
|
||||
assert(NULL != type);
|
||||
/* Assign the type of PIN*/
|
||||
switch (pin_type) {
|
||||
case IPIN:
|
||||
/* case SINK: */
|
||||
pin_class_type = RECEIVER; /* This is the end of a route path*/
|
||||
break;
|
||||
/*case SOURCE:*/
|
||||
case OPIN:
|
||||
pin_class_type = DRIVER; /* This is the start of a route path */
|
||||
break;
|
||||
/* SINK and SOURCE are hypothesis nodes */
|
||||
default:
|
||||
vpr_printf(TIO_MESSAGE_ERROR, "(File:%s, [LINE%d])Invalid pin_type!\n", __FILE__, __LINE__);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Output the pins on the side*/
|
||||
(*num_pin_rr_nodes) = 0;
|
||||
height = grid[x][y].offset;
|
||||
for (ipin = 0; ipin < type->num_pins; ipin++) {
|
||||
class_id = type->pin_class[ipin];
|
||||
if ((1 == type->pinloc[height][side][ipin])&&(pin_class_type == type->class_inf[class_id].type)) {
|
||||
(*num_pin_rr_nodes)++;
|
||||
}
|
||||
}
|
||||
/* Malloc */
|
||||
ret = (t_rr_node**)my_malloc(sizeof(t_rr_node*)*(*num_pin_rr_nodes));
|
||||
|
||||
/* Fill the return array*/
|
||||
cur = 0;
|
||||
height = grid[x][y].offset;
|
||||
for (ipin = 0; ipin < type->num_pins; ipin++) {
|
||||
class_id = type->pin_class[ipin];
|
||||
if ((1 == type->pinloc[height][side][ipin])&&(pin_class_type == type->class_inf[class_id].type)) {
|
||||
inode = get_rr_node_index(x, y, pin_type, ipin, LL_rr_node_indices);
|
||||
ret[cur] = &(rr_node[inode]);
|
||||
cur++;
|
||||
}
|
||||
}
|
||||
assert(cur == (*num_pin_rr_nodes));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void dump_verilog_grid_side_pin_with_given_index(FILE* fp, t_rr_type pin_type,
|
||||
int pin_index, int side,
|
||||
int x, int y,
|
||||
|
@ -489,142 +427,6 @@ void dump_verilog_grid_side_pins(FILE* fp,
|
|||
return;
|
||||
}
|
||||
|
||||
/* Determine the channel coordinates in switch box subckt */
|
||||
static
|
||||
void verilog_determine_src_chan_coordinate_switch_box(t_rr_node* src_rr_node,
|
||||
t_rr_node* des_rr_node,
|
||||
int side,
|
||||
int switch_box_x,
|
||||
int switch_box_y,
|
||||
int* src_chan_x,
|
||||
int* src_chan_y,
|
||||
char** src_chan_port_name) {
|
||||
/* Check */
|
||||
assert((!(0 > side))&&(side < 4));
|
||||
assert((CHANX == src_rr_node->type)||(CHANY == src_rr_node->type));
|
||||
assert((CHANX == des_rr_node->type)||(CHANY == des_rr_node->type));
|
||||
assert((!(0 > switch_box_x))&&(!(switch_box_x > (nx + 1))));
|
||||
assert((!(0 > switch_box_y))&&(!(switch_box_y > (ny + 1))));
|
||||
|
||||
/* Initialize*/
|
||||
(*src_chan_x) = 0;
|
||||
(*src_chan_y) = 0;
|
||||
(*src_chan_port_name) = NULL;
|
||||
|
||||
switch (side) {
|
||||
case 0: /*TOP*/
|
||||
/* The destination rr_node only have one condition!!! */
|
||||
assert((INC_DIRECTION == des_rr_node->direction)&&(CHANY == des_rr_node->type));
|
||||
/* Following cases:
|
||||
* |
|
||||
* / | \
|
||||
*/
|
||||
if ((INC_DIRECTION == src_rr_node->direction)&&(CHANY == src_rr_node->type)) {
|
||||
(*src_chan_x) = switch_box_x;
|
||||
(*src_chan_y) = switch_box_y;
|
||||
(*src_chan_port_name) = "in";
|
||||
} else if ((INC_DIRECTION == src_rr_node->direction)&&(CHANX == src_rr_node->type)) {
|
||||
(*src_chan_x) = switch_box_x;
|
||||
(*src_chan_y) = switch_box_y;
|
||||
(*src_chan_port_name) = "in";
|
||||
} else if ((DEC_DIRECTION == src_rr_node->direction)&&(CHANX == src_rr_node->type)) {
|
||||
(*src_chan_x) = switch_box_x + 1;
|
||||
(*src_chan_y) = switch_box_y;
|
||||
(*src_chan_port_name) = "in";
|
||||
} else {
|
||||
vpr_printf(TIO_MESSAGE_ERROR, "(File:%s, [LINE%d])Invalid source channel!\n", __FILE__, __LINE__);
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
case 1: /*RIGHT*/
|
||||
/* The destination rr_node only have one condition!!! */
|
||||
assert((INC_DIRECTION == des_rr_node->direction)&&(CHANX == des_rr_node->type));
|
||||
/* Following cases:
|
||||
* \
|
||||
* --- ----
|
||||
* /
|
||||
*/
|
||||
if ((DEC_DIRECTION == src_rr_node->direction)&&(CHANY == src_rr_node->type)) {
|
||||
(*src_chan_x) = switch_box_x;
|
||||
(*src_chan_y) = switch_box_y + 1;
|
||||
(*src_chan_port_name) = "in";
|
||||
} else if ((INC_DIRECTION == src_rr_node->direction)&&(CHANX == src_rr_node->type)) {
|
||||
(*src_chan_x) = switch_box_x;
|
||||
(*src_chan_y) = switch_box_y;
|
||||
(*src_chan_port_name) = "in";
|
||||
} else if ((INC_DIRECTION == src_rr_node->direction)&&(CHANY == src_rr_node->type)) {
|
||||
(*src_chan_x) = switch_box_x;
|
||||
(*src_chan_y) = switch_box_y;
|
||||
(*src_chan_port_name) = "in";
|
||||
} else {
|
||||
vpr_printf(TIO_MESSAGE_ERROR, "(File:%s, [LINE%d])Invalid source channel!\n", __FILE__, __LINE__);
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
case 2: /*BOTTOM*/
|
||||
/* The destination rr_node only have one condition!!! */
|
||||
assert((DEC_DIRECTION == des_rr_node->direction)&&(CHANY == des_rr_node->type));
|
||||
/* Following cases:
|
||||
* |
|
||||
* \ /
|
||||
* |
|
||||
*/
|
||||
if ((DEC_DIRECTION == src_rr_node->direction)&&(CHANY == src_rr_node->type)) {
|
||||
(*src_chan_x) = switch_box_x;
|
||||
(*src_chan_y) = switch_box_y + 1;
|
||||
(*src_chan_port_name) = "in";
|
||||
} else if ((INC_DIRECTION == src_rr_node->direction)&&(CHANX == src_rr_node->type)) {
|
||||
(*src_chan_x) = switch_box_x;
|
||||
(*src_chan_y) = switch_box_y;
|
||||
(*src_chan_port_name) = "in";
|
||||
} else if ((DEC_DIRECTION == src_rr_node->direction)&&(CHANX == src_rr_node->type)) {
|
||||
(*src_chan_x) = switch_box_x + 1;
|
||||
(*src_chan_y) = switch_box_y;
|
||||
(*src_chan_port_name) = "in";
|
||||
} else {
|
||||
vpr_printf(TIO_MESSAGE_ERROR, "(File:%s, [LINE%d])Invalid source channel!\n", __FILE__, __LINE__);
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
case 3: /*LEFT*/
|
||||
/* The destination rr_node only have one condition!!! */
|
||||
assert((DEC_DIRECTION == des_rr_node->direction)&&(CHANX == des_rr_node->type));
|
||||
/* Following cases:
|
||||
* /
|
||||
* --- ----
|
||||
* \
|
||||
*/
|
||||
if ((DEC_DIRECTION == src_rr_node->direction)&&(CHANX == src_rr_node->type)) {
|
||||
(*src_chan_x) = switch_box_x + 1;
|
||||
(*src_chan_y) = switch_box_y;
|
||||
(*src_chan_port_name) = "in";
|
||||
} else if ((INC_DIRECTION == src_rr_node->direction)&&(CHANY == src_rr_node->type)) {
|
||||
(*src_chan_x) = switch_box_x;
|
||||
(*src_chan_y) = switch_box_y;
|
||||
(*src_chan_port_name) = "in";
|
||||
} else if ((DEC_DIRECTION == src_rr_node->direction)&&(CHANY == src_rr_node->type)) {
|
||||
(*src_chan_x) = switch_box_x;
|
||||
(*src_chan_y) = switch_box_y + 1;
|
||||
(*src_chan_port_name) = "in";
|
||||
} else {
|
||||
vpr_printf(TIO_MESSAGE_ERROR, "(File:%s, [LINE%d])Invalid source channel!\n", __FILE__, __LINE__);
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
vpr_printf(TIO_MESSAGE_ERROR,"(File:%s, [LINE%d])Invalid side!\n", __FILE__, __LINE__);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Make sure the source rr_node (channel) is in the range*/
|
||||
assert((!((*src_chan_x) < src_rr_node->xlow))&&(!((*src_chan_x) > src_rr_node->xhigh)));
|
||||
if (!((!((*src_chan_y) < src_rr_node->ylow))&&(!((*src_chan_y) > src_rr_node->yhigh)))) {
|
||||
assert((!((*src_chan_y) < src_rr_node->ylow))&&(!((*src_chan_y) > src_rr_node->yhigh)));
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void dump_verilog_switch_box_chan_port(FILE* fp,
|
||||
t_sb* cur_sb_info,
|
||||
int chan_side,
|
||||
|
@ -680,6 +482,7 @@ void dump_verilog_unique_switch_box_chan_port(FILE* fp,
|
|||
/* Get the index in sb_info of cur_rr_node */
|
||||
index = rr_sb.get_node_index(cur_rr_node, chan_side, cur_rr_node_direction);
|
||||
/* Make sure this node is included in this sb_info */
|
||||
if (!((-1 != index)&&(NUM_SIDES != chan_side)))
|
||||
assert((-1 != index)&&(NUM_SIDES != chan_side));
|
||||
|
||||
chan_rr_node_type = cur_rr_node->type;
|
||||
|
@ -737,9 +540,7 @@ void dump_verilog_unique_switch_box_short_interc(FILE* fp,
|
|||
if (0 == actual_fan_in) {
|
||||
assert(drive_rr_node == cur_rr_node);
|
||||
} else {
|
||||
Side side_manager(chan_side);
|
||||
/* drive_rr_node = &(rr_node[cur_rr_node->prev_node]); */
|
||||
assert(1 == rr_node_drive_switch_box(drive_rr_node, cur_rr_node, rr_sb.get_sb_coordinator().get_x(), rr_sb.get_sb_coordinator().get_y(), side_manager.get_side()));
|
||||
assert (1 == actual_fan_in);
|
||||
}
|
||||
|
||||
int grid_x = drive_rr_node->xlow;
|
||||
|
@ -1581,7 +1382,7 @@ void dump_verilog_unique_switch_box_interc(t_sram_orgz_info* cur_sram_orgz_info,
|
|||
FILE* fp,
|
||||
const RRGSB& rr_sb,
|
||||
enum e_side chan_side,
|
||||
t_rr_node* cur_rr_node) {
|
||||
size_t chan_node_id) {
|
||||
int num_drive_rr_nodes = 0;
|
||||
t_rr_node** drive_rr_nodes = NULL;
|
||||
|
||||
|
@ -1592,11 +1393,12 @@ void dump_verilog_unique_switch_box_interc(t_sram_orgz_info* cur_sram_orgz_info,
|
|||
exit(1);
|
||||
}
|
||||
|
||||
/* Get the node */
|
||||
t_rr_node* cur_rr_node = rr_sb.get_chan_node(chan_side, chan_node_id);
|
||||
|
||||
/* Determine if the interc lies inside a channel wire, that is interc between segments */
|
||||
/* Check each num_drive_rr_nodes, see if they appear in the cur_sb_info */
|
||||
if (true == rr_sb.is_sb_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_sb_node_exist_opposite_side(cur_rr_node, chan_side));
|
||||
if (true == rr_sb.is_sb_node_passing_wire(chan_side, chan_node_id)) {
|
||||
num_drive_rr_nodes = 0;
|
||||
drive_rr_nodes = NULL;
|
||||
} else {
|
||||
|
@ -2072,7 +1874,7 @@ void dump_verilog_routing_switch_box_unique_side_module(t_sram_orgz_info* cur_sr
|
|||
}
|
||||
dump_verilog_unique_switch_box_interc(cur_sram_orgz_info, fp, rr_sb,
|
||||
side_manager.get_side(),
|
||||
rr_sb.get_chan_node(side_manager.get_side(), itrack));
|
||||
itrack);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2482,7 +2284,7 @@ void dump_verilog_routing_switch_box_unique_subckt(t_sram_orgz_info* cur_sram_or
|
|||
if (OUT_PORT == rr_gsb.get_chan_node_direction(side_manager.get_side(), itrack)) {
|
||||
dump_verilog_unique_switch_box_interc(cur_sram_orgz_info, fp, rr_sb,
|
||||
side_manager.get_side(),
|
||||
rr_gsb.get_chan_node(side_manager.get_side(), itrack));
|
||||
itrack);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3962,7 +3764,6 @@ void dump_verilog_routing_resources(t_sram_orgz_info* cur_sram_orgz_info,
|
|||
int LL_num_rr_nodes, t_rr_node* LL_rr_node,
|
||||
t_ivec*** LL_rr_node_indices,
|
||||
t_rr_indexed_data* LL_rr_indexed_data,
|
||||
t_syn_verilog_opts fpga_verilog_opts,
|
||||
boolean compact_routing_hierarchy) {
|
||||
assert(UNI_DIRECTIONAL == routing_arch->directionality);
|
||||
|
||||
|
|
|
@ -132,7 +132,6 @@ void dump_verilog_routing_resources(t_sram_orgz_info* cur_sram_orgz_info,
|
|||
int LL_num_rr_nodes, t_rr_node* LL_rr_node,
|
||||
t_ivec*** LL_rr_node_indices,
|
||||
t_rr_indexed_data* LL_rr_indexed_data,
|
||||
t_syn_verilog_opts fpga_verilog_opts,
|
||||
boolean compact_routing_hierarchy);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -370,7 +370,7 @@ void verilog_generate_sdc_break_loop_sb(FILE* fp,
|
|||
||(CHANY == chan_rr_node->type));
|
||||
/* We only care the output port and it should indicate a SB mux */
|
||||
if ( (OUT_PORT != rr_gsb.get_chan_node_direction(side_manager.get_side(), itrack))
|
||||
|| (false != rr_gsb.is_sb_node_imply_short_connection(chan_rr_node))) {
|
||||
|| (false != rr_gsb.is_sb_node_passing_wire(side_manager.get_side(), itrack))) {
|
||||
continue;
|
||||
}
|
||||
/* Bypass if we have only 1 driving node */
|
||||
|
@ -741,7 +741,7 @@ void verilog_generate_sdc_constrain_sbs(t_sdc_opts sdc_opts,
|
|||
continue;
|
||||
}
|
||||
/* Constrain thru wires */
|
||||
if (false != rr_gsb.is_sb_node_imply_short_connection(chan_rr_node)) {
|
||||
if (false != rr_gsb.is_sb_node_passing_wire(side_manager.get_side(), itrack)) {
|
||||
/* Set the max, min delay to 0? */
|
||||
verilog_generate_sdc_constrain_one_sb_path(fp, rr_gsb,
|
||||
chan_rr_node,
|
||||
|
@ -2510,7 +2510,7 @@ void verilog_generate_wire_report_timing_blockage_direction(FILE* fp,
|
|||
int LL_nx, int LL_ny) {
|
||||
|
||||
int ix, iy;
|
||||
int side, itrack, inode;
|
||||
int side, itrack;
|
||||
t_sb* cur_sb_info = NULL;
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue