Add copy constructor for RRChan, RRSwitchBlock etc.

This commit is contained in:
tangxifan 2019-05-27 15:44:34 -06:00
parent 1bea9870fc
commit 5720217cfd
5 changed files with 154 additions and 24 deletions

View File

@ -3,12 +3,10 @@
/* Member functions for DeviceCoordinator */
/* Public constructors */
/*
DeviceCoordinator::DeviceCoordinator(DeviceCoordinator& coordinator) {
DeviceCoordinator::DeviceCoordinator(const DeviceCoordinator& coordinator) {
set(coordinator.get_x(), coordinator.get_y());
return;
}
*/
DeviceCoordinator::DeviceCoordinator(size_t x, size_t y) {
set(x, y);

View File

@ -11,6 +11,7 @@
class DeviceCoordinator {
public: /* Contructors */
DeviceCoordinator(size_t x, size_t y);
DeviceCoordinator(const DeviceCoordinator&); /* copy constructor*/
DeviceCoordinator();
public: /* Accessors */
size_t get_x() const;

View File

@ -1048,7 +1048,7 @@ RRSwitchBlock rotate_rr_switch_block_for_mirror(DeviceCoordinator& device_range,
* nothing to do. This is the base we like
*/
if ( ( 0 == rotated_rr_switch_block.get_x())
|| ( 0 == rotated_rr_switch_block.get_y()) ) {
&& ( 0 == rotated_rr_switch_block.get_y()) ) {
return rotated_rr_switch_block;
}
/* 2. TOP-LEFT corner:
@ -1056,7 +1056,7 @@ RRSwitchBlock rotate_rr_switch_block_for_mirror(DeviceCoordinator& device_range,
* swap the chan_node between TOP and BOTTOM,
*/
if ( ( 0 == rotated_rr_switch_block.get_x())
|| (device_range.get_y() == rotated_rr_switch_block.get_y()) ) {
&& (device_range.get_y() == rotated_rr_switch_block.get_y()) ) {
rotated_rr_switch_block.swap_opin_node(TOP, BOTTOM);
rotated_rr_switch_block.swap_chan_node(TOP, BOTTOM);
rotated_rr_switch_block.mirror_side_chan_node_direction(TOP);
@ -1070,10 +1070,9 @@ RRSwitchBlock rotate_rr_switch_block_for_mirror(DeviceCoordinator& device_range,
* swap the chan_node between LEFT and RIGHT,
*/
if ( (device_range.get_x() == rotated_rr_switch_block.get_x())
|| (device_range.get_y() == rotated_rr_switch_block.get_y()) ) {
&& (device_range.get_y() == rotated_rr_switch_block.get_y()) ) {
rotated_rr_switch_block.swap_opin_node(TOP, BOTTOM);
rotated_rr_switch_block.swap_chan_node(TOP, BOTTOM);
return rotated_rr_switch_block;
rotated_rr_switch_block.mirror_side_chan_node_direction(TOP);
rotated_rr_switch_block.mirror_side_chan_node_direction(BOTTOM);
rotated_rr_switch_block.swap_opin_node(LEFT, RIGHT);
@ -1087,7 +1086,7 @@ RRSwitchBlock rotate_rr_switch_block_for_mirror(DeviceCoordinator& device_range,
* swap the chan_node between LEFT and RIGHT,
*/
if ( (device_range.get_x() == rotated_rr_switch_block.get_x())
|| (0 == rotated_rr_switch_block.get_y()) ) {
&& (0 == rotated_rr_switch_block.get_y()) ) {
rotated_rr_switch_block.swap_opin_node(LEFT, RIGHT);
rotated_rr_switch_block.swap_chan_node(LEFT, RIGHT);
rotated_rr_switch_block.mirror_side_chan_node_direction(LEFT);
@ -1167,18 +1166,17 @@ DeviceRRSwitchBlock build_device_rr_switch_blocks(int LL_num_rr_nodes, t_rr_node
DeviceRRSwitchBlock LL_device_rr_switch_block;
/* Initialize */
DeviceCoordinator device_coordinator((size_t)nx + 1, (size_t)ny + 1);
LL_device_rr_switch_block.reserve(device_coordinator);
DeviceCoordinator sb_range((size_t)nx, (size_t)ny);
LL_device_rr_switch_block.reserve(sb_range);
/* For each switch block, determine the size of array */
for (size_t ix = 0; ix < device_coordinator.get_x(); ++ix) {
for (size_t iy = 0; iy < device_coordinator.get_y(); ++iy) {
DeviceCoordinator sb_range((size_t)nx, (size_t)ny);
for (size_t ix = 0; ix <= sb_range.get_x(); ++ix) {
for (size_t iy = 0; iy <= sb_range.get_y(); ++iy) {
RRSwitchBlock rr_switch_block = build_rr_switch_block(sb_range, ix, iy,
LL_num_rr_nodes, LL_rr_node,
LL_rr_node_indices,
num_segments, LL_rr_indexed_data);
RRSwitchBlock rotated_switch_block = rotate_rr_switch_block_for_mirror(sb_range, rr_switch_block);
RRSwitchBlock rotated_switch_block = rotate_rr_switch_block_for_mirror(sb_range, rotated_switch_block);
DeviceCoordinator sb_coordinator = rr_switch_block.get_coordinator();
LL_device_rr_switch_block.add_rr_switch_block(sb_coordinator, rr_switch_block, rotated_switch_block);
}

View File

@ -7,6 +7,20 @@
/* Member Functions of Class RRChan */
/* Constructors */
/* Copy Constructor */
RRChan::RRChan(const RRChan& rr_chan) {
this->type_ = rr_chan.get_type();
/* Copy node and node_segments */
this->reserve_node(rr_chan.get_chan_width());
for (size_t inode = 0; inode < rr_chan.get_chan_width(); ++inode) {
this->nodes_.push_back(rr_chan.get_node(inode));
this->node_segments_.push_back(rr_chan.get_node_segment(inode));
}
return;
}
/* default constructor */
RRChan::RRChan() {
type_ = NUM_RR_TYPES;
nodes_.resize(0);
@ -449,6 +463,51 @@ bool DeviceRRChan::valid_module_id(t_rr_type chan_type, size_t module_id) const
}
/* Member Functions of Class RRSwitchBlock*/
/* Constructor for an empty object */
RRSwitchBlock::RRSwitchBlock() {
return;
}
/* Copy constructor */
RRSwitchBlock::RRSwitchBlock(const RRSwitchBlock& src) {
/* Copy coordinator */
this->set_coordinator(src.get_coordinator().get_x(), src.get_coordinator().get_y());
/* Initialize sides */
this->init_num_sides(src.get_num_sides());
/* Copy vectors */
for (size_t side = 0; side < src.get_num_sides(); ++side) {
Side side_manager(side);
/* Copy chan_nodes */
this->chan_node_[side_manager.get_side()] = src.get_chan(side_manager.get_side());
/* Copy chan_node_direction_*/
for (size_t inode = 0; inode < src.get_chan_width(side_manager.get_side()); ++inode) {
this->chan_node_direction_[side_manager.get_side()].push_back(src.get_chan_node_direction(side_manager.get_side(), inode));
}
/* Copy opin_node and opin_node_grid_side_ */
for (size_t inode = 0; inode < src.get_num_opin_nodes(side_manager.get_side()); ++inode) {
this->opin_node_[side_manager.get_side()].push_back(src.get_opin_node(side_manager.get_side(), inode));
this->opin_node_grid_side_[side_manager.get_side()].push_back(src.get_opin_node_grid_side(side_manager.get_side(), inode));
}
/* Copy ipin_node and ipin_node_grid_side_ */
for (size_t inode = 0; inode < src.get_num_ipin_nodes(side_manager.get_side()); ++inode) {
this->ipin_node_[side_manager.get_side()].push_back(src.get_ipin_node(side_manager.get_side(), inode));
this->ipin_node_grid_side_[side_manager.get_side()].push_back(src.get_ipin_node_grid_side(side_manager.get_side(), inode));
}
}
/* Copy conf_bits
* TODO: this will be recovered when num_conf_bits etc will be initialized during FPGA-X2P setup
this->set_num_reserved_conf_bits(src.get_num_reserved_conf_bits());
this->set_conf_bits_lsb(src.get_conf_bits_lsb());
this->set_conf_bits_msb(src.get_conf_bits_msb());
*/
return;
}
/* Accessors */
@ -504,6 +563,17 @@ enum PORTS RRSwitchBlock::get_chan_node_direction(enum e_side side, size_t track
return chan_node_direction_[side_manager.to_size_t()][track_id];
}
/* get a RRChan at a given side and track_id */
RRChan RRSwitchBlock::get_chan(enum e_side side) const {
Side side_manager(side);
assert(side_manager.validate());
/* Ensure the side is valid in the context of this switch block */
assert( validate_side(side) );
return chan_node_[side_manager.to_size_t()];
}
/* get a rr_node at a given side and track_id */
t_rr_node* RRSwitchBlock::get_chan_node(enum e_side side, size_t track_id) const {
Side side_manager(side);
@ -540,6 +610,47 @@ size_t RRSwitchBlock::get_num_ipin_nodes(enum e_side side) const {
return ipin_node_[side_manager.to_size_t()].size();
}
/* get a opin_node at a given side and track_id */
t_rr_node* RRSwitchBlock::get_ipin_node(enum e_side side, size_t node_id) const {
Side side_manager(side);
assert(side_manager.validate());
/* Ensure the side is valid in the context of this switch block */
assert( validate_side(side) );
/* Ensure the track is valid in the context of this switch block at a specific side */
assert( validate_ipin_node_id(side, node_id) );
return ipin_node_[side_manager.to_size_t()][node_id];
}
/* get the grid_side of a opin_node at a given side and track_id */
enum e_side RRSwitchBlock::get_ipin_node_grid_side(enum e_side side, size_t node_id) const {
Side side_manager(side);
assert(side_manager.validate());
/* Ensure the side is valid in the context of this switch block */
assert( validate_side(side) );
/* Ensure the track is valid in the context of this switch block at a specific side */
assert( validate_ipin_node_id(side, node_id) );
return ipin_node_grid_side_[side_manager.to_size_t()][node_id];
}
/* get the grid side of a opin_rr_node */
enum e_side RRSwitchBlock::get_ipin_node_grid_side(t_rr_node* ipin_node) const {
enum e_side side;
int index;
/* Find the side and index */
get_node_side_and_index(ipin_node, OUT_PORT, &side, &index);
assert(-1 != index);
assert(validate_side(side));
return get_ipin_node_grid_side(side, index);
}
/* Get the number of OPIN rr_nodes on a side */
size_t RRSwitchBlock::get_num_opin_nodes(enum e_side side) const {
Side side_manager(side);
@ -847,10 +958,12 @@ bool RRSwitchBlock::is_mirror(RRSwitchBlock& cand) const {
if (get_chan_node_direction(side_manager.get_side(), itrack) != cand.get_chan_node_direction(side_manager.get_side(), itrack)) {
return false;
}
/* Check the track_id of each node */
/* Check the track_id of each node
* ptc is not necessary, we care the connectivity!
if (get_chan_node(side_manager.get_side(), itrack)->ptc_num != cand.get_chan_node(side_manager.get_side(), itrack)->ptc_num) {
return false;
}
*/
/* For OUT_PORT rr_node, we need to check fan-in */
if (OUT_PORT != get_chan_node_direction(side_manager.get_side(), itrack)) {
continue; /* skip IN_PORT */
@ -1445,6 +1558,21 @@ bool RRSwitchBlock::validate_opin_node_id(enum e_side side, size_t node_id) cons
return false;
}
/* Check the ipin_node_id is valid for opin_node_ and opin_node_grid_side_ */
bool RRSwitchBlock::validate_ipin_node_id(enum e_side side, size_t node_id) const {
Side side_manager(side);
if (false == validate_side(side)) {
return false;
}
if ( ( node_id < ipin_node_[side_manager.to_size_t()].size())
&&( node_id < ipin_node_grid_side_[side_manager.to_size_t()].size()) ) {
return true;
}
return false;
}
/* Validate the number of configuration bits, MSB should be no less than the LSB !!! */
bool RRSwitchBlock::validate_num_conf_bits() const {
if (conf_bits_msb_ >= conf_bits_lsb_) {
@ -1559,15 +1687,15 @@ void DeviceRRSwitchBlock::reserve(DeviceCoordinator& coordinator) {
/* Resize rr_switch_block array is needed*/
void DeviceRRSwitchBlock::resize_upon_need(DeviceCoordinator& coordinator) {
if (coordinator.get_x() + 1 > rr_switch_block_.size()) {
rr_switch_block_.resize(coordinator.get_x());
rr_switch_block_mirror_id_.resize(coordinator.get_x());
rr_switch_block_rotatable_mirror_id_.resize(coordinator.get_x());
rr_switch_block_.resize(coordinator.get_x() + 1);
rr_switch_block_mirror_id_.resize(coordinator.get_x() + 1);
rr_switch_block_rotatable_mirror_id_.resize(coordinator.get_x() + 1);
}
if (coordinator.get_y() + 1 > rr_switch_block_[coordinator.get_x()].size()) {
rr_switch_block_[coordinator.get_x()].resize(coordinator.get_y());
rr_switch_block_mirror_id_[coordinator.get_x()].resize(coordinator.get_y());
rr_switch_block_rotatable_mirror_id_[coordinator.get_x()].resize(coordinator.get_y());
rr_switch_block_[coordinator.get_x()].resize(coordinator.get_y() + 1);
rr_switch_block_mirror_id_[coordinator.get_x()].resize(coordinator.get_y() + 1);
rr_switch_block_rotatable_mirror_id_[coordinator.get_x()].resize(coordinator.get_y() + 1);
}
return;
@ -1607,9 +1735,6 @@ void DeviceRRSwitchBlock::add_rr_switch_block(DeviceCoordinator& coordinator,
/* add rotatable mirror support */
for (size_t mirror_id = 0; mirror_id < get_num_rotatable_mirror(); ++mirror_id) {
/* Try to rotate as many times as the maximum channel width in this switch block
* This may not fully cover all the rotation possibility but may be enough now
*/
/* Skip if these may never match as a mirror (violation in basic requirements */
if (false == get_switch_block(rotatable_mirror_[mirror_id]).is_mirrorable(rotated_rr_switch_block)) {
continue;

View File

@ -37,6 +37,7 @@
*/
class RRChan {
public: /* Constructors */
RRChan(const RRChan&); /* Copy Constructor */
RRChan();
public: /* Accessors */
t_rr_type get_type() const;
@ -128,6 +129,8 @@ class DeviceRRChan {
*/
class RRSwitchBlock {
public: /* Contructors */
RRSwitchBlock(const RRSwitchBlock&);/* Copy constructor */
RRSwitchBlock();/* Default constructor */
public: /* Accessors */
size_t get_x() const; /* get the x coordinator of this switch block */
size_t get_y() const; /* get the y coordinator of this switch block */
@ -136,9 +139,13 @@ class RRSwitchBlock {
size_t get_chan_width(enum e_side side) const; /* Get the number of routing tracks on a side */
size_t get_max_chan_width() const; /* Get the maximum number of routing tracks on all sides */
enum PORTS get_chan_node_direction(enum e_side side, size_t track_id) const; /* Get the direction of a rr_node at a given side and track_id */
RRChan get_chan(enum e_side side) const; /* get a rr_node at a given side and track_id */
t_rr_node* get_chan_node(enum e_side side, size_t track_id) const; /* get a rr_node at a given side and track_id */
size_t get_chan_node_segment(enum e_side side, size_t track_id) const; /* get the segment id of a channel rr_node */
size_t get_num_ipin_nodes(enum e_side side) const; /* Get the number of IPIN rr_nodes on a side */
t_rr_node* get_ipin_node(enum e_side side, size_t node_id) const; /* get a rr_node at a given side and track_id */
enum e_side get_ipin_node_grid_side(enum e_side side, size_t node_id) const; /* get a rr_node at a given side and track_id */
enum e_side get_ipin_node_grid_side(t_rr_node* ipin_node) const; /* get a rr_node at a given side and track_id */
size_t get_num_opin_nodes(enum e_side side) const; /* Get the number of OPIN rr_nodes on a side */
t_rr_node* get_opin_node(enum e_side side, size_t node_id) const; /* get a rr_node at a given side and track_id */
enum e_side get_opin_node_grid_side(enum e_side side, size_t node_id) const; /* get a rr_node at a given side and track_id */
@ -195,6 +202,7 @@ class RRSwitchBlock {
bool validate_side(enum e_side side) const;
bool validate_track_id(enum e_side side, size_t track_id) const;
bool validate_opin_node_id(enum e_side side, size_t node_id) const;
bool validate_ipin_node_id(enum e_side side, size_t node_id) const;
bool validate_num_reserved_conf_bits() const;
bool validate_num_conf_bits() const;
private: /* Internal Data */