#include #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; }