debugging SwitchBlock rotating

This commit is contained in:
tangxifan 2019-05-24 23:10:30 -06:00
parent 9adc2945c8
commit ae0248fbc6
6 changed files with 75 additions and 10 deletions

View File

@ -3129,7 +3129,6 @@ void spice_backannotate_vpr_post_route_info(t_det_routing_arch RoutingArch,
/* Build Array for each Switch block and Connection block */ /* Build Array for each Switch block and Connection block */
vpr_printf(TIO_MESSAGE_INFO, "Collecting detailed information for each Switch block...\n"); vpr_printf(TIO_MESSAGE_INFO, "Collecting detailed information for each Switch block...\n");
alloc_and_build_switch_blocks_info(RoutingArch, num_rr_nodes, rr_node, rr_node_indices); alloc_and_build_switch_blocks_info(RoutingArch, num_rr_nodes, rr_node, rr_node_indices);
device_rr_switch_block = build_device_rr_switch_blocks(num_rr_nodes, rr_node, rr_node_indices);
vpr_printf(TIO_MESSAGE_INFO, "Collecting detailed information for each to Connection block...\n"); vpr_printf(TIO_MESSAGE_INFO, "Collecting detailed information for each to Connection block...\n");
alloc_and_build_connection_blocks_info(RoutingArch, num_rr_nodes, rr_node, rr_node_indices); alloc_and_build_connection_blocks_info(RoutingArch, num_rr_nodes, rr_node, rr_node_indices);

View File

@ -1400,6 +1400,7 @@ void fpga_x2p_setup(t_vpr_setup vpr_setup,
/* Assign Gobal variable: build the Routing Resource Channels */ /* Assign Gobal variable: build the Routing Resource Channels */
device_rr_chan = build_device_rr_chan(num_rr_nodes, rr_node, rr_node_indices, Arch->num_segments, rr_indexed_data); device_rr_chan = build_device_rr_chan(num_rr_nodes, rr_node, rr_node_indices, Arch->num_segments, rr_indexed_data);
device_rr_switch_block = build_device_rr_switch_blocks(num_rr_nodes, rr_node, rr_node_indices);
/* Rotatable will be done in the next step /* Rotatable will be done in the next step
identify_rotatable_switch_blocks(); identify_rotatable_switch_blocks();

View File

@ -1037,6 +1037,7 @@ RRSwitchBlock build_rr_switch_block(int sb_x, int sb_y,
rr_switch_block.clear_ipin_nodes(side_manager.get_side()); rr_switch_block.clear_ipin_nodes(side_manager.get_side());
/* Free */ /* Free */
my_free(chan_rr_node);
temp_num_opin_rr_nodes[0] = 0; temp_num_opin_rr_nodes[0] = 0;
my_free(temp_opin_rr_node[0]); my_free(temp_opin_rr_node[0]);
temp_num_opin_rr_nodes[1] = 0; temp_num_opin_rr_nodes[1] = 0;
@ -1082,6 +1083,10 @@ DeviceRRSwitchBlock build_device_rr_switch_blocks(int LL_num_rr_nodes,
"Detect %d independent switch blocks from %d switch blocks.\n", "Detect %d independent switch blocks from %d switch blocks.\n",
LL_device_rr_switch_block.get_num_unique_mirror(), (nx + 1) * (ny + 1) ); LL_device_rr_switch_block.get_num_unique_mirror(), (nx + 1) * (ny + 1) );
vpr_printf(TIO_MESSAGE_INFO,
"Detect %d rotatable unique switch blocks from %d switch blocks.\n",
LL_device_rr_switch_block.get_num_rotatable_mirror(), (nx + 1) * (ny + 1) );
return LL_device_rr_switch_block; return LL_device_rr_switch_block;
} }

View File

@ -336,6 +336,16 @@ size_t RRSwitchBlock::get_chan_width(enum e_side side) const {
return chan_node_[side_manager.to_size_t()].size(); return chan_node_[side_manager.to_size_t()].size();
} }
/* Get the maximum number of routing tracks on all sides */
size_t RRSwitchBlock::get_max_chan_width() const {
size_t max_chan_width = 0;
for (size_t side = 0; side < get_num_sides(); ++side) {
Side side_manager(side);
max_chan_width = std::max(max_chan_width, get_chan_width(side_manager.get_side()));
}
return max_chan_width;
}
/* Get the direction of a rr_node at a given side and track_id */ /* Get the direction of a rr_node at a given side and track_id */
enum PORTS RRSwitchBlock::get_chan_node_direction(enum e_side side, size_t track_id) const { enum PORTS RRSwitchBlock::get_chan_node_direction(enum e_side side, size_t track_id) const {
Side side_manager(side); Side side_manager(side);
@ -783,12 +793,12 @@ void RRSwitchBlock::rotate_chan_node(size_t offset) {
size_t rotate_begin = 0; size_t rotate_begin = 0;
size_t rotate_end = 0; size_t rotate_end = 0;
/* Partition the chan nodes on this side, depending on its length */ /* Partition the chan nodes on this side, depending on its length */
/* skip this side if there is no nodes */
if (0 == get_chan_width(side_manager.get_side())) {
continue;
}
for (size_t inode = 0; inode < get_chan_width(side_manager.get_side()) - 1; ++inode) { for (size_t inode = 0; inode < get_chan_width(side_manager.get_side()) - 1; ++inode) {
if ( ( (chan_node_[side][inode]->xlow != chan_node_[side][inode + 1]->xlow) if ( ( abs(chan_node_[side][inode]->yhigh - chan_node_[side][inode]->ylow + chan_node_[side][inode]->xhigh - chan_node_[side][inode]->xlow) != abs(chan_node_[side][inode + 1]->yhigh - chan_node_[side][inode + 1]->ylow + chan_node_[side][inode + 1]->xhigh - chan_node_[side][inode + 1]->xlow))
|| (chan_node_[side][inode]->ylow != chan_node_[side][inode + 1]->ylow)
|| (chan_node_[side][inode]->xhigh != chan_node_[side][inode + 1]->xhigh)
|| (chan_node_[side][inode]->yhigh != chan_node_[side][inode + 1]->yhigh)
|| (chan_node_direction_[side][inode] != chan_node_direction_[side][inode + 1]))
|| ( inode == get_chan_width(side_manager.get_side()) - 2) ) { || ( inode == get_chan_width(side_manager.get_side()) - 2) ) {
/* Record the upper bound */ /* Record the upper bound */
if ( inode == get_chan_width(side_manager.get_side()) - 2) { if ( inode == get_chan_width(side_manager.get_side()) - 2) {
@ -797,7 +807,13 @@ void RRSwitchBlock::rotate_chan_node(size_t offset) {
rotate_end = inode; rotate_end = inode;
} }
/* Make sure offset is in range */ /* Make sure offset is in range */
assert (offset < rotate_end - rotate_begin); /* skip this side if there is no nodes */
if (0 >= rotate_end - rotate_begin) {
/* Update the lower bound */
rotate_begin = inode + 1;
continue;
}
assert(offset < rotate_end - rotate_begin + 1);
/* Find a group split, rotate */ /* Find a group split, rotate */
std::rotate(chan_node_.begin() + rotate_begin, std::rotate(chan_node_.begin() + rotate_begin,
chan_node_.begin() + rotate_begin + offset, chan_node_.begin() + rotate_begin + offset,
@ -822,6 +838,10 @@ void RRSwitchBlock::rotate_opin_node(size_t offset) {
Side side_manager(side); Side side_manager(side);
size_t rotate_begin = 0; size_t rotate_begin = 0;
size_t rotate_end = 0; size_t rotate_end = 0;
/* skip this side if there is no nodes */
if (0 == get_num_opin_nodes(side_manager.get_side())) {
continue;
}
/* Partition the opin nodes on this side, depending on grids */ /* Partition the opin nodes on this side, depending on grids */
for (size_t inode = 0; inode < get_num_opin_nodes(side_manager.get_side()) - 1; ++inode) { for (size_t inode = 0; inode < get_num_opin_nodes(side_manager.get_side()) - 1; ++inode) {
if ( ( (opin_node_[side][inode]->xlow != opin_node_[side][inode + 1]->xlow) if ( ( (opin_node_[side][inode]->xlow != opin_node_[side][inode + 1]->xlow)
@ -836,8 +856,14 @@ void RRSwitchBlock::rotate_opin_node(size_t offset) {
} else { } else {
rotate_end = inode; rotate_end = inode;
} }
/* skip this side if there is no nodes */
if (0 >= rotate_end - rotate_begin) {
/* Update the lower bound */
rotate_begin = inode + 1;
continue;
}
/* Make sure offset is in range */ /* Make sure offset is in range */
assert (offset < rotate_end - rotate_begin); assert (offset < rotate_end - rotate_begin + 1);
/* Find a group split, rotate */ /* Find a group split, rotate */
std::rotate(opin_node_.begin() + rotate_begin, std::rotate(opin_node_.begin() + rotate_begin,
opin_node_.begin() + rotate_begin + offset, opin_node_.begin() + rotate_begin + offset,
@ -1153,9 +1179,12 @@ void DeviceRRSwitchBlock::set_rr_switch_block_conf_bits_msb(DeviceCoordinator& c
void DeviceRRSwitchBlock::reserve(DeviceCoordinator& coordinator) { void DeviceRRSwitchBlock::reserve(DeviceCoordinator& coordinator) {
rr_switch_block_.resize(coordinator.get_x()); rr_switch_block_.resize(coordinator.get_x());
rr_switch_block_mirror_id_.resize(coordinator.get_x()); rr_switch_block_mirror_id_.resize(coordinator.get_x());
rr_switch_block_rotatable_mirror_id_.resize(coordinator.get_x());
for (size_t x = 0; x < coordinator.get_x(); ++x) { for (size_t x = 0; x < coordinator.get_x(); ++x) {
rr_switch_block_[x].resize(coordinator.get_y()); rr_switch_block_[x].resize(coordinator.get_y());
rr_switch_block_mirror_id_[x].resize(coordinator.get_y()); rr_switch_block_mirror_id_[x].resize(coordinator.get_y());
rr_switch_block_rotatable_mirror_id_[x].resize(coordinator.get_y());
} }
return; return;
} }
@ -1165,11 +1194,13 @@ void DeviceRRSwitchBlock::resize_upon_need(DeviceCoordinator& coordinator) {
if (coordinator.get_x() + 1 > rr_switch_block_.capacity()) { if (coordinator.get_x() + 1 > rr_switch_block_.capacity()) {
rr_switch_block_.resize(coordinator.get_x()); rr_switch_block_.resize(coordinator.get_x());
rr_switch_block_mirror_id_.resize(coordinator.get_x()); rr_switch_block_mirror_id_.resize(coordinator.get_x());
rr_switch_block_rotatable_mirror_id_.resize(coordinator.get_x());
} }
if (coordinator.get_y() + 1 > rr_switch_block_[coordinator.get_x()].capacity()) { if (coordinator.get_y() + 1 > rr_switch_block_[coordinator.get_x()].capacity()) {
rr_switch_block_[coordinator.get_x()].resize(coordinator.get_y()); 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_mirror_id_[coordinator.get_x()].resize(coordinator.get_y());
rr_switch_block_rotatable_mirror_id_[coordinator.get_x()].resize(coordinator.get_y());
} }
return; return;
@ -1179,6 +1210,7 @@ void DeviceRRSwitchBlock::resize_upon_need(DeviceCoordinator& coordinator) {
void DeviceRRSwitchBlock::add_rr_switch_block(DeviceCoordinator& coordinator, void DeviceRRSwitchBlock::add_rr_switch_block(DeviceCoordinator& coordinator,
RRSwitchBlock& rr_switch_block) { RRSwitchBlock& rr_switch_block) {
bool is_unique_mirror = true; bool is_unique_mirror = true;
bool is_rotatable_mirror = true;
/* Resize upon needs*/ /* Resize upon needs*/
resize_upon_need(coordinator); resize_upon_need(coordinator);
@ -1203,7 +1235,33 @@ void DeviceRRSwitchBlock::add_rr_switch_block(DeviceCoordinator& coordinator,
rr_switch_block_mirror_id_[coordinator.get_x()][coordinator.get_y()] = unique_mirror_.size() - 1; rr_switch_block_mirror_id_[coordinator.get_x()][coordinator.get_y()] = unique_mirror_.size() - 1;
} }
/* TODO: add rotatable mirror support */ /* add rotatable mirror support */
for (size_t mirror_id = 0; mirror_id < get_num_rotatable_mirror(); ++mirror_id) {
RRSwitchBlock rotate_mirror = rr_switch_block;
/* 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
*/
for (size_t offset = 0; offset < rr_switch_block.get_max_chan_width(); ++offset) {
rotate_mirror.rotate(1);
if (true == get_switch_block(unique_mirror_[mirror_id]).is_mirror(rotate_mirror)) {
/* This is a mirror, raise the flag and we finish */
is_rotatable_mirror = false;
/* Record the id of unique mirror */
rr_switch_block_rotatable_mirror_id_[coordinator.get_x()][coordinator.get_y()] = mirror_id;
break;
}
}
if (false == is_rotatable_mirror) {
break;
}
}
/* Add to list if this is a unique mirror*/
if (true == is_rotatable_mirror) {
rotatable_mirror_.push_back(coordinator);
/* Record the id of unique mirror */
rr_switch_block_rotatable_mirror_id_[coordinator.get_x()][coordinator.get_y()] = rotatable_mirror_.size() - 1;
}
return; return;
} }

View File

@ -126,6 +126,7 @@ class RRSwitchBlock {
DeviceCoordinator get_coordinator() const; /* Get the number of sides of this SB */ DeviceCoordinator get_coordinator() const; /* Get the number of sides of this SB */
size_t get_num_sides() const; /* Get the number of sides of this SB */ size_t get_num_sides() const; /* Get the number of sides of this SB */
size_t get_chan_width(enum e_side side) const; /* Get the number of routing tracks on a side */ 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 */ 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 */
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 */ 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_num_ipin_nodes(enum e_side side) const; /* Get the number of IPIN rr_nodes on a side */ size_t get_num_ipin_nodes(enum e_side side) const; /* Get the number of IPIN rr_nodes on a side */
@ -223,6 +224,7 @@ class DeviceRRSwitchBlock {
private: /* Internal Data */ private: /* Internal Data */
std::vector< std::vector<RRSwitchBlock> > rr_switch_block_; std::vector< std::vector<RRSwitchBlock> > rr_switch_block_;
std::vector< std::vector<size_t> > rr_switch_block_mirror_id_; /* A map from rr_switch_block to its unique mirror */ std::vector< std::vector<size_t> > rr_switch_block_mirror_id_; /* A map from rr_switch_block to its unique mirror */
std::vector< std::vector<size_t> > rr_switch_block_rotatable_mirror_id_; /* A map from rr_switch_block to its unique mirror */
std::vector<DeviceCoordinator> unique_mirror_; std::vector<DeviceCoordinator> unique_mirror_;
std::vector<DeviceCoordinator> rotatable_mirror_; std::vector<DeviceCoordinator> rotatable_mirror_;
}; };

View File

@ -39,6 +39,6 @@ rm -rf $verilog_output_dirpath/$verilog_output_dirname
#valgrind #valgrind
./vpr $arch_xml_file $blif_file --full_stats --nodisp --activity_file $act_file --fpga_verilog --fpga_verilog_dir $verilog_output_dirpath/$verilog_output_dirname --fpga_x2p_rename_illegal_port --fpga_bitstream_generator --fpga_verilog_print_top_testbench --fpga_verilog_print_input_blif_testbench --fpga_verilog_include_timing --fpga_verilog_include_signal_init --fpga_verilog_print_modelsim_autodeck $modelsim_ini_file --fpga_verilog_print_formal_verification_top_netlist --fpga_verilog_print_autocheck_top_testbench $verilog_reference --fpga_verilog_print_user_defined_template --route_chan_width $vpr_route_chan_width --fpga_verilog_print_sdc_pnr --fpga_verilog_print_sdc_analysis --fpga_verilog_print_report_timing_tcl ./vpr $arch_xml_file $blif_file --full_stats --nodisp --activity_file $act_file --fpga_verilog --fpga_verilog_dir $verilog_output_dirpath/$verilog_output_dirname --fpga_x2p_rename_illegal_port --fpga_bitstream_generator --fpga_verilog_print_top_testbench --fpga_verilog_print_input_blif_testbench --fpga_verilog_include_timing --fpga_verilog_include_signal_init --fpga_verilog_print_modelsim_autodeck $modelsim_ini_file --fpga_verilog_print_formal_verification_top_netlist --fpga_verilog_print_autocheck_top_testbench $verilog_reference --fpga_verilog_print_user_defined_template --route_chan_width $vpr_route_chan_width --fpga_verilog_print_sdc_pnr --fpga_verilog_print_sdc_analysis --fpga_verilog_print_report_timing_tcl
./vpr $arch_xml_file $blif_file --full_stats --nodisp --activity_file $act_file --fpga_verilog --fpga_verilog_dir $verilog_output_dirpath/$verilog_output_dirname\_compact --fpga_x2p_rename_illegal_port --fpga_bitstream_generator --fpga_verilog_print_top_testbench --fpga_verilog_print_input_blif_testbench --fpga_verilog_include_timing --fpga_verilog_include_signal_init --fpga_verilog_print_modelsim_autodeck $modelsim_ini_file --fpga_verilog_print_formal_verification_top_netlist --fpga_verilog_print_autocheck_top_testbench $verilog_reference --fpga_verilog_print_user_defined_template --route_chan_width $vpr_route_chan_width --fpga_x2p_compact_routing_hierarchy --fpga_verilog_print_sdc_pnr --fpga_verilog_print_sdc_analysis --fpga_verilog_print_report_timing_tcl #./vpr $arch_xml_file $blif_file --full_stats --nodisp --activity_file $act_file --fpga_verilog --fpga_verilog_dir $verilog_output_dirpath/$verilog_output_dirname\_compact --fpga_x2p_rename_illegal_port --fpga_bitstream_generator --fpga_verilog_print_top_testbench --fpga_verilog_print_input_blif_testbench --fpga_verilog_include_timing --fpga_verilog_include_signal_init --fpga_verilog_print_modelsim_autodeck $modelsim_ini_file --fpga_verilog_print_formal_verification_top_netlist --fpga_verilog_print_autocheck_top_testbench $verilog_reference --fpga_verilog_print_user_defined_template --route_chan_width $vpr_route_chan_width --fpga_x2p_compact_routing_hierarchy --fpga_verilog_print_sdc_pnr --fpga_verilog_print_sdc_analysis --fpga_verilog_print_report_timing_tcl