271 lines
7.0 KiB
C++
271 lines
7.0 KiB
C++
|
#include <cassert>
|
||
|
|
||
|
#include "rr_chan.h"
|
||
|
|
||
|
|
||
|
/* Member Functions of Class RRChan */
|
||
|
/* accessors */
|
||
|
t_rr_type RRChan::get_type() const {
|
||
|
return type_;
|
||
|
}
|
||
|
|
||
|
/* get the number of tracks in this channel */
|
||
|
size_t RRChan::get_chan_width() const {
|
||
|
return nodes_.size();
|
||
|
}
|
||
|
|
||
|
/* get the track_id of a node */
|
||
|
int RRChan::get_node_track_id(t_rr_node* node) const {
|
||
|
/* if the given node is NULL, we return an invalid id */
|
||
|
if (NULL == node) {
|
||
|
return -1; /* FIXME: use a strong id!!! */
|
||
|
}
|
||
|
/* check each member and return if we find a match in content */
|
||
|
for (size_t inode = 0; inode < nodes_.size(); ++inode) {
|
||
|
if (node == nodes_[inode]) {
|
||
|
return inode;
|
||
|
}
|
||
|
}
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
/* get the rr_node with the track_id */
|
||
|
t_rr_node* RRChan::get_node(size_t track_num) const {
|
||
|
if ( false == valid_node_id(track_num) ) {
|
||
|
return NULL;
|
||
|
}
|
||
|
return nodes_[track_num];
|
||
|
}
|
||
|
|
||
|
/* get the segment id of a node */
|
||
|
int RRChan::get_node_segment(t_rr_node* node) const {
|
||
|
int node_id = get_node_track_id(node);
|
||
|
if ( false == valid_node_id(node_id)) {
|
||
|
return -1;
|
||
|
}
|
||
|
return get_node_segment(node_id);
|
||
|
}
|
||
|
|
||
|
/* get the segment id of a node */
|
||
|
int RRChan::get_node_segment(size_t track_num) const {
|
||
|
if ( false == valid_node_id(track_num)) {
|
||
|
return -1;
|
||
|
}
|
||
|
return node_segments_[track_num];
|
||
|
}
|
||
|
|
||
|
/* evaluate if two RRChan is mirror to each other */
|
||
|
bool RRChan::is_mirror(RRChan& cand) const {
|
||
|
/* If any following element does not match, it is not mirror */
|
||
|
/* 1. type */
|
||
|
if (this->get_type() != cand.get_type()) {
|
||
|
return false;
|
||
|
}
|
||
|
/* 2. track_width */
|
||
|
if (this->get_chan_width() != cand.get_chan_width()) {
|
||
|
return false;
|
||
|
}
|
||
|
/* 3. for each node */
|
||
|
for (size_t inode = 0; inode < this->get_chan_width(); ++inode) {
|
||
|
/* 3.1 check node type */
|
||
|
if (this->get_node(inode)->type != cand.get_node(inode)->type) {
|
||
|
return false;
|
||
|
}
|
||
|
/* 3.2 check node directionality */
|
||
|
if (this->get_node(inode)->direction != cand.get_node(inode)->direction) {
|
||
|
return false;
|
||
|
}
|
||
|
/* 3.3 check node segment */
|
||
|
if (this->get_node_segment(inode) != cand.get_node_segment(inode)) {
|
||
|
return false;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
/* Mutators */
|
||
|
/* modify type */
|
||
|
void RRChan::set_type(t_rr_type type) {
|
||
|
assert(valid_type(type));
|
||
|
type_ = type;
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
/* add a node to the array */
|
||
|
void RRChan::add_node(t_rr_node* node, size_t node_segment) {
|
||
|
/* resize the array if needed, node is placed in the sequence of node->ptc_num */
|
||
|
if (size_t(node->ptc_num) > (nodes_.size() + 1)) {
|
||
|
nodes_.resize(node->ptc_num + 1); /* resize to the maximum */
|
||
|
node_segments_.resize(node->ptc_num + 1); /* resize to the maximum */
|
||
|
}
|
||
|
/* fill the dedicated element in the vector */
|
||
|
nodes_[node->ptc_num] = node;
|
||
|
node_segments_[node->ptc_num] = node_segment;
|
||
|
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
/* Clear content */
|
||
|
void RRChan::clear() {
|
||
|
nodes_.clear();
|
||
|
node_segments_.clear();
|
||
|
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
/* Internal functions */
|
||
|
|
||
|
/* for type, only valid type is CHANX and CHANY */
|
||
|
bool RRChan::valid_type(t_rr_type type) const {
|
||
|
if ((CHANX == type) && (CHANY == type)) {
|
||
|
return true;
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
/* check if the node id is valid */
|
||
|
bool RRChan::valid_node_id(size_t node_id) const {
|
||
|
if ( (size_t(-1) < node_id) && (node_id < nodes_.size()) ) {
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
/* Member Functions of Class DeviceRRChan */
|
||
|
/* accessors */
|
||
|
RRChan DeviceRRChan::get_module(t_rr_type chan_type, size_t module_id) const {
|
||
|
assert(valid_module_id(chan_type, module_id));
|
||
|
|
||
|
if (CHANX == chan_type) {
|
||
|
return chanx_modules_[module_id];
|
||
|
} else if (CHANY == chan_type) {
|
||
|
return chany_modules_[module_id];
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void DeviceRRChan::init_module_ids(size_t device_width, size_t device_height) {
|
||
|
init_chan_module_ids(CHANX, device_width, device_height);
|
||
|
init_chan_module_ids(CHANY, device_width, device_height);
|
||
|
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
void DeviceRRChan::init_chan_module_ids(t_rr_type chan_type, size_t device_width, size_t device_height) {
|
||
|
assert(valid_chan_type(chan_type));
|
||
|
|
||
|
if (CHANX == chan_type) {
|
||
|
chanx_module_ids_.resize(device_width);
|
||
|
for (size_t x = 0; x < chanx_module_ids_.size(); ++x) {
|
||
|
chanx_module_ids_[x].resize(device_height);
|
||
|
}
|
||
|
} else if (CHANY == chan_type) {
|
||
|
chany_module_ids_.resize(device_width);
|
||
|
for (size_t x = 0; x < chany_module_ids_.size(); ++x) {
|
||
|
chany_module_ids_[x].resize(device_height);
|
||
|
}
|
||
|
}
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
void DeviceRRChan::add_one_chan_module(t_rr_type chan_type, size_t x, size_t y, RRChan rr_chan) {
|
||
|
assert(valid_coordinator(chan_type, x, y));
|
||
|
|
||
|
if (CHANX == chan_type) {
|
||
|
/* Find if the module is unique */
|
||
|
for (size_t i = 0; i < chanx_modules_.size(); ++i) {
|
||
|
if ( true == chanx_modules_[i].is_mirror(rr_chan)) {
|
||
|
/* Find a mirror in the list, assign ids and return */
|
||
|
chanx_module_ids_[x][y] = i;
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
/* Reach here, it means this is a unique module */
|
||
|
/* add to the module list */
|
||
|
chanx_modules_.push_back(rr_chan);
|
||
|
chanx_module_ids_[x][y] = chanx_modules_.size() - 1;
|
||
|
} else if (CHANY == chan_type) {
|
||
|
/* Find if the module is unique */
|
||
|
for (size_t i = 0; i < chany_modules_.size(); ++i) {
|
||
|
if ( true == chany_modules_[i].is_mirror(rr_chan)) {
|
||
|
/* Find a mirror in the list, assign ids and return */
|
||
|
chany_module_ids_[x][y] = i;
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
/* Reach here, it means this is a unique module */
|
||
|
/* add to the module list */
|
||
|
chany_modules_.push_back(rr_chan);
|
||
|
chany_module_ids_[x][y] = chany_modules_.size() - 1;
|
||
|
}
|
||
|
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
void DeviceRRChan::clear() {
|
||
|
clear_chan(CHANX);
|
||
|
clear_chan(CHANY);
|
||
|
}
|
||
|
|
||
|
void DeviceRRChan::clear_chan(t_rr_type chan_type) {
|
||
|
assert(valid_chan_type(chan_type));
|
||
|
|
||
|
if (CHANX == chan_type) {
|
||
|
chanx_modules_.clear();
|
||
|
} else if (CHANY == chan_type) {
|
||
|
chany_modules_.clear();
|
||
|
}
|
||
|
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
/* for type, only valid type is CHANX and CHANY */
|
||
|
bool DeviceRRChan::valid_chan_type(t_rr_type chan_type) const {
|
||
|
if ((CHANX == chan_type) && (CHANY == chan_type)) {
|
||
|
return true;
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
/* check if the coordinator is in range */
|
||
|
bool DeviceRRChan::valid_coordinator(t_rr_type chan_type, size_t x, size_t y) const {
|
||
|
assert(valid_chan_type(chan_type));
|
||
|
|
||
|
if (CHANX == chan_type) {
|
||
|
if (!( (size_t(-1) < x) && (x < chanx_module_ids_.size()) )) {
|
||
|
return false;
|
||
|
}
|
||
|
if (!( (size_t(-1) < y) && (y < chanx_module_ids_[x].size()) )) {
|
||
|
return false;
|
||
|
}
|
||
|
} else if (CHANY == chan_type) {
|
||
|
if (!( (size_t(-1) < x) && (x < chany_module_ids_.size()) )) {
|
||
|
return false;
|
||
|
}
|
||
|
if (!( (size_t(-1) < y) && (y < chany_module_ids_[x].size()) )) {
|
||
|
return false;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
/* check if the node id is valid */
|
||
|
bool DeviceRRChan::valid_module_id(t_rr_type chan_type, size_t module_id) const {
|
||
|
assert(valid_chan_type(chan_type));
|
||
|
|
||
|
if (CHANX == chan_type) {
|
||
|
if ( (size_t(-1) < module_id) && (module_id < chanx_modules_.size()) ) {
|
||
|
return true;
|
||
|
}
|
||
|
} else if (CHANY == chan_type) {
|
||
|
if ( (size_t(-1) < module_id) && (module_id < chany_modules_.size()) ) {
|
||
|
return true;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return false;
|
||
|
}
|
||
|
|