From a33627606e16a3c97daa80bee6f08b6ea96a4776 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Fri, 14 Jun 2019 17:35:40 -0600 Subject: [PATCH] developing tileable routing track arrangement --- .../SRC/device/rr_graph/chan_node_details.cpp | 268 ++++++++++++++++++ .../SRC/device/rr_graph/chan_node_details.h | 105 +++++++ .../rr_graph/rr_graph_tileable_builder.c | 264 ++++++++++++++++- 3 files changed, 629 insertions(+), 8 deletions(-) create mode 100644 vpr7_x2p/vpr/SRC/device/rr_graph/chan_node_details.cpp create mode 100644 vpr7_x2p/vpr/SRC/device/rr_graph/chan_node_details.h diff --git a/vpr7_x2p/vpr/SRC/device/rr_graph/chan_node_details.cpp b/vpr7_x2p/vpr/SRC/device/rr_graph/chan_node_details.cpp new file mode 100644 index 000000000..2e8c80708 --- /dev/null +++ b/vpr7_x2p/vpr/SRC/device/rr_graph/chan_node_details.cpp @@ -0,0 +1,268 @@ +/********************************************************** + * 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: chan_node_details.cpp + * Created by: Xifan Tang + * Change history: + * +-------------------------------------+ + * | Date | Author | Notes + * +-------------------------------------+ + * | 2019/06/14 | Xifan Tang | Created + * +-------------------------------------+ + ***********************************************************************/ +/************************************************************************ + * This file contains member functions for class ChanNodeDetails + ***********************************************************************/ +#include +#include +#include "chan_node_details.h" + +/************************************************************************ + * Constructors + ***********************************************************************/ +ChanNodeDetails::ChanNodeDetails(const ChanNodeDetails& src) { + /* duplicate */ + size_t chan_width = src.get_chan_width(); + this->reserve(chan_width); + for (size_t itrack = 0; itrack < chan_width; ++itrack) { + track_node_ids_.push_back(src.get_track_node_id(itrack)); + track_direction_.push_back(src.get_track_direction(itrack)); + seg_length_.push_back(src.get_track_segment_length(itrack)); + track_start_.push_back(src.is_track_start(itrack)); + track_end_.push_back(src.is_track_end(itrack)); + } +} + +ChanNodeDetails::ChanNodeDetails() { + this->clear(); +} + +/************************************************************************ + * Accessors + ***********************************************************************/ +size_t ChanNodeDetails::get_chan_width() const { + assert(validate_chan_width()); + return track_node_ids_.size(); +} + +size_t ChanNodeDetails::get_track_node_id(size_t track_id) const { + assert(validate_track_id(track_id)); + return track_node_ids_[track_id]; +} + +e_direction ChanNodeDetails::get_track_direction(size_t track_id) const { + assert(validate_track_id(track_id)); + return track_direction_[track_id]; +} + +size_t ChanNodeDetails::get_track_segment_length(size_t track_id) const { + assert(validate_track_id(track_id)); + return seg_length_[track_id]; +} + +bool ChanNodeDetails::is_track_start(size_t track_id) const { + assert(validate_track_id(track_id)); + return track_start_[track_id]; +} + +bool ChanNodeDetails::is_track_end(size_t track_id) const { + assert(validate_track_id(track_id)); + return track_end_[track_id]; +} + +/* Track_id is the starting point of group (whose is_start should be true) + * This function will try to find the track_ids with the same directionality as track_id and seg_length + * A group size is the number of such nodes between the starting points (include the 1st starting point) + */ +std::vector ChanNodeDetails::get_seg_group(size_t track_id) const { + assert(validate_chan_width()); + assert(validate_track_id(track_id)); + assert(is_track_start(track_id)); + + std::vector group; + /* Make sure a clean start */ + group.clear(); + + /* track_id is the first element */ + group.push_back(track_id); + + for (size_t itrack = track_id; itrack < get_chan_width(); ++itrack) { + if ( (get_track_direction(itrack) == get_track_direction(track_id) ) + && (get_track_segment_length(itrack) == get_track_segment_length(track_id)) ) { + if ( (false == is_track_start(itrack)) + || ( (true == is_track_start(itrack)) && (itrack == track_id)) ) { + group.push_back(itrack); + continue; + } + /* Stop if this another starting point */ + if (true == is_track_start(itrack)) { + break; + } + } + } + return group; +} + +/* Get a list of track_ids with the given list of track indices */ +std::vector ChanNodeDetails::get_seg_group_node_id(std::vector seg_group) const { + std::vector group; + /* Make sure a clean start */ + group.clear(); + + for (size_t id = 0; id < seg_group.size(); ++id) { + assert(validate_track_id(seg_group[id])); + group.push_back(get_track_node_id(seg_group[id])); + } + + return group; +} + +/* Get the number of tracks that starts in this routing channel */ +size_t ChanNodeDetails::get_num_starting_tracks() const { + size_t counter = 0; + for (size_t itrack = 0; itrack < get_chan_width(); ++itrack) { + if (false == is_track_start(itrack)) { + continue; + } + counter++; + } + return counter; +} + +/* Get the number of tracks that ends in this routing channel */ +size_t ChanNodeDetails::get_num_ending_tracks() const { + size_t counter = 0; + for (size_t itrack = 0; itrack < get_chan_width(); ++itrack) { + if (false == is_track_end(itrack)) { + continue; + } + counter++; + } + return counter; +} + +/************************************************************************ + * Mutators + ***********************************************************************/ +/* Reserve the capacitcy of vectors */ +void ChanNodeDetails::reserve(size_t chan_width) { + track_node_ids_.reserve(chan_width); + track_direction_.reserve(chan_width); + seg_length_.reserve(chan_width); + track_start_.reserve(chan_width); + track_end_.reserve(chan_width); +} + +/* Add a track to the channel */ +void ChanNodeDetails::add_track(size_t track_node_id, e_direction track_direction, size_t seg_length, size_t is_start, size_t is_end) { + track_node_ids_.push_back(track_node_id); + track_direction_.push_back(track_direction); + seg_length_.push_back(seg_length); + track_start_.push_back(is_start); + track_end_.push_back(is_end); +} + +/* Set tracks with a given direction to start */ +void ChanNodeDetails::set_tracks_start(e_direction track_direction) { + for (size_t inode = 0; inode < get_chan_width(); ++inode) { + /* Bypass non-match tracks */ + if (track_direction != get_track_direction(inode)) { + } + track_start_[inode] = true; + } +} + +/* Set tracks with a given direction to end */ +void ChanNodeDetails::set_tracks_end(e_direction track_direction) { + for (size_t inode = 0; inode < get_chan_width(); ++inode) { + /* Bypass non-match tracks */ + if (track_direction != get_track_direction(inode)) { + } + track_end_[inode] = true; + } +} + +/* rotate the track_node_id by an offset */ +void ChanNodeDetails::rotate_track_node_id(size_t offset, bool counter_rotate) { + /* Rotate the node_ids by groups + * A group begins from a track_start and ends before another track_start + */ + assert(validate_chan_width()); + for (size_t itrack = 0; itrack < get_chan_width(); ++itrack) { + /* Bypass non-start segment */ + if (false == is_track_start(itrack) ) { + continue; + } + /* Find the group nodes */ + std::vector track_group = get_seg_group(itrack); + /* Build a vector of the node ids of the tracks */ + std::vector track_group_node_id = get_seg_group_node_id(track_group); + /* Rotate or Counter rotate */ + if (true == counter_rotate) { + std::rotate(track_group_node_id.begin(), track_group_node_id.end() - offset, track_group_node_id.end()); + } else { + std::rotate(track_group_node_id.begin(), track_group_node_id.begin() + offset, track_group_node_id.end()); + } + /* Update the node_ids */ + for (size_t inode = 0; inode < track_group.size(); ++inode) { + track_node_ids_[track_group[inode]] = track_group_node_id[inode]; + } + } + return; +} + +void ChanNodeDetails::clear() { + track_node_ids_.clear(); + track_direction_.clear(); + seg_length_.clear(); + track_start_.clear(); + track_end_.clear(); +} + +/************************************************************************ + * Validators + ***********************************************************************/ +bool ChanNodeDetails::validate_chan_width() const { + size_t chan_width = track_node_ids_.size(); + if ( (chan_width == track_direction_.size()) + &&(chan_width == seg_length_.size()) + &&(chan_width == track_start_.size()) + &&(chan_width == track_end_.size()) ) { + return true; + } + return false; +} + +bool ChanNodeDetails::validate_track_id(size_t track_id) const { + if ( (track_id < track_node_ids_.size()) + && (track_id < track_direction_.size()) + && (track_id < seg_length_.size()) + && (track_id < track_start_.size()) + && (track_id < track_end_.size()) ) { + return true; + } + return false; +} + diff --git a/vpr7_x2p/vpr/SRC/device/rr_graph/chan_node_details.h b/vpr7_x2p/vpr/SRC/device/rr_graph/chan_node_details.h new file mode 100644 index 000000000..8b45ba25f --- /dev/null +++ b/vpr7_x2p/vpr/SRC/device/rr_graph/chan_node_details.h @@ -0,0 +1,105 @@ +/********************************************************** + * 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: chan_node_details.h + * Created by: Xifan Tang + * Change history: + * +-------------------------------------+ + * | Date | Author | Notes + * +-------------------------------------+ + * | 2019/06/11 | Xifan Tang | Created + * +-------------------------------------+ + ***********************************************************************/ +/************************************************************************ + * This file contains a class to model the details of routing node + * in a channel: + * 1. segment information: length, frequency etc. + * 2. starting point of segment + * 3. ending point of segment + * 4. potentail track_id(ptc_num) of each segment + ***********************************************************************/ + +/* IMPORTANT: + * The following preprocessing flags are added to + * avoid compilation error when this headers are included in more than 1 times + */ +#ifndef CHAN_NODE_DETAILS_H +#define CHAN_NODE_DETAILS_H + +/* + * Notes in include header files in a head file + * Only include the neccessary header files + * that is required by the data types in the function/class declarations! + */ +/* Header files should be included in a sequence */ +/* Standard header files required go first */ +#include +#include "vpr_types.h" + +/************************************************************************ + * ChanNodeDetails records segment length, directionality and starting of routing tracks + * +---------------------------------+ + * | Index | Direction | Start Point | + * +---------------------------------+ + * | 0 | --------> | Yes | + * +---------------------------------+ + ***********************************************************************/ + + +class ChanNodeDetails { + public : /* Constructor */ + ChanNodeDetails(const ChanNodeDetails&); /* Duplication */ + ChanNodeDetails(); /* Initilization */ + public: /* Accessors */ + size_t get_chan_width() const; + size_t get_track_node_id(size_t track_id) const; + e_direction get_track_direction(size_t track_id) const; + size_t get_track_segment_length(size_t track_id) const; + bool is_track_start(size_t track_id) const; + bool is_track_end(size_t track_id) const; + std::vector get_seg_group(size_t track_id) const; + std::vector get_seg_group_node_id(std::vector seg_group) const; + size_t get_num_starting_tracks() const; + size_t get_num_ending_tracks() const; + public: /* Mutators */ + void reserve(size_t chan_width); /* Reserve the capacitcy of vectors */ + void add_track(size_t track_node_id, e_direction track_direction, size_t seg_length, size_t is_start, size_t is_end); + void set_tracks_start(e_direction track_direction); + void set_tracks_end(e_direction track_direction); + void rotate_track_node_id(size_t offset, bool counter_rotate); /* rotate the track_node_id by an offset */ + void clear(); + private: /* validators */ + bool validate_chan_width() const; + bool validate_track_id(size_t track_id) const; + private: /* Internal data */ + std::vector track_node_ids_; /* indices of each track */ + std::vector track_direction_; /* direction of each track */ + std::vector seg_length_; /* Length of each segment */ + std::vector track_start_; /* flag to identify if this is the starting point of the track */ + std::vector track_end_; /* flag to identify if this is the ending point of the track */ +}; + +#endif + diff --git a/vpr7_x2p/vpr/SRC/device/rr_graph/rr_graph_tileable_builder.c b/vpr7_x2p/vpr/SRC/device/rr_graph/rr_graph_tileable_builder.c index 647e8d1f9..32438ad89 100644 --- a/vpr7_x2p/vpr/SRC/device/rr_graph/rr_graph_tileable_builder.c +++ b/vpr7_x2p/vpr/SRC/device/rr_graph/rr_graph_tileable_builder.c @@ -55,11 +55,213 @@ #include "fpga_x2p_types.h" #include "rr_graph_tileable_builder.h" +#include "chan_node_details.h" /************************************************************************ * Local function in the file ***********************************************************************/ +/************************************************************************ + * Generate the number of tracks for each types of routing segments + * w.r.t. the frequency of each of segments and channel width + * Note that if we dertermine the number of tracks per type using + * chan_width * segment_frequency / total_freq may cause + * The total track num may not match the chan_width, + * therefore, we assign tracks one by one until we meet the frequency requirement + * In this way, we can assign the number of tracks with repect to frequency + ***********************************************************************/ +static +std::vector get_num_tracks_per_seg_type(size_t chan_width, + std::vector segment_inf, + bool use_full_seg_groups) { + std::vector result; + std::vector demand; + /* Make sure a clean start */ + result.resize(segment_inf.size()); + demand.resize(segment_inf.size()); + + /* Scale factor so we can divide by any length + * and still use integers */ + /* Get the sum of frequency */ + size_t scale = 1; + size_t freq_sum = 0; + for (size_t iseg = 0; iseg < segment_inf.size(); ++iseg) { + scale *= segment_inf[iseg].length; + freq_sum += segment_inf[iseg].frequency; + } + size_t reduce = scale * freq_sum; + + /* Init assignments to 0 and set the demand values */ + /* Get the fraction of each segment type considering the frequency: + * num_track_per_seg = chan_width * (freq_of_seg / sum_freq) + */ + for (size_t iseg = 0; iseg < segment_inf.size(); ++iseg) { + result[iseg] = 0; + demand[iseg] = scale * chan_width * segment_inf[iseg].frequency; + if (true == use_full_seg_groups) { + demand[iseg] /= segment_inf[iseg].length; + } + } + + /* check if the sum of num_tracks, matches the chan_width */ + /* Keep assigning tracks until we use them up */ + size_t assigned = 0; + size_t size = 0; + size_t imax = 0; + while (assigned < chan_width) { + /* Find current maximum demand */ + double max = 0; + for (size_t iseg = 0; iseg < segment_inf.size(); ++iseg) { + if (demand[iseg] > max) { + imax = iseg; + } + max = std::max(demand[iseg], max); + } + + /* Assign tracks to the type and reduce the types demand */ + size = (use_full_seg_groups ? segment_inf[imax].length : 1); + demand[imax] -= reduce; + result[imax] += size; + assigned += size; + } + + /* Undo last assignment if we were closer to goal without it */ + if ((assigned - chan_width) > (size / 2)) { + result[imax] -= size; + } + + return result; +} + +/************************************************************************ + * Build details of routing tracks in a channel + * The function will + * 1. Assign the segments for each routing channel, + * To be specific, for each routing track, we assign a routing segment. + * The assignment is subject to users' specifications, such as + * a. length of each type of segment + * b. frequency of each type of segment. + * c. routing channel width + * + * 2. The starting point of each segment in the channel will be assigned + * For each segment group with same directionality (tracks have the same length), + * every L track will be a starting point (where L denotes the length of segments) + * In this case, if the number of tracks is not a multiple of L, + * indeed we may have some | Yes | + * +---------------------------------+ + * | 1 | <-------- | Yes | + * +---------------------------------+ + * | 2 | --------> | No | + * +---------------------------------+ + * | 3 | <-------- | No | + * +---------------------------------+ + * | 4 | --------> | No | + * +---------------------------------+ + * | 5 | <-------- | No | + * +---------------------------------+ + * | 7 | --------> | No | + * +---------------------------------+ + * | 8 | <-------- | No | + * +---------------------------------+ + * | 9 | --------> | Yes | + * +---------------------------------+ + * | 10 | <-------- | Yes | + * +---------------------------------+ + * | 11 | --------> | No | + * +---------------------------------+ + * | 12 | <-------- | No | + * +---------------------------------+ + * + * 3. SPECIAL for fringes: TOP|RIGHT|BOTTOM|RIGHT + * if device_side is NUM_SIDES, we assume this channel does not locate on borders + * All segments will start and ends with no exception + * + * 4. IMPORTANT: we should be aware that channel width maybe different + * in X-direction and Y-direction channels!!! + * So we will load segment details for different channels + ***********************************************************************/ +static +ChanNodeDetails build_unidir_chan_node_details(size_t chan_width, size_t max_seg_length, + enum e_side device_side, + std::vector segment_inf) { + ChanNodeDetails chan_node_details; + /* Correct the chan_width: it should be an even number */ + if (0 != chan_width % 2) { + chan_width++; /* increment it to be even */ + } + assert (0 == chan_width % 2); + + /* Reserve channel width */ + chan_node_details.reserve(chan_width); + /* Return if zero width is forced */ + if (0 == chan_width) { + return chan_node_details; + } + + /* Find the number of segments required by each group */ + std::vector num_tracks = get_num_tracks_per_seg_type(chan_width/2, segment_inf, TRUE); + + /* Add node to ChanNodeDetails */ + size_t cur_track = 0; + for (size_t iseg = 0; iseg < segment_inf.size(); ++iseg) { + /* segment length will be set to maxium segment length if this is a longwire */ + size_t seg_len = segment_inf[iseg].length; + if (TRUE == segment_inf[iseg].longline) { + seg_len = max_seg_length; + } + for (size_t itrack = 0; itrack < num_tracks[iseg]; ++itrack) { + bool seg_start = false; + /* Every length of wire, we set a starting point */ + if (0 == itrack % seg_len) { + seg_start = true; + } + /* Since this is a unidirectional routing architecture, + * Add a pair of tracks, 1 INC_DIRECTION track and 1 DEC_DIRECTION track + */ + chan_node_details.add_track(cur_track, INC_DIRECTION, seg_len, seg_start, false); + cur_track++; + chan_node_details.add_track(cur_track, DEC_DIRECTION, seg_len, seg_start, false); + cur_track++; + } + } + /* Check if all the tracks have been satisified */ + assert (cur_track == chan_width); + + /* If this is on the border of a device, segments should start */ + switch (device_side) { + case TOP: + case RIGHT: + /* INC_DIRECTION should all end */ + chan_node_details.set_tracks_end(INC_DIRECTION); + /* DEC_DIRECTION should all start */ + chan_node_details.set_tracks_start(DEC_DIRECTION); + break; + case BOTTOM: + case LEFT: + /* INC_DIRECTION should all start */ + chan_node_details.set_tracks_start(INC_DIRECTION); + /* DEC_DIRECTION should all end */ + chan_node_details.set_tracks_end(DEC_DIRECTION); + break; + case NUM_SIDES: + break; + default: + vpr_printf(TIO_MESSAGE_ERROR, + "(File:%s, [LINE%d]) Invalid device_side!\n", + __FILE__, __LINE__); + exit(1); + } + + return chan_node_details; +} + /************************************************************************ * Estimate the number of rr_nodes per category: * CHANX, CHANY, IPIN, OPIN, SOURCE, SINK @@ -122,9 +324,9 @@ t_rr_graph build_tileable_unidir_rr_graph(INP int L_num_types, INP t_timing_inf timing_inf, INP int wire_to_ipin_switch, INP enum e_base_cost_type base_cost_type, INP t_direct_inf *directs, INP int num_directs, INP boolean ignore_Fc_0, OUTP int *Warnings, - /*Xifan TANG: Switch Segment Pattern Support*/ - INP int num_swseg_pattern, INP t_swseg_pattern_inf* swseg_patterns, - INP boolean opin_to_cb_fast_edges, INP boolean opin_logic_eq_edges) { + /*Xifan TANG: Switch Segment Pattern Support*/ + INP int num_swseg_pattern, INP t_swseg_pattern_inf* swseg_patterns, + INP boolean opin_to_cb_fast_edges, INP boolean opin_logic_eq_edges) { /* Create an empty graph */ t_rr_graph rr_graph; rr_graph.rr_node_indices = NULL; @@ -141,6 +343,46 @@ t_rr_graph build_tileable_unidir_rr_graph(INP int L_num_types, * a. length of each type of segment * b. frequency of each type of segment. * c. routing channel width + * + * The starting point of each segment in the channel will be assigned + * For each segment group with same directionality (tracks have the same length), + * every L track will be a starting point (where L denotes the length of segments) + * In this case, if the number of tracks is not a multiple of L, + * indeed we may have some | Yes | + * +---------------------------------+ + * | 1 | <-------- | Yes | + * +---------------------------------+ + * | 2 | --------> | No | + * +---------------------------------+ + * | 3 | <-------- | No | + * +---------------------------------+ + * | 4 | --------> | No | + * +---------------------------------+ + * | 5 | <-------- | No | + * +---------------------------------+ + * | 7 | --------> | No | + * +---------------------------------+ + * | 8 | <-------- | No | + * +---------------------------------+ + * | 9 | --------> | Yes | + * +---------------------------------+ + * | 10 | <-------- | Yes | + * +---------------------------------+ + * | 11 | --------> | No | + * +---------------------------------+ + * | 12 | <-------- | No | + * +---------------------------------+ + * + * SPECIAL for fringes: + * All segments will start and ends with no exception + * * IMPORTANT: we should be aware that channel width maybe different * in X-direction and Y-direction channels!!! * So we will load segment details for different channels @@ -148,11 +390,15 @@ t_rr_graph build_tileable_unidir_rr_graph(INP int L_num_types, /* Check the channel width */ int nodes_per_chan = chan_width; assert(chan_width > 0); - t_seg_details *seg_details = NULL; - seg_details = alloc_and_load_seg_details(&nodes_per_chan, - std::max(L_nx, L_ny), - num_seg_types, segment_inf, - TRUE, FALSE, UNI_DIRECTIONAL); + + /* Create a vector of segment_inf */ + std::vector segment_infs; + for (int iseg = 0; iseg < num_seg_types; ++iseg) { + segment_infs.push_back(segment_inf[iseg]); + } + + ChanNodeDetails chanx_details = build_unidir_chan_node_details(nodes_per_chan, L_nx, NUM_SIDES, segment_infs); + ChanNodeDetails chany_details = build_unidir_chan_node_details(nodes_per_chan, L_ny, NUM_SIDES, segment_infs); /* Predict the track index of each channel, * The track index, also called ptc_num of each CHANX and CHANY rr_node @@ -204,6 +450,7 @@ t_rr_graph build_tileable_unidir_rr_graph(INP int L_num_types, * c. handle direct-connections ***********************************************************************/ /* Alloc node lookups, count nodes, alloc rr nodes */ + /* rr_graph.num_rr_nodes = 0; rr_graph.rr_node_indices = alloc_and_load_rr_node_indices(nodes_per_chan, L_nx, L_ny, &(rr_graph.num_rr_nodes), seg_details); @@ -211,6 +458,7 @@ t_rr_graph build_tileable_unidir_rr_graph(INP int L_num_types, memset(rr_node, 0, sizeof(t_rr_node) * rr_graph.num_rr_nodes); boolean* L_rr_edge_done = (boolean *) my_malloc(sizeof(boolean) * rr_graph.num_rr_nodes); memset(L_rr_edge_done, 0, sizeof(boolean) * rr_graph.num_rr_nodes); + */ /* handle direct-connections */ t_clb_to_clb_directs* clb_to_clb_directs = NULL;