diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_unique_routing.c b/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_unique_routing.c index 5aca29cba..e95f168fe 100644 --- a/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_unique_routing.c +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_unique_routing.c @@ -1224,6 +1224,11 @@ DeviceRRSwitchBlock build_device_rr_switch_blocks(boolean output_sb_xml, char* s "Backannotated %d switch blocks.\n", (nx + 1) * (ny + 1) ); + LL_device_rr_switch_block.build_segment_ids(); + vpr_printf(TIO_MESSAGE_INFO, + "Detect %lu routing segments used by switch blocks.\n", + LL_device_rr_switch_block.get_num_segments()); + if (TRUE == output_sb_xml) { write_device_rr_switch_block_to_xml(sb_xml_dir, LL_device_rr_switch_block); @@ -1247,10 +1252,14 @@ DeviceRRSwitchBlock build_device_rr_switch_blocks(boolean output_sb_xml, char* s /* Report number of unique mirrors */ for (size_t side = 0; side < LL_device_rr_switch_block.get_max_num_sides(); ++side) { Side side_manager(side); - vpr_printf(TIO_MESSAGE_INFO, - "For side %s: Detect %d independent switch blocks from %d switch blocks.\n", - side_manager.to_string(), LL_device_rr_switch_block.get_num_unique_module(side_manager.get_side()), - (nx + 1) * (ny + 1) ); + /* get segment ids */ + for (size_t iseg = 0; iseg < LL_device_rr_switch_block.get_num_segments(); ++iseg) { + vpr_printf(TIO_MESSAGE_INFO, + "For side %s, segment id %lu: Detect %d independent switch blocks from %d switch blocks.\n", + side_manager.to_string(), LL_device_rr_switch_block.get_segment_id(iseg), + LL_device_rr_switch_block.get_num_unique_module(side_manager.get_side(), iseg), + (nx + 1) * (ny + 1) ); + } } /* Create directory if needed */ diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/base/rr_blocks.cpp b/vpr7_x2p/vpr/SRC/fpga_x2p/base/rr_blocks.cpp index 9989d8ea6..911a1915c 100644 --- a/vpr7_x2p/vpr/SRC/fpga_x2p/base/rr_blocks.cpp +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/base/rr_blocks.cpp @@ -934,19 +934,8 @@ size_t RRSwitchBlock::get_hint_rotate_offset(RRSwitchBlock& cand) const { return offset_hint; } - -/* check if a side of candidate SB is a mirror of the current one - * Check the specified side of two switch blocks: - * 1. Number of channel/opin/ipin rr_nodes are same - * For channel rr_nodes - * 2. check if their track_ids (ptc_num) are same - * 3. Check if the switches (ids) are same - * For opin/ipin rr_nodes, - * 4. check if their parent type_descriptors same, - * 5. check if pin class id and pin id are same - * If all above are satisfied, the side of the two switch blocks are mirrors! - */ -bool RRSwitchBlock::is_side_mirror(RRSwitchBlock& cand, enum e_side side) const { +/* check if all the routing segments of a side of candidate SB is a mirror of the current one */ +bool RRSwitchBlock::is_side_segment_mirror(RRSwitchBlock& cand, enum e_side side, size_t seg_id) const { /* Create a side manager */ Side side_manager(side); @@ -954,12 +943,17 @@ bool RRSwitchBlock::is_side_mirror(RRSwitchBlock& cand, enum e_side side) const assert ( side_manager.to_size_t() < get_num_sides() ); assert ( side_manager.to_size_t() < cand.get_num_sides() ); + /* check the numbers/directionality of channel rr_nodes */ /* Ensure we have the same channel width on this side */ if (get_chan_width(side) != cand.get_chan_width(side)) { return false; } for (size_t itrack = 0; itrack < get_chan_width(side); ++itrack) { + /* Bypass unrelated segments */ + if (seg_id != get_chan_node_segment(side, itrack)) { + continue; + } /* Check the directionality of each node */ if (get_chan_node_direction(side, itrack) != cand.get_chan_node_direction(side, itrack)) { return false; @@ -967,7 +961,7 @@ bool RRSwitchBlock::is_side_mirror(RRSwitchBlock& cand, enum e_side side) const /* 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; + eturn false; } */ /* For OUT_PORT rr_node, we need to check fan-in */ @@ -990,6 +984,31 @@ bool RRSwitchBlock::is_side_mirror(RRSwitchBlock& cand, enum e_side side) const return false; } + return true; +} + +/* check if a side of candidate SB is a mirror of the current one + * Check the specified side of two switch blocks: + * 1. Number of channel/opin/ipin rr_nodes are same + * For channel rr_nodes + * 2. check if their track_ids (ptc_num) are same + * 3. Check if the switches (ids) are same + * For opin/ipin rr_nodes, + * 4. check if their parent type_descriptors same, + * 5. check if pin class id and pin id are same + * If all above are satisfied, the side of the two switch blocks are mirrors! + */ +bool RRSwitchBlock::is_side_mirror(RRSwitchBlock& cand, enum e_side side) const { + + /* get a list of segments */ + std::vector seg_ids = get_chan(side).get_segment_ids(); + + for (size_t iseg = 0; iseg < seg_ids.size(); ++iseg) { + if (false == is_side_segment_mirror(cand, side, seg_ids[iseg])) { + return false; + } + } + return true; } @@ -1098,40 +1117,44 @@ char* RRSwitchBlock::gen_verilog_instance_name() const { } /* Public Accessors Verilog writer */ -char* RRSwitchBlock::gen_verilog_side_module_name(enum e_side side) const { +char* RRSwitchBlock::gen_verilog_side_module_name(enum e_side side, size_t seg_id) const { char* ret = NULL; Side side_manager(side); std::string x_str = std::to_string(get_x()); std::string y_str = std::to_string(get_y()); + std::string seg_id_str = std::to_string(seg_id); std::string side_str(side_manager.to_string()); ret = (char*)my_malloc(2 + 1 + x_str.length() + 2 + y_str.length() + 2 + side_str.length() + + 2 + 3 + seg_id_str.length() + 1 + 1); - sprintf(ret, "sb_%lu__%lu__%s_", - get_x(), get_y(), side_manager.to_string()); + sprintf(ret, "sb_%lu__%lu__%s_seg%lu_", + get_x(), get_y(), side_manager.to_string(), seg_id); return ret; } -char* RRSwitchBlock::gen_verilog_side_instance_name(enum e_side side) const { +char* RRSwitchBlock::gen_verilog_side_instance_name(enum e_side side, size_t seg_id) const { char* ret = NULL; Side side_manager(side); std::string x_str = std::to_string(get_x()); std::string y_str = std::to_string(get_y()); + std::string seg_id_str = std::to_string(seg_id); std::string side_str(side_manager.to_string()); ret = (char*)my_malloc(2 + 1 + x_str.length() + 2 + y_str.length() + 2 + side_str.length() + + 2 + 3 + seg_id_str.length() + 4 + 1); - sprintf(ret, "sb_%lu__%lu__%s__0_", - get_x(), get_y(), side_manager.to_string()); + sprintf(ret, "sb_%lu__%lu__%s_seg%lu_0_", + get_x(), get_y(), side_manager.to_string(), seg_id); return ret; } @@ -1760,10 +1783,11 @@ RRSwitchBlock DeviceRRSwitchBlock::get_switch_block(DeviceCoordinator& coordinat } /* get the number of unique side modules of switch blocks */ -size_t DeviceRRSwitchBlock::get_num_unique_module(enum e_side side) const { +size_t DeviceRRSwitchBlock::get_num_unique_module(enum e_side side, size_t seg_index) const { Side side_manager(side); assert(validate_side(side)); - return unique_module_[side_manager.to_size_t()].size(); + assert(validate_segment_index(seg_index)); + return unique_module_[side_manager.to_size_t()][seg_index].size(); } /* Get a rr switch block in the array with a coordinator */ @@ -1783,13 +1807,13 @@ size_t DeviceRRSwitchBlock::get_num_rotatable_mirror() const { } /* Get a rr switch block which is a unique module of a side of SB */ -RRSwitchBlock DeviceRRSwitchBlock::get_unique_side_module(size_t index, enum e_side side) const { - assert (validate_unique_module_index(index, side)); +RRSwitchBlock DeviceRRSwitchBlock::get_unique_side_module(size_t index, enum e_side side, size_t seg_id) const { + assert (validate_unique_module_index(index, side, seg_id)); Side side_manager(side); assert (validate_side(side)); - return rr_switch_block_[unique_module_[side_manager.to_size_t()][index].get_x()][unique_module_[side_manager.to_size_t()][index].get_y()]; + return rr_switch_block_[unique_module_[side_manager.to_size_t()][seg_id][index].get_x()][unique_module_[side_manager.to_size_t()][seg_id][index].get_y()]; } /* Get a rr switch block which a unique mirror */ @@ -1824,6 +1848,17 @@ size_t DeviceRRSwitchBlock::get_max_num_sides() const { return max_num_sides; } +/* Get the size of segment_ids */ +size_t DeviceRRSwitchBlock::get_num_segments() const { + return segment_ids_.size(); +} + +/* Get a segment id */ +size_t DeviceRRSwitchBlock::get_segment_id(size_t index) const { + assert(validate_segment_index(index)); + return segment_ids_[index]; +} + /* Public Mutators */ /* TODO: TOBE DEPRECATED!!! conf_bits should be initialized when creating a switch block!!! */ @@ -1871,6 +1906,11 @@ void DeviceRRSwitchBlock::reserve_unique_module_id(DeviceCoordinator& coordinato RRSwitchBlock rr_sb = get_switch_block(coordinator); rr_sb_unique_module_id_[coordinator.get_x()][coordinator.get_y()].resize(rr_sb.get_num_sides()); + for (size_t side = 0; side < rr_sb.get_num_sides(); ++side) { + Side side_manager(side); + rr_sb_unique_module_id_[coordinator.get_x()][coordinator.get_y()][side_manager.to_size_t()].resize(segment_ids_.size()); + } + return; } @@ -1952,19 +1992,22 @@ void DeviceRRSwitchBlock::build_unique_module() { /* Allocate the unique_side_module_ */ unique_module_.resize(get_max_num_sides()); + for (size_t side = 0; side < unique_module_.size(); ++side) { + unique_module_[side].resize(segment_ids_.size()); + } for (size_t ix = 0; ix < rr_switch_block_.size(); ++ix) { for (size_t iy = 0; iy < rr_switch_block_[ix].size(); ++iy) { DeviceCoordinator coordinator(ix, iy); - RRSwitchBlock* rr_sb = &(rr_switch_block_[ix][iy]); + RRSwitchBlock rr_sb = rr_switch_block_[ix][iy]; /* reserve the rr_sb_unique_module_id */ reserve_unique_module_id(coordinator); - for (size_t side = 0; side < rr_sb->get_num_sides(); ++side) { + for (size_t side = 0; side < rr_sb.get_num_sides(); ++side) { Side side_manager(side); /* Try to add it to the list */ - add_unique_side_module(coordinator, *rr_sb, side_manager.get_side()); + add_unique_side_module(coordinator, rr_sb, side_manager.get_side()); } } } @@ -2004,32 +2047,30 @@ void DeviceRRSwitchBlock::add_rotatable_mirror(DeviceCoordinator& coordinator, return; } -/* Add a unique side module to the list: - * Check if the connections and nodes on the specified side of the rr_sb - * If it is similar to any module[side][i] in the list, we build a link from the rr_sb to the unique_module - * Otherwise, we add the module to the unique_module list - */ -void DeviceRRSwitchBlock::add_unique_side_module(DeviceCoordinator& coordinator, RRSwitchBlock& rr_sb, enum e_side side) { +void DeviceRRSwitchBlock::add_unique_side_segment_module(DeviceCoordinator& coordinator, + RRSwitchBlock& rr_sb, + enum e_side side, + size_t seg_id) { bool is_unique_side_module = true; Side side_manager(side); /* add rotatable mirror support */ - for (size_t id = 0; id < get_num_unique_module(side); ++id) { + for (size_t id = 0; id < get_num_unique_module(side, seg_id); ++id) { /* Skip if these may never match as a mirror (violation in basic requirements */ - if (true == get_switch_block(unique_module_[side_manager.to_size_t()][id]).is_side_mirror(rr_sb, side)) { + if (true == get_switch_block(unique_module_[side_manager.to_size_t()][seg_id][id]).is_side_segment_mirror(rr_sb, side, segment_ids_[seg_id])) { /* This is a mirror, raise the flag and we finish */ is_unique_side_module = false; /* Record the id of unique mirror */ - rr_sb_unique_module_id_[coordinator.get_x()][coordinator.get_y()][side_manager.to_size_t()] = id; + rr_sb_unique_module_id_[coordinator.get_x()][coordinator.get_y()][side_manager.to_size_t()][seg_id] = id; break; } } /* Add to list if this is a unique mirror*/ if (true == is_unique_side_module) { - unique_module_[side_manager.to_size_t()].push_back(coordinator); + unique_module_[side_manager.to_size_t()][seg_id].push_back(coordinator); /* Record the id of unique mirror */ - rr_sb_unique_module_id_[coordinator.get_x()][coordinator.get_y()][side_manager.to_size_t()] = unique_module_[side_manager.to_size_t()].size() - 1; + rr_sb_unique_module_id_[coordinator.get_x()][coordinator.get_y()][side_manager.to_size_t()][seg_id] = unique_module_[side_manager.to_size_t()][seg_id].size() - 1; /* printf("Detect a rotatable mirror: SB[%lu][%lu]\n", coordinator.get_x(), coordinator.get_y()); */ @@ -2038,6 +2079,50 @@ void DeviceRRSwitchBlock::add_unique_side_module(DeviceCoordinator& coordinator, return; } +/* Add a unique side module to the list: + * Check if the connections and nodes on the specified side of the rr_sb + * If it is similar to any module[side][i] in the list, we build a link from the rr_sb to the unique_module + * Otherwise, we add the module to the unique_module list + */ +void DeviceRRSwitchBlock::add_unique_side_module(DeviceCoordinator& coordinator, + RRSwitchBlock& rr_sb, + enum e_side side) { + Side side_manager(side); + + for (size_t iseg = 0; iseg < segment_ids_.size(); ++iseg) { + add_unique_side_segment_module(coordinator, rr_sb, side, iseg); + } + + return; +} + +/* build a map of segment_ids */ +void DeviceRRSwitchBlock::build_segment_ids() { + /* go through each rr_sb, each side and find the segment_ids */ + for (size_t ix = 0; ix < rr_switch_block_.size(); ++ix) { + for (size_t iy = 0; iy < rr_switch_block_[ix].size(); ++iy) { + RRSwitchBlock* rr_sb = &(rr_switch_block_[ix][iy]); + for (size_t side = 0 ; side < rr_sb->get_num_sides(); ++side) { + Side side_manager(side); + /* get a list of segment_ids in this side */ + std::vector cur_seg_ids = rr_sb->get_chan(side_manager.get_side()).get_segment_ids(); + /* add to the segment_id_ if exist */ + for (size_t iseg = 0; iseg < cur_seg_ids.size(); ++iseg) { + std::vector::iterator it = std::find(segment_ids_.begin(), segment_ids_.end(), cur_seg_ids[iseg]); + /* find if it exists in the list */ + if (it != segment_ids_.end()) { + /* exist: continue */ + continue; + } + /* does not exist, push into the vector */ + segment_ids_.push_back(cur_seg_ids[iseg]); + } + } + } + } + return; +} + /* clean the content */ void DeviceRRSwitchBlock::clear() { /* clean rr_switch_block array */ @@ -2099,6 +2184,15 @@ void DeviceRRSwitchBlock::clear_rotatable_mirror() { return; } +/* clean the content related to segment_ids */ +void DeviceRRSwitchBlock::clear_segment_ids() { + /* clean segment_ids_ */ + segment_ids_.clear(); + + return; +} + + /* Validate if the (x,y) is the range of this device */ bool DeviceRRSwitchBlock::validate_coordinator(DeviceCoordinator& coordinator) const { if (coordinator.get_x() >= rr_switch_block_.capacity()) { @@ -2136,12 +2230,20 @@ bool DeviceRRSwitchBlock::validate_rotatable_mirror_index(size_t index) const { } /* Validate if the index in the range of unique_mirror vector*/ -bool DeviceRRSwitchBlock::validate_unique_module_index(size_t index, enum e_side side) const { +bool DeviceRRSwitchBlock::validate_unique_module_index(size_t index, enum e_side side, size_t seg_index) const { assert( validate_side(side)); + assert( validate_segment_index(seg_index)); Side side_manager(side); - if (index >= unique_module_[side_manager.get_side()].size()) { + if (index >= unique_module_[side_manager.get_side()][seg_index].size()) { return false; } return true; } + +bool DeviceRRSwitchBlock::validate_segment_index(size_t index) const { + if (index >= segment_ids_.size()) { + return false; + } + return true; +} diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/base/rr_blocks.h b/vpr7_x2p/vpr/SRC/fpga_x2p/base/rr_blocks.h index 7557b6d71..1f1034239 100644 --- a/vpr7_x2p/vpr/SRC/fpga_x2p/base/rr_blocks.h +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/base/rr_blocks.h @@ -163,6 +163,7 @@ class RRSwitchBlock { size_t get_conf_bits_msb() const; bool is_node_imply_short_connection(t_rr_node* src_node) const; /* Check if the node imply a short connection inside the SB, which happens to long wires across a FPGA fabric */ bool is_side_mirror(RRSwitchBlock& cand, enum e_side side) const; /* check if a side of candidate SB is a mirror of the current one */ + bool is_side_segment_mirror(RRSwitchBlock& cand, enum e_side side, size_t seg_id) const; /* check if all the routing segments of a side of candidate SB is a mirror of the current one */ bool is_mirror(RRSwitchBlock& cand) const; /* check if the candidate SB is a mirror of the current one */ bool is_mirrorable(RRSwitchBlock& cand) const; /* check if the candidate SB satisfy the basic requirements on being a mirror of the current one */ size_t get_hint_rotate_offset(RRSwitchBlock& cand) const; /* Determine an initial offset in rotating the candidate Switch Block to find a mirror matching*/ @@ -171,8 +172,8 @@ class RRSwitchBlock { public: /* Verilog writer */ char* gen_verilog_module_name() const; char* gen_verilog_instance_name() const; - char* gen_verilog_side_module_name(enum e_side side) const; - char* gen_verilog_side_instance_name(enum e_side side) const; + char* gen_verilog_side_module_name(enum e_side side, size_t seg_id) const; + char* gen_verilog_side_instance_name(enum e_side side, size_t seg_id) const; public: /* Mutators */ void set(const RRSwitchBlock& src); /* get a copy from a source */ void set_coordinator(size_t x, size_t y); @@ -242,15 +243,17 @@ class DeviceRRSwitchBlock { DeviceCoordinator get_switch_block_range() const; /* get the max coordinator of the switch block array */ RRSwitchBlock get_switch_block(DeviceCoordinator& coordinator) const; /* Get a rr switch block in the array with a coordinator */ RRSwitchBlock get_switch_block(size_t x, size_t y) const; /* Get a rr switch block in the array with a coordinator */ - size_t get_num_unique_module(enum e_side side) const; /* get the number of unique mirrors of switch blocks */ + size_t get_num_unique_module(enum e_side side, size_t seg_index) const; /* get the number of unique mirrors of switch blocks */ size_t get_num_unique_mirror() const; /* get the number of unique mirrors of switch blocks */ size_t get_num_rotatable_mirror() const; /* get the number of rotatable mirrors of switch blocks */ - RRSwitchBlock get_unique_side_module(size_t index, enum e_side side) const; /* Get a rr switch block which a unique mirror */ + RRSwitchBlock get_unique_side_module(size_t index, enum e_side side, size_t seg_id) const; /* Get a rr switch block which a unique mirror */ RRSwitchBlock get_unique_mirror(size_t index) const; /* Get a rr switch block which a unique mirror */ RRSwitchBlock get_unique_mirror(DeviceCoordinator& coordinator) const; /* Get a rr switch block which a unique mirror */ RRSwitchBlock get_rotatable_mirror(size_t index) const; /* Get a rr switch block which a unique mirror */ size_t get_max_num_sides() const; /* Get the maximum number of sides across the switch blocks */ - public: /* Mutators */ + size_t get_num_segments() const; /* Get the size of segment_ids */ + size_t get_segment_id(size_t index) const; /* Get a segment id */ + public: /* Mutators */ void set_rr_switch_block_num_reserved_conf_bits(DeviceCoordinator& coordinator, size_t num_reserved_conf_bits); /* TODO: TOBE DEPRECATED!!! conf_bits should be initialized when creating a switch block!!! */ void set_rr_switch_block_conf_bits_lsb(DeviceCoordinator& coordinator, size_t conf_bits_lsb); /* TODO: TOBE DEPRECATED!!! conf_bits should be initialized when creating a switch block!!! */ void set_rr_switch_block_conf_bits_msb(DeviceCoordinator& coordinator, size_t conf_bits_msb); /* TODO: TOBE DEPRECATED!!! conf_bits should be initialized when creating a switch block!!! */ @@ -261,27 +264,33 @@ 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_module(); /* Add a switch block to the array, which will automatically identify and update the lists of unique side module */ 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_unique_side_segment_module(DeviceCoordinator& coordinator, RRSwitchBlock& rr_sb, enum e_side side, size_t seg_id); void add_unique_side_module(DeviceCoordinator& coordinator, RRSwitchBlock& rr_sb, enum e_side side); + void build_segment_ids(); /* build a map of segment_ids */ void clear(); /* clean the content */ void clear_unique_module(); /* clean the content */ void clear_mirror(); /* clean the content */ void clear_rotatable_mirror(); /* clean the content */ + void clear_segment_ids(); private: /* Validators */ bool validate_coordinator(DeviceCoordinator& coordinator) const; /* Validate if the (x,y) is the range of this device */ bool validate_side(enum e_side side) const; /* validate if side is in the range of unique_side_module_ */ bool validate_unique_mirror_index(size_t index) const; /* Validate if the index in the range of unique_mirror vector*/ bool validate_rotatable_mirror_index(size_t index) const; /* Validate if the index in the range of unique_mirror vector*/ - bool validate_unique_module_index(size_t index, enum e_side side) const; /* Validate if the index in the range of unique_module vector */ + bool validate_unique_module_index(size_t index, enum e_side side, size_t seg_index) const; /* Validate if the index in the range of unique_module vector */ + bool validate_segment_index(size_t index) const; private: /* Internal Data */ std::vector< std::vector > rr_switch_block_; - std::vector< std::vector< std::vector > > rr_sb_unique_module_id_; /* A map from rr_switch_block to its unique_side_module [0..x][0..y][0..num_sides]*/ - std::vector > unique_module_; /* For each side of switch block, we identify a list of unique modules based on its connection. This is a matrix [0..num_sides-1][0..num_module], num_sides will the max number of sides of all the rr_switch_blocks */ + std::vector< std::vector< std::vector< std::vector > > > rr_sb_unique_module_id_; /* A map from rr_switch_block to its unique_side_module [0..x][0..y][0..num_sides][num_seg-1]*/ + std::vector< std::vector > > unique_module_; /* For each side of switch block, we identify a list of unique modules based on its connection. This is a matrix [0..num_sides-1][0..num_seg-1][0..num_module], num_sides will the max number of sides of all the rr_switch_blocks */ std::vector< std::vector > rr_switch_block_mirror_id_; /* A map from rr_switch_block to its unique mirror */ std::vector unique_mirror_; std::vector< std::vector > rr_switch_block_rotatable_mirror_id_; /* A map from rr_switch_block to its unique mirror */ std::vector rotatable_mirror_; + + std::vector segment_ids_; }; #endif diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/router/.fpga_x2p_router.c.swp b/vpr7_x2p/vpr/SRC/fpga_x2p/router/.fpga_x2p_router.c.swp deleted file mode 100644 index 0a269694f..000000000 Binary files a/vpr7_x2p/vpr/SRC/fpga_x2p/router/.fpga_x2p_router.c.swp and /dev/null differ diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_routing.c b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_routing.c index 0f5dd2f02..df2270a6f 100644 --- a/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_routing.c +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_routing.c @@ -1660,12 +1660,16 @@ int count_verilog_switch_box_reserved_conf_bits(t_sram_orgz_info* cur_sram_orgz_ /* Count the number of configuration bits of a Switch Box */ static size_t count_verilog_switch_box_side_reserved_conf_bits(t_sram_orgz_info* cur_sram_orgz_info, - RRSwitchBlock& rr_sb, enum e_side side) { + RRSwitchBlock& rr_sb, enum e_side side, size_t seg_id) { size_t num_reserved_conf_bits = 0; size_t temp_num_reserved_conf_bits = 0; Side side_manager(side); for (size_t itrack = 0; itrack < rr_sb.get_chan_width(side); ++itrack) { + /* Bypass unwanted segments */ + if (seg_id != rr_sb.get_chan_node_segment(side, itrack)) { + continue; + } switch (rr_sb.get_chan_node_direction(side, itrack)) { case OUT_PORT: temp_num_reserved_conf_bits = @@ -1697,9 +1701,13 @@ size_t count_verilog_switch_box_reserved_conf_bits(t_sram_orgz_info* cur_sram_or for (size_t side = 0; side < rr_sb.get_num_sides(); ++side) { Side side_manager(side); - temp_num_reserved_conf_bits = count_verilog_switch_box_side_reserved_conf_bits(cur_sram_orgz_info, rr_sb, side_manager.get_side()); - /* Always select the largest number of reserved conf_bits */ - num_reserved_conf_bits = std::max(num_reserved_conf_bits, temp_num_reserved_conf_bits); + /* get segment ids */ + std::vector seg_ids = rr_sb.get_chan(side_manager.get_side()).get_segment_ids(); + for (size_t iseg = 0; iseg < seg_ids.size(); ++iseg) { + temp_num_reserved_conf_bits = count_verilog_switch_box_side_reserved_conf_bits(cur_sram_orgz_info, rr_sb, side_manager.get_side(), seg_ids[iseg]); + /* Always select the largest number of reserved conf_bits */ + num_reserved_conf_bits = std::max(num_reserved_conf_bits, temp_num_reserved_conf_bits); + } } return num_reserved_conf_bits; @@ -1736,11 +1744,16 @@ int count_verilog_switch_box_conf_bits(t_sram_orgz_info* cur_sram_orgz_info, /* Count the number of configuration bits of a Switch Box */ static size_t count_verilog_switch_box_side_conf_bits(t_sram_orgz_info* cur_sram_orgz_info, - RRSwitchBlock& rr_sb, enum e_side side) { + RRSwitchBlock& rr_sb, + enum e_side side, size_t seg_id) { size_t num_conf_bits = 0; Side side_manager(side); for (size_t itrack = 0; itrack < rr_sb.get_chan_width(side); ++itrack) { + /* Bypass unwanted segments */ + if (seg_id != rr_sb.get_chan_node_segment(side, itrack)) { + continue; + } switch (rr_sb.get_chan_node_direction(side, itrack)) { case OUT_PORT: num_conf_bits += count_verilog_switch_box_interc_conf_bits(cur_sram_orgz_info, rr_sb, side, @@ -1767,7 +1780,11 @@ size_t count_verilog_switch_box_conf_bits(t_sram_orgz_info* cur_sram_orgz_info, for (size_t side = 0; side < rr_sb.get_num_sides(); ++side) { Side side_manager(side); - num_conf_bits += count_verilog_switch_box_side_conf_bits(cur_sram_orgz_info, rr_sb, side_manager.get_side()); + /* get segment ids */ + std::vector seg_ids = rr_sb.get_chan(side_manager.get_side()).get_segment_ids(); + for (size_t iseg = 0; iseg < seg_ids.size(); ++iseg) { + num_conf_bits += count_verilog_switch_box_side_conf_bits(cur_sram_orgz_info, rr_sb, side_manager.get_side(), seg_ids[iseg]); + } } return num_conf_bits; @@ -1809,6 +1826,7 @@ static void dump_verilog_routing_switch_box_unique_side_subckt_portmap(FILE* fp, RRSwitchBlock& rr_sb, enum e_side sb_side, + size_t seg_id, boolean dump_port_type) { /* Check file handler*/ if (NULL == fp) { @@ -1828,6 +1846,10 @@ void dump_verilog_routing_switch_box_unique_side_subckt_portmap(FILE* fp, DeviceCoordinator port_coordinator = rr_sb.get_side_block_coordinator(side_manager.get_side()); for (size_t itrack = 0; itrack < rr_sb.get_chan_width(side_manager.get_side()); ++itrack) { + /* Bypass unwanted segments */ + if (seg_id != rr_sb.get_chan_node_segment(side_manager.get_side(), itrack)) { + continue; + } switch (rr_sb.get_chan_node_direction(side_manager.get_side(), itrack)) { case OUT_PORT: /* if this is the specified side, we only consider output ports */ @@ -1920,7 +1942,8 @@ void dump_verilog_routing_switch_box_unique_side_subckt_portmap(FILE* fp, */ static void dump_verilog_routing_switch_box_unique_side_module(t_sram_orgz_info* cur_sram_orgz_info, - char* verilog_dir, char* subckt_dir, size_t module_id, + char* verilog_dir, char* subckt_dir, + size_t module_id, size_t seg_id, RRSwitchBlock& rr_sb, enum e_side side) { FILE* fp = NULL; char* fname = NULL; @@ -1932,9 +1955,9 @@ void dump_verilog_routing_switch_box_unique_side_module(t_sram_orgz_info* cur_sr } /* Count the number of configuration bits to be consumed by this Switch block */ - int num_conf_bits = count_verilog_switch_box_side_conf_bits(cur_sram_orgz_info, rr_sb, side); + int num_conf_bits = count_verilog_switch_box_side_conf_bits(cur_sram_orgz_info, rr_sb, side, seg_id); /* Count the number of reserved configuration bits to be consumed by this Switch block */ - int num_reserved_conf_bits = count_verilog_switch_box_side_reserved_conf_bits(cur_sram_orgz_info, rr_sb, side); + int num_reserved_conf_bits = count_verilog_switch_box_side_reserved_conf_bits(cur_sram_orgz_info, rr_sb, side, seg_id); /* Estimate the sram_verilog_model->cnt */ int cur_num_sram = get_sram_orgz_info_num_mem_bit(cur_sram_orgz_info); int esti_sram_cnt = cur_num_sram + num_conf_bits; @@ -1945,26 +1968,28 @@ void dump_verilog_routing_switch_box_unique_side_module(t_sram_orgz_info* cur_sr std::string file_description("Unique module for Switch Block side: "); file_description += side_manager.to_string(); + file_description += "seg"; + file_description += std::to_string(seg_id); /* Create file handler */ fp = verilog_create_one_subckt_file(subckt_dir, file_description.c_str(), - fname_prefix.c_str(), module_id, -1, &fname); + fname_prefix.c_str(), module_id, seg_id, &fname); /* Print preprocessing flags */ verilog_include_defines_preproc_file(fp, verilog_dir); /* Comment lines */ fprintf(fp, - "//----- Verilog Module of Unique Switch Box[%lu][%lu] at Side %s -----\n", - rr_sb.get_x(), rr_sb.get_y(), side_manager.to_string()); + "//----- Verilog Module of Unique Switch Box[%lu][%lu] at Side %s, Segment id: %lu -----\n", + rr_sb.get_x(), rr_sb.get_y(), side_manager.to_string(), seg_id); /* Print the definition of subckt*/ - fprintf(fp, "module %s ( \n", rr_sb.gen_verilog_side_module_name(side)); + fprintf(fp, "module %s ( \n", rr_sb.gen_verilog_side_module_name(side, seg_id)); /* dump global ports */ if (0 < dump_verilog_global_ports(fp, global_ports_head, TRUE)) { fprintf(fp, ",\n"); } - dump_verilog_routing_switch_box_unique_side_subckt_portmap(fp, rr_sb, side, TRUE); + dump_verilog_routing_switch_box_unique_side_subckt_portmap(fp, rr_sb, side, seg_id, TRUE); /* Put down configuration port */ /* output of each configuration bit */ @@ -2005,6 +2030,10 @@ void dump_verilog_routing_switch_box_unique_side_module(t_sram_orgz_info* cur_sr fprintf(fp, "//----- %s side Multiplexers -----\n", side_manager.to_string()); for (size_t itrack = 0; itrack < rr_sb.get_chan_width(side_manager.get_side()); ++itrack) { + /* Bypass unwanted segments */ + if (seg_id != rr_sb.get_chan_node_segment(side_manager.get_side(), itrack)) { + continue; + } assert((CHANX == rr_sb.get_chan_node(side_manager.get_side(), itrack)->type) ||(CHANY == rr_sb.get_chan_node(side_manager.get_side(), itrack)->type)); /* We care INC_DIRECTION tracks at this side*/ @@ -2175,61 +2204,70 @@ void dump_verilog_routing_switch_box_unique_module(t_sram_orgz_info* cur_sram_or /* Get the channel width on this side, if it is zero, we return */ if (0 == rr_sb.get_chan_width(side_manager.get_side())) { + fprintf(fp, "//----- %s side has zero channel width, module dump skipped -----\n", + side_manager.to_string()); continue; } - /* Count the number of configuration bits to be consumed by this Switch block */ - int side_num_conf_bits = count_verilog_switch_box_side_conf_bits(cur_sram_orgz_info, rr_sb, side_manager.get_side()); - /* Count the number of reserved configuration bits to be consumed by this Switch block */ - int side_num_reserved_conf_bits = count_verilog_switch_box_side_reserved_conf_bits(cur_sram_orgz_info, rr_sb, side_manager.get_side()); + /* get segment ids */ + std::vector seg_ids = rr_sb.get_chan(side_manager.get_side()).get_segment_ids(); + for (size_t iseg = 0; iseg < seg_ids.size(); ++iseg) { + fprintf(fp, "//----- %s side Submodule with Segment id: %lu -----\n", + side_manager.to_string(), seg_ids[iseg]); - /* Cache the sram counter */ - cur_sram_msb += side_num_conf_bits - 1; + /* Count the number of configuration bits to be consumed by this Switch block */ + int side_num_conf_bits = count_verilog_switch_box_side_conf_bits(cur_sram_orgz_info, rr_sb, side_manager.get_side(), seg_ids[iseg]); + /* Count the number of reserved configuration bits to be consumed by this Switch block */ + int side_num_reserved_conf_bits = count_verilog_switch_box_side_reserved_conf_bits(cur_sram_orgz_info, rr_sb, side_manager.get_side(), seg_ids[iseg]); - /* Instanciate the subckt*/ - fprintf(fp, - "%s %s ( \n", - rr_sb.gen_verilog_side_module_name(side_manager.get_side()), - rr_sb.gen_verilog_side_instance_name(side_manager.get_side())); - /* dump global ports */ - if (0 < dump_verilog_global_ports(fp, global_ports_head, FALSE)) { - fprintf(fp, ",\n"); + /* Cache the sram counter */ + cur_sram_msb += side_num_conf_bits - 1; + + /* Instanciate the subckt*/ + fprintf(fp, + "%s %s ( \n", + rr_sb.gen_verilog_side_module_name(side_manager.get_side(), seg_ids[iseg]), + rr_sb.gen_verilog_side_instance_name(side_manager.get_side(), seg_ids[iseg])); + /* dump global ports */ + if (0 < dump_verilog_global_ports(fp, global_ports_head, FALSE)) { + fprintf(fp, ",\n"); + } + + dump_verilog_routing_switch_box_unique_side_subckt_portmap(fp, rr_sb, side_manager.get_side(), seg_ids[iseg], FALSE); + + /* Put down configuration port */ + /* output of each configuration bit */ + /* Reserved sram ports */ + dump_verilog_reserved_sram_ports(fp, cur_sram_orgz_info, + 0, + side_num_reserved_conf_bits - 1, + VERILOG_PORT_INPUT); + if (0 < side_num_reserved_conf_bits) { + fprintf(fp, ",\n"); + } + /* Normal sram ports */ + dump_verilog_sram_ports(fp, cur_sram_orgz_info, + cur_sram_lsb, + cur_sram_msb, + VERILOG_PORT_INPUT); + + /* Dump ports only visible during formal verification*/ + if (0 < num_conf_bits) { + fprintf(fp, "\n"); + fprintf(fp, "`ifdef %s\n", verilog_formal_verification_preproc_flag); + fprintf(fp, ",\n"); + dump_verilog_formal_verification_sram_ports(fp, cur_sram_orgz_info, + cur_sram_lsb, + cur_sram_msb, + VERILOG_PORT_OUTPUT); + fprintf(fp, "\n"); + fprintf(fp, "`endif\n"); + } + fprintf(fp, "); \n"); + + /* Update sram_lsb */ + cur_sram_lsb = cur_sram_msb + 1; } - - dump_verilog_routing_switch_box_unique_side_subckt_portmap(fp, rr_sb, side_manager.get_side(), FALSE); - - /* Put down configuration port */ - /* output of each configuration bit */ - /* Reserved sram ports */ - dump_verilog_reserved_sram_ports(fp, cur_sram_orgz_info, - 0, - side_num_reserved_conf_bits - 1, - VERILOG_PORT_INPUT); - if (0 < side_num_reserved_conf_bits) { - fprintf(fp, ",\n"); - } - /* Normal sram ports */ - dump_verilog_sram_ports(fp, cur_sram_orgz_info, - cur_sram_lsb, - cur_sram_msb, - VERILOG_PORT_INPUT); - - /* Dump ports only visible during formal verification*/ - if (0 < num_conf_bits) { - fprintf(fp, "\n"); - fprintf(fp, "`ifdef %s\n", verilog_formal_verification_preproc_flag); - fprintf(fp, ",\n"); - dump_verilog_formal_verification_sram_ports(fp, cur_sram_orgz_info, - cur_sram_lsb, - cur_sram_msb, - VERILOG_PORT_OUTPUT); - fprintf(fp, "\n"); - fprintf(fp, "`endif\n"); - } - fprintf(fp, "); \n"); - - /* Update sram_lsb */ - cur_sram_lsb = cur_sram_msb + 1; } fprintf(fp, "endmodule\n"); @@ -3409,9 +3447,12 @@ void dump_verilog_routing_resources(t_sram_orgz_info* cur_sram_orgz_info, /* Output unique side modules */ for (size_t side = 0; side < device_rr_switch_block.get_max_num_sides(); ++side) { Side side_manager(side); - for (size_t isb = 0; isb < device_rr_switch_block.get_num_unique_module(side_manager.get_side()); ++isb) { - RRSwitchBlock unique_mirror = device_rr_switch_block.get_unique_side_module(isb, side_manager.get_side()); - dump_verilog_routing_switch_box_unique_side_module(cur_sram_orgz_info, verilog_dir, subckt_dir, isb, unique_mirror, side_manager.get_side()); + for (size_t iseg = 0; iseg < device_rr_switch_block.get_num_segments(); ++iseg) { + for (size_t isb = 0; isb < device_rr_switch_block.get_num_unique_module(side_manager.get_side(), iseg); ++isb) { + RRSwitchBlock unique_mirror = device_rr_switch_block.get_unique_side_module(isb, side_manager.get_side(), iseg); + size_t seg_id = device_rr_switch_block.get_segment_id(iseg); + dump_verilog_routing_switch_box_unique_side_module(cur_sram_orgz_info, verilog_dir, subckt_dir, isb, seg_id, unique_mirror, side_manager.get_side()); + } } }