start adapting tileable rr_graph builder. Bring channel node detail data structure online
This commit is contained in:
parent
7fcd27e000
commit
524798799c
|
@ -0,0 +1,292 @@
|
|||
/************************************************************************
|
||||
* This file contains member functions for class ChanNodeDetails
|
||||
***********************************************************************/
|
||||
#include <cassert>
|
||||
#include <algorithm>
|
||||
#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_ids_.push_back(src.get_track_segment_id(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(const size_t& track_id) const {
|
||||
assert(validate_track_id(track_id));
|
||||
return track_node_ids_[track_id];
|
||||
}
|
||||
|
||||
/* Return a copy of vector */
|
||||
std::vector<size_t> ChanNodeDetails::get_track_node_ids() const {
|
||||
std::vector<size_t> copy;
|
||||
for (size_t inode = 0; inode < get_chan_width(); ++inode) {
|
||||
copy.push_back(track_node_ids_[inode]);
|
||||
}
|
||||
return copy;
|
||||
}
|
||||
|
||||
e_direction ChanNodeDetails::get_track_direction(const size_t& track_id) const {
|
||||
assert(validate_track_id(track_id));
|
||||
return track_direction_[track_id];
|
||||
}
|
||||
|
||||
size_t ChanNodeDetails::get_track_segment_length(const size_t& track_id) const {
|
||||
assert(validate_track_id(track_id));
|
||||
return seg_length_[track_id];
|
||||
}
|
||||
|
||||
size_t ChanNodeDetails::get_track_segment_id(const size_t& track_id) const {
|
||||
assert(validate_track_id(track_id));
|
||||
return seg_ids_[track_id];
|
||||
}
|
||||
|
||||
bool ChanNodeDetails::is_track_start(const size_t& track_id) const {
|
||||
assert(validate_track_id(track_id));
|
||||
return track_start_[track_id];
|
||||
}
|
||||
|
||||
bool ChanNodeDetails::is_track_end(const 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<size_t> ChanNodeDetails::get_seg_group(const size_t& track_id) const {
|
||||
assert(validate_chan_width());
|
||||
assert(validate_track_id(track_id));
|
||||
assert(is_track_start(track_id));
|
||||
|
||||
std::vector<size_t> group;
|
||||
/* Make sure a clean start */
|
||||
group.clear();
|
||||
|
||||
for (size_t itrack = track_id; itrack < get_chan_width(); ++itrack) {
|
||||
if ( (get_track_direction(itrack) != get_track_direction(track_id) )
|
||||
|| (get_track_segment_id(itrack) != get_track_segment_id(track_id)) ) {
|
||||
/* Bypass any nodes in different direction and segment information*/
|
||||
continue;
|
||||
}
|
||||
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<size_t> ChanNodeDetails::get_seg_group_node_id(const std::vector<size_t>& seg_group) const {
|
||||
std::vector<size_t> 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 e_direction& track_direction) const {
|
||||
size_t counter = 0;
|
||||
for (size_t itrack = 0; itrack < get_chan_width(); ++itrack) {
|
||||
/* Bypass unmatched track_direction */
|
||||
if (track_direction != get_track_direction(itrack)) {
|
||||
continue;
|
||||
}
|
||||
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 e_direction& track_direction) const {
|
||||
size_t counter = 0;
|
||||
for (size_t itrack = 0; itrack < get_chan_width(); ++itrack) {
|
||||
/* Bypass unmatched track_direction */
|
||||
if (track_direction != get_track_direction(itrack)) {
|
||||
continue;
|
||||
}
|
||||
if (false == is_track_end(itrack)) {
|
||||
continue;
|
||||
}
|
||||
counter++;
|
||||
}
|
||||
return counter;
|
||||
}
|
||||
|
||||
|
||||
/************************************************************************
|
||||
* Mutators
|
||||
***********************************************************************/
|
||||
/* Reserve the capacitcy of vectors */
|
||||
void ChanNodeDetails::reserve(const size_t& chan_width) {
|
||||
track_node_ids_.reserve(chan_width);
|
||||
track_direction_.reserve(chan_width);
|
||||
seg_length_.reserve(chan_width);
|
||||
seg_ids_.reserve(chan_width);
|
||||
track_start_.reserve(chan_width);
|
||||
track_end_.reserve(chan_width);
|
||||
}
|
||||
|
||||
/* Add a track to the channel */
|
||||
void ChanNodeDetails::add_track(const size_t& track_node_id, const e_direction& track_direction,
|
||||
const size_t& seg_id, const size_t& seg_length,
|
||||
const size_t& is_start, const size_t& is_end) {
|
||||
track_node_ids_.push_back(track_node_id);
|
||||
track_direction_.push_back(track_direction);
|
||||
seg_ids_.push_back(seg_id);
|
||||
seg_length_.push_back(seg_length);
|
||||
track_start_.push_back(is_start);
|
||||
track_end_.push_back(is_end);
|
||||
}
|
||||
|
||||
/* Update the node_id of a given track */
|
||||
void ChanNodeDetails::set_track_node_id(const size_t& track_index, const size_t& track_node_id) {
|
||||
assert(validate_track_id(track_index));
|
||||
track_node_ids_[track_index] = track_node_id;
|
||||
}
|
||||
|
||||
/* Update the node_ids from a vector */
|
||||
void ChanNodeDetails::set_track_node_ids(const std::vector<size_t>& track_node_ids) {
|
||||
/* the size of vector should match chan_width */
|
||||
assert ( get_chan_width() == track_node_ids.size() );
|
||||
for (size_t inode = 0; inode < track_node_ids.size(); ++inode) {
|
||||
track_node_ids_[inode] = track_node_ids[inode];
|
||||
}
|
||||
}
|
||||
|
||||
/* Set tracks with a given direction to start */
|
||||
void ChanNodeDetails::set_tracks_start(const 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)) {
|
||||
continue; /* Pass condition*/
|
||||
}
|
||||
track_start_[inode] = true;
|
||||
}
|
||||
}
|
||||
|
||||
/* Set tracks with a given direction to end */
|
||||
void ChanNodeDetails::set_tracks_end(const 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)) {
|
||||
continue; /* Pass condition*/
|
||||
}
|
||||
track_end_[inode] = true;
|
||||
}
|
||||
}
|
||||
|
||||
/* rotate the track_node_id by an offset */
|
||||
void ChanNodeDetails::rotate_track_node_id(const size_t& offset, const e_direction& track_direction, const bool& counter_rotate) {
|
||||
/* Direct return if offset = 0*/
|
||||
if (0 == offset) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* 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;
|
||||
}
|
||||
/* Bypass segments do not match track_direction */
|
||||
if (track_direction != get_track_direction(itrack) ) {
|
||||
continue;
|
||||
}
|
||||
/* Find the group nodes */
|
||||
std::vector<size_t> track_group = get_seg_group(itrack);
|
||||
/* Build a vector of the node ids of the tracks */
|
||||
std::vector<size_t> track_group_node_id = get_seg_group_node_id(track_group);
|
||||
/* adapt offset to the range of track_group_node_id */
|
||||
size_t actual_offset = offset % track_group_node_id.size();
|
||||
/* Rotate or Counter rotate */
|
||||
if (true == counter_rotate) {
|
||||
std::rotate(track_group_node_id.rbegin(), track_group_node_id.rbegin() + actual_offset, track_group_node_id.rend());
|
||||
} else {
|
||||
std::rotate(track_group_node_id.begin(), track_group_node_id.begin() + actual_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_ids_.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_ids_.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(const size_t& track_id) const {
|
||||
if ( (track_id < track_node_ids_.size())
|
||||
&& (track_id < track_direction_.size())
|
||||
&& (track_id < seg_ids_.size())
|
||||
&& (track_id < seg_length_.size())
|
||||
&& (track_id < track_start_.size())
|
||||
&& (track_id < track_end_.size()) ) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
@ -0,0 +1,80 @@
|
|||
/************************************************************************
|
||||
* 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 <vector>
|
||||
#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(const size_t& track_id) const;
|
||||
std::vector<size_t> get_track_node_ids() const;
|
||||
e_direction get_track_direction(const size_t& track_id) const;
|
||||
size_t get_track_segment_length(const size_t& track_id) const;
|
||||
size_t get_track_segment_id(const size_t& track_id) const;
|
||||
bool is_track_start(const size_t& track_id) const;
|
||||
bool is_track_end(const size_t& track_id) const;
|
||||
std::vector<size_t> get_seg_group(const size_t& track_id) const;
|
||||
std::vector<size_t> get_seg_group_node_id(const std::vector<size_t>& seg_group) const;
|
||||
size_t get_num_starting_tracks(const e_direction& track_direction) const;
|
||||
size_t get_num_ending_tracks(const e_direction& track_direction) const;
|
||||
public: /* Mutators */
|
||||
void reserve(const size_t& chan_width); /* Reserve the capacitcy of vectors */
|
||||
void add_track(const size_t& track_node_id, const e_direction& track_direction,
|
||||
const size_t& seg_id, const size_t& seg_length,
|
||||
const size_t& is_start, const size_t& is_end);
|
||||
void set_track_node_id(const size_t& track_index, const size_t& track_node_id);
|
||||
void set_track_node_ids(const std::vector<size_t>& track_node_ids);
|
||||
void set_tracks_start(const e_direction& track_direction);
|
||||
void set_tracks_end(const e_direction& track_direction);
|
||||
void rotate_track_node_id(const size_t& offset,
|
||||
const e_direction& track_direction,
|
||||
const bool& counter_rotate); /* rotate the track_node_id by an offset */
|
||||
void clear();
|
||||
private: /* validators */
|
||||
bool validate_chan_width() const;
|
||||
bool validate_track_id(const size_t& track_id) const;
|
||||
private: /* Internal data */
|
||||
std::vector<size_t> track_node_ids_; /* indices of each track */
|
||||
std::vector<e_direction> track_direction_; /* direction of each track */
|
||||
std::vector<size_t> seg_ids_; /* id of segment of each track */
|
||||
std::vector<size_t> seg_length_; /* Length of each segment */
|
||||
std::vector<bool> track_start_; /* flag to identify if this is the starting point of the track */
|
||||
std::vector<bool> track_end_; /* flag to identify if this is the ending point of the track */
|
||||
};
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue