support rotation on segment groups inside RRChan and improve rotatable mirror searching
This commit is contained in:
parent
e0717369e1
commit
6f30d3ad05
|
@ -1,3 +1,6 @@
|
||||||
|
#ifndef FPGA_X2P_PBTYPES_UTILS_H
|
||||||
|
#define FPGA_X2P_PBTYPES_UTILS_H
|
||||||
|
|
||||||
void check_pb_graph_edge(t_pb_graph_edge pb_graph_edge);
|
void check_pb_graph_edge(t_pb_graph_edge pb_graph_edge);
|
||||||
|
|
||||||
void check_pb_graph_pin_edges(t_pb_graph_pin pb_graph_pin);
|
void check_pb_graph_pin_edges(t_pb_graph_pin pb_graph_pin);
|
||||||
|
@ -236,3 +239,5 @@ boolean is_pb_used_for_wiring(t_pb_graph_node* cur_pb_graph_node,
|
||||||
t_rr_node* pb_rr_graph);
|
t_rr_node* pb_rr_graph);
|
||||||
|
|
||||||
char* get_pb_graph_full_name_in_hierarchy(t_pb_graph_node* cur_pb_graph_node);
|
char* get_pb_graph_full_name_in_hierarchy(t_pb_graph_node* cur_pb_graph_node);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -1150,16 +1150,16 @@ RRSwitchBlock rotate_rr_switch_block_for_mirror(DeviceCoordinator& device_range,
|
||||||
|
|
||||||
/* For BOTTOM SIDE: Y-channel in DEC_DIRECTION, rotate by an offset of its y-coordinator */
|
/* For BOTTOM SIDE: Y-channel in DEC_DIRECTION, rotate by an offset of its y-coordinator */
|
||||||
if (device_range.get_y() - 1 > rotated_rr_switch_block.get_y()) {
|
if (device_range.get_y() - 1 > rotated_rr_switch_block.get_y()) {
|
||||||
rotated_rr_switch_block.counter_rotate_side_chan_node_by_direction(BOTTOM, DEC_DIRECTION, device_range.get_y() - 1 - rotated_rr_switch_block.get_y());
|
rotated_rr_switch_block.counter_rotate_side_chan_node_by_direction(BOTTOM, DEC_DIRECTION, rotated_rr_switch_block.get_y() - 1);
|
||||||
/* Rotate the same nodes on the opposite side */
|
/* Rotate the same nodes on the opposite side */
|
||||||
rotated_rr_switch_block.counter_rotate_side_chan_node_by_direction(TOP, DEC_DIRECTION, device_range.get_y() - 1 - rotated_rr_switch_block.get_y());
|
rotated_rr_switch_block.counter_rotate_side_chan_node_by_direction(TOP, DEC_DIRECTION, rotated_rr_switch_block.get_y() - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* For LEFT SIDE: X-channel in DEC_DIRECTION, rotate by an offset of its x-coordinator */
|
/* For LEFT SIDE: X-channel in DEC_DIRECTION, rotate by an offset of its x-coordinator */
|
||||||
if (device_range.get_x() - 1 > rotated_rr_switch_block.get_x()) {
|
if (device_range.get_x() - 1 > rotated_rr_switch_block.get_x()) {
|
||||||
rotated_rr_switch_block.counter_rotate_side_chan_node_by_direction(LEFT, DEC_DIRECTION, device_range.get_x() - 1 - rotated_rr_switch_block.get_x());
|
rotated_rr_switch_block.counter_rotate_side_chan_node_by_direction(LEFT, DEC_DIRECTION, rotated_rr_switch_block.get_x() - 1);
|
||||||
/* Rotate the same nodes on the opposite side */
|
/* Rotate the same nodes on the opposite side */
|
||||||
rotated_rr_switch_block.counter_rotate_side_chan_node_by_direction(RIGHT, DEC_DIRECTION, device_range.get_x() - 1 - rotated_rr_switch_block.get_x());
|
rotated_rr_switch_block.counter_rotate_side_chan_node_by_direction(RIGHT, DEC_DIRECTION, rotated_rr_switch_block.get_x() - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
return rotated_rr_switch_block;
|
return rotated_rr_switch_block;
|
||||||
|
|
|
@ -101,6 +101,26 @@ bool RRChan::is_mirror(RRChan& cand) const {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Get a list of segments used in this routing channel */
|
||||||
|
std::vector<size_t> RRChan::get_segment_ids() const {
|
||||||
|
std::vector<size_t> seg_list;
|
||||||
|
|
||||||
|
/* make sure a clean start */
|
||||||
|
seg_list.clear();
|
||||||
|
|
||||||
|
/* Traverse node_segments */
|
||||||
|
for (size_t inode = 0; inode < get_chan_width(); ++inode) {
|
||||||
|
std::vector<size_t>::iterator it;
|
||||||
|
/* Try to find the node_segment id in the list */
|
||||||
|
it = find(seg_list.begin(), seg_list.end(), node_segments_[inode]);
|
||||||
|
if ( it != seg_list.end() ) {
|
||||||
|
/* Not found, add it to the list */
|
||||||
|
seg_list.push_back(node_segments_[inode]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return seg_list;
|
||||||
|
}
|
||||||
|
|
||||||
/* Mutators */
|
/* Mutators */
|
||||||
void RRChan::set(const RRChan& rr_chan) {
|
void RRChan::set(const RRChan& rr_chan) {
|
||||||
|
@ -166,7 +186,7 @@ void RRChan::rotate(size_t rotate_begin, size_t rotate_end, size_t offset) {
|
||||||
|
|
||||||
/* rotate all the channel nodes by a given offset:
|
/* rotate all the channel nodes by a given offset:
|
||||||
* Routing Channel nodes are divided into different groups using segment ids
|
* Routing Channel nodes are divided into different groups using segment ids
|
||||||
* each group is rotated separatedly
|
* each group should be rotated separatedly
|
||||||
*/
|
*/
|
||||||
void RRChan::rotate_by_node_direction(enum e_direction node_direction, size_t offset) {
|
void RRChan::rotate_by_node_direction(enum e_direction node_direction, size_t offset) {
|
||||||
/* skip if there are no nodes */
|
/* skip if there are no nodes */
|
||||||
|
@ -174,37 +194,44 @@ void RRChan::rotate_by_node_direction(enum e_direction node_direction, size_t of
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get the channel nodes of a given direction */
|
/* get a list of segment_ids existing in the routing channel */
|
||||||
std::vector<t_rr_node*> nodes;
|
std::vector<size_t> seg_ids = get_segment_ids();
|
||||||
std::vector<size_t> node_segments;
|
|
||||||
for (size_t inode = 0; inode < get_chan_width(); ++inode) {
|
for (size_t iseg = 0; iseg < seg_ids.size(); ++iseg) {
|
||||||
if (node_direction == get_node(inode)->direction) {
|
/* Get the channel nodes of a given direction */
|
||||||
nodes.push_back(get_node(inode));
|
std::vector<t_rr_node*> nodes;
|
||||||
node_segments.push_back(get_node_segment(inode));
|
std::vector<size_t> node_segments;
|
||||||
|
for (size_t inode = 0; inode < get_chan_width(); ++inode) {
|
||||||
|
if ( (node_direction == get_node(inode)->direction)
|
||||||
|
&& (seg_ids[iseg] == get_node_segment(inode)) ) {
|
||||||
|
nodes.push_back(get_node(inode));
|
||||||
|
node_segments.push_back(get_node_segment(inode));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
size_t adapt_offset = offset % nodes.size();
|
size_t adapt_offset = offset % nodes.size();
|
||||||
assert(adapt_offset < nodes.size());
|
assert(adapt_offset < nodes.size());
|
||||||
|
|
||||||
/* Rotate the chan_nodes */
|
/* Rotate the chan_nodes */
|
||||||
std::rotate(nodes.begin(), nodes.begin() + adapt_offset, nodes.end());
|
std::rotate(nodes.begin(), nodes.begin() + adapt_offset, nodes.end());
|
||||||
std::rotate(node_segments.begin(), node_segments.begin() + adapt_offset, node_segments.end());
|
std::rotate(node_segments.begin(), node_segments.begin() + adapt_offset, node_segments.end());
|
||||||
|
|
||||||
/* back-annotate to to the original chan nodes*/
|
/* back-annotate to to the original chan nodes*/
|
||||||
for (size_t inode = 0; inode < get_chan_width(); ++inode) {
|
for (size_t inode = 0; inode < get_chan_width(); ++inode) {
|
||||||
if (node_direction == get_node(inode)->direction) {
|
if ( (node_direction == get_node(inode)->direction)
|
||||||
nodes_[inode] = nodes.front();
|
&& (seg_ids[iseg] == get_node_segment(inode)) ) {
|
||||||
node_segments_[inode] = node_segments.front();
|
nodes_[inode] = nodes.front();
|
||||||
/* pop up temp vectors */
|
node_segments_[inode] = node_segments.front();
|
||||||
nodes.erase(nodes.begin());
|
/* pop up temp vectors */
|
||||||
node_segments.erase(node_segments.begin());
|
nodes.erase(nodes.begin());
|
||||||
|
node_segments.erase(node_segments.begin());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* Make sure temp vectors are all poped out */
|
/* Make sure temp vectors are all poped out */
|
||||||
assert ( 0 == nodes.size());
|
assert ( 0 == nodes.size());
|
||||||
assert ( 0 == node_segments.size());
|
assert ( 0 == node_segments.size());
|
||||||
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -219,37 +246,44 @@ void RRChan::counter_rotate_by_node_direction(enum e_direction node_direction, s
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get the channel nodes of a given direction */
|
/* get a list of segment_ids existing in the routing channel */
|
||||||
std::vector<t_rr_node*> nodes;
|
std::vector<size_t> seg_ids = get_segment_ids();
|
||||||
std::vector<size_t> node_segments;
|
|
||||||
for (size_t inode = 0; inode < get_chan_width(); ++inode) {
|
for (size_t iseg = 0; iseg < seg_ids.size(); ++iseg) {
|
||||||
if (node_direction == get_node(inode)->direction) {
|
/* Get the channel nodes of a given direction */
|
||||||
nodes.push_back(get_node(inode));
|
std::vector<t_rr_node*> nodes;
|
||||||
node_segments.push_back(get_node_segment(inode));
|
std::vector<size_t> node_segments;
|
||||||
|
for (size_t inode = 0; inode < get_chan_width(); ++inode) {
|
||||||
|
if ( (node_direction == get_node(inode)->direction)
|
||||||
|
&& (seg_ids[iseg] == get_node_segment(inode)) ) {
|
||||||
|
nodes.push_back(get_node(inode));
|
||||||
|
node_segments.push_back(get_node_segment(inode));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
size_t adapt_offset = offset % nodes.size();
|
size_t adapt_offset = offset % nodes.size();
|
||||||
assert(adapt_offset < nodes.size());
|
assert(adapt_offset < nodes.size());
|
||||||
|
|
||||||
/* Rotate the chan_nodes */
|
/* Rotate the chan_nodes */
|
||||||
std::rotate(nodes.begin(), nodes.begin() + nodes.size() - adapt_offset, nodes.end());
|
std::rotate(nodes.begin(), nodes.begin() + nodes.size() - adapt_offset, nodes.end());
|
||||||
std::rotate(node_segments.begin(), node_segments.begin() + node_segments.size() - adapt_offset, node_segments.end());
|
std::rotate(node_segments.begin(), node_segments.begin() + node_segments.size() - adapt_offset, node_segments.end());
|
||||||
|
|
||||||
/* back-annotate to to the original chan nodes*/
|
/* back-annotate to to the original chan nodes*/
|
||||||
for (size_t inode = 0; inode < get_chan_width(); ++inode) {
|
for (size_t inode = 0; inode < get_chan_width(); ++inode) {
|
||||||
if (node_direction == get_node(inode)->direction) {
|
if ( (node_direction == get_node(inode)->direction)
|
||||||
nodes_[inode] = nodes.front();
|
&& (seg_ids[iseg] == get_node_segment(inode)) ) {
|
||||||
node_segments_[inode] = node_segments.front();
|
nodes_[inode] = nodes.front();
|
||||||
/* pop up temp vectors */
|
node_segments_[inode] = node_segments.front();
|
||||||
nodes.erase(nodes.begin());
|
/* pop up temp vectors */
|
||||||
node_segments.erase(node_segments.begin());
|
nodes.erase(nodes.begin());
|
||||||
|
node_segments.erase(node_segments.begin());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* Make sure temp vectors are all poped out */
|
/* Make sure temp vectors are all poped out */
|
||||||
assert ( 0 == nodes.size());
|
assert ( 0 == nodes.size());
|
||||||
assert ( 0 == node_segments.size());
|
assert ( 0 == node_segments.size());
|
||||||
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1763,6 +1797,9 @@ void DeviceRRSwitchBlock::add_rr_switch_block(DeviceCoordinator& coordinator,
|
||||||
|
|
||||||
/* Add a switch block to the array, which will automatically identify and update the lists of unique mirrors and rotatable mirrors */
|
/* Add a switch block to the array, which will automatically identify and update the lists of unique mirrors and rotatable mirrors */
|
||||||
void DeviceRRSwitchBlock::build_unique_mirror() {
|
void DeviceRRSwitchBlock::build_unique_mirror() {
|
||||||
|
/* Make sure a clean start */
|
||||||
|
clear_mirror();
|
||||||
|
|
||||||
for (size_t ix = 0; ix < rr_switch_block_.size(); ++ix) {
|
for (size_t ix = 0; ix < rr_switch_block_.size(); ++ix) {
|
||||||
for (size_t iy = 0; iy < rr_switch_block_[ix].size(); ++iy) {
|
for (size_t iy = 0; iy < rr_switch_block_[ix].size(); ++iy) {
|
||||||
bool is_unique_mirror = true;
|
bool is_unique_mirror = true;
|
||||||
|
@ -1830,15 +1867,34 @@ void DeviceRRSwitchBlock::clear() {
|
||||||
/* clean rr_switch_block array */
|
/* clean rr_switch_block array */
|
||||||
for (size_t x = 0; x < rr_switch_block_.size(); ++x) {
|
for (size_t x = 0; x < rr_switch_block_.size(); ++x) {
|
||||||
rr_switch_block_[x].clear();
|
rr_switch_block_[x].clear();
|
||||||
|
rr_switch_block_mirror_id_[x].clear();
|
||||||
|
rr_switch_block_rotatable_mirror_id_[x].clear();
|
||||||
}
|
}
|
||||||
rr_switch_block_.clear();
|
rr_switch_block_.clear();
|
||||||
|
rr_switch_block_mirror_id_.clear();
|
||||||
|
rr_switch_block_rotatable_mirror_id_.clear();
|
||||||
|
|
||||||
|
/* clean unique mirror */
|
||||||
|
clear_mirror();
|
||||||
|
|
||||||
|
/* clean unique mirror */
|
||||||
|
clear_rotatable_mirror();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* clean the content related to unique_mirrors */
|
||||||
|
void DeviceRRSwitchBlock::clear_mirror() {
|
||||||
/* clean unique mirror */
|
/* clean unique mirror */
|
||||||
unique_mirror_.clear();
|
unique_mirror_.clear();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* clean the content related to rotatable_mirrors */
|
||||||
|
void DeviceRRSwitchBlock::clear_rotatable_mirror() {
|
||||||
/* clean unique mirror */
|
/* clean unique mirror */
|
||||||
rotatable_mirror_.clear();
|
rotatable_mirror_.clear();
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -47,6 +47,7 @@ class RRChan {
|
||||||
int get_node_segment(t_rr_node* node) const;
|
int get_node_segment(t_rr_node* node) const;
|
||||||
int get_node_segment(size_t track_num) const;
|
int get_node_segment(size_t track_num) const;
|
||||||
bool is_mirror(RRChan& cand) const; /* evaluate if two RR_chan is mirror to each other */
|
bool is_mirror(RRChan& cand) const; /* evaluate if two RR_chan is mirror to each other */
|
||||||
|
std::vector<size_t> get_segment_ids() const; /* Get a list of segments used in this routing channel */
|
||||||
public: /* Mutators */
|
public: /* Mutators */
|
||||||
void set(const RRChan&); /* copy */
|
void set(const RRChan&); /* copy */
|
||||||
void set_type(t_rr_type type); /* modify type */
|
void set_type(t_rr_type type); /* modify type */
|
||||||
|
@ -253,6 +254,8 @@ class DeviceRRSwitchBlock {
|
||||||
void build_unique_mirror(); /* Add a switch block to the array, which will automatically identify and update the lists of unique mirrors and rotatable mirrors */
|
void build_unique_mirror(); /* Add a switch block to the array, which will automatically identify and update the lists of unique mirrors and rotatable mirrors */
|
||||||
void add_rotatable_mirror(DeviceCoordinator& coordinator, RRSwitchBlock& rr_sb); /* Add a switch block to the array, which will automatically identify and update the lists of unique mirrors and rotatable mirrors */
|
void add_rotatable_mirror(DeviceCoordinator& coordinator, RRSwitchBlock& rr_sb); /* Add a switch block to the array, which will automatically identify and update the lists of unique mirrors and rotatable mirrors */
|
||||||
void clear(); /* clean the content */
|
void clear(); /* clean the content */
|
||||||
|
void clear_mirror(); /* clean the content */
|
||||||
|
void clear_rotatable_mirror(); /* clean the content */
|
||||||
private: /* Validators */
|
private: /* Validators */
|
||||||
bool validate_coordinator(DeviceCoordinator& coordinator) const; /* Validate if the (x,y) is the range of this device */
|
bool validate_coordinator(DeviceCoordinator& coordinator) const; /* Validate if the (x,y) is the range of this device */
|
||||||
bool validate_unique_mirror_index(size_t index) const; /* Validate if the index in the range of unique_mirror vector*/
|
bool validate_unique_mirror_index(size_t index) const; /* Validate if the index in the range of unique_mirror vector*/
|
||||||
|
|
Loading…
Reference in New Issue