From af91fca1e0de913fcba88e65d29650b4b17021ec Mon Sep 17 00:00:00 2001 From: tangxifan Date: Tue, 28 May 2019 14:52:44 -0600 Subject: [PATCH] add rr_blocks XML writer to help debugging Switch Block Rotation --- .../fpga_x2p/base/fpga_x2p_unique_routing.c | 75 ++++++++---- vpr7_x2p/vpr/SRC/fpga_x2p/base/rr_blocks.cpp | 12 +- .../vpr/SRC/fpga_x2p/base/write_rr_blocks.cpp | 111 ++++++++++++++++++ .../vpr/SRC/fpga_x2p/base/write_rr_blocks.h | 8 ++ 4 files changed, 177 insertions(+), 29 deletions(-) create mode 100644 vpr7_x2p/vpr/SRC/fpga_x2p/base/write_rr_blocks.cpp create mode 100644 vpr7_x2p/vpr/SRC/fpga_x2p/base/write_rr_blocks.h 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 9b27f7aab..ab98aca19 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 @@ -32,6 +32,7 @@ #include "fpga_x2p_globals.h" #include "fpga_x2p_utils.h" #include "fpga_x2p_backannotate_utils.h" +#include "write_rr_blocks.h" #include "fpga_x2p_unique_routing.h" /***** subroutines declaration *****/ @@ -820,7 +821,7 @@ DeviceRRChan build_device_rr_chan(int LL_num_rr_nodes, t_rr_node* LL_rr_node, * For channels chanX with DEC_DIRECTION on the right side, they should be marked as inputs */ static -RRSwitchBlock build_rr_switch_block(DeviceCoordinator device_range, +RRSwitchBlock build_rr_switch_block(DeviceCoordinator& device_range, size_t sb_x, size_t sb_y, int LL_num_rr_nodes, t_rr_node* LL_rr_node, t_ivec*** LL_rr_node_indices, int num_segments, @@ -1044,6 +1045,7 @@ RRSwitchBlock rotate_rr_switch_block_for_mirror(DeviceCoordinator& device_range, const RRSwitchBlock& rr_switch_block) { RRSwitchBlock rotated_rr_switch_block; rotated_rr_switch_block.set(rr_switch_block); + size_t Fco_offset = 1; /* For the 4 Switch Blocks at the four corners */ /* 1. BOTTOM-LEFT corner: @@ -1103,10 +1105,22 @@ RRSwitchBlock rotate_rr_switch_block_for_mirror(DeviceCoordinator& device_range, * swap the chan_node between TOP and BOTTOM, */ if (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.reverse_opin_node(TOP); - rotated_rr_switch_block.reverse_opin_node(BOTTOM); + + /* For RIGHT SIDE: X-channel in INC_DIRECTION, rotate by an offset of its x-coordinator */ + rotated_rr_switch_block.rotate_side_chan_node_by_direction(RIGHT, INC_DIRECTION, Fco_offset * (rotated_rr_switch_block.get_x() - 1)); + /* Rotate the same nodes on the opposite side */ + rotated_rr_switch_block.rotate_side_chan_node_by_direction(LEFT, INC_DIRECTION, Fco_offset * (rotated_rr_switch_block.get_x() - 1)); + + /* For LEFT SIDE: X-channel in DEC_DIRECTION, rotate by an offset of its x-coordinator */ + rotated_rr_switch_block.counter_rotate_side_chan_node_by_direction(LEFT, DEC_DIRECTION, Fco_offset * (rotated_rr_switch_block.get_x() - 1)); + /* Rotate the same nodes on the opposite side */ + rotated_rr_switch_block.counter_rotate_side_chan_node_by_direction(RIGHT, DEC_DIRECTION, Fco_offset * (rotated_rr_switch_block.get_x() - 1)); + + //rotated_rr_switch_block.swap_opin_node(TOP, BOTTOM); + //rotated_rr_switch_block.swap_chan_node(TOP, BOTTOM); + //rotated_rr_switch_block.reverse_opin_node(TOP); + //rotated_rr_switch_block.reverse_opin_node(BOTTOM); + return rotated_rr_switch_block; } /* 3. RIGHT side: @@ -1114,10 +1128,22 @@ 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() ) { - rotated_rr_switch_block.swap_opin_node(LEFT, RIGHT); - rotated_rr_switch_block.swap_chan_node(LEFT, RIGHT); - rotated_rr_switch_block.reverse_opin_node(LEFT); - rotated_rr_switch_block.reverse_opin_node(RIGHT); + + /* For TOP SIDE: Y-channel in INC_DIRECTION, rotate by an offset of its y-coordinator */ + rotated_rr_switch_block.rotate_side_chan_node_by_direction(TOP, INC_DIRECTION, Fco_offset * (rotated_rr_switch_block.get_y() - 1)); + /* Rotate the same nodes on the opposite side */ + rotated_rr_switch_block.rotate_side_chan_node_by_direction(BOTTOM, INC_DIRECTION, Fco_offset * (rotated_rr_switch_block.get_y() - 1)); + + /* For BOTTOM SIDE: Y-channel in DEC_DIRECTION, rotate by an offset of its y-coordinator */ + rotated_rr_switch_block.counter_rotate_side_chan_node_by_direction(BOTTOM, DEC_DIRECTION, Fco_offset * (rotated_rr_switch_block.get_y() - 1)); + /* Rotate the same nodes on the opposite side */ + rotated_rr_switch_block.counter_rotate_side_chan_node_by_direction(TOP, DEC_DIRECTION, Fco_offset * (rotated_rr_switch_block.get_y() - 1)); + + //rotated_rr_switch_block.swap_opin_node(LEFT, RIGHT); + //rotated_rr_switch_block.swap_chan_node(LEFT, RIGHT); + //rotated_rr_switch_block.reverse_opin_node(LEFT); + //rotated_rr_switch_block.reverse_opin_node(RIGHT); + return rotated_rr_switch_block; } /* 4. LEFT side: @@ -1136,35 +1162,36 @@ RRSwitchBlock rotate_rr_switch_block_for_mirror(DeviceCoordinator& device_range, /* Reach here, it means we have a SB at the center region */ /* For TOP SIDE: Y-channel in INC_DIRECTION, rotate by an offset of its y-coordinator */ if (1 < rotated_rr_switch_block.get_y()) { - rotated_rr_switch_block.rotate_side_chan_node_by_direction(TOP, INC_DIRECTION, rotated_rr_switch_block.get_y() - 1); + rotated_rr_switch_block.rotate_side_chan_node_by_direction(TOP, INC_DIRECTION, Fco_offset * (rotated_rr_switch_block.get_y() - 1)); /* Rotate the same nodes on the opposite side */ - rotated_rr_switch_block.rotate_side_chan_node_by_direction(BOTTOM, INC_DIRECTION, rotated_rr_switch_block.get_y() - 1); + rotated_rr_switch_block.rotate_side_chan_node_by_direction(BOTTOM, INC_DIRECTION, Fco_offset * (rotated_rr_switch_block.get_y() - 1)); } /* For RIGHT SIDE: X-channel in INC_DIRECTION, rotate by an offset of its x-coordinator */ if (1 < rotated_rr_switch_block.get_x()) { - rotated_rr_switch_block.rotate_side_chan_node_by_direction(RIGHT, INC_DIRECTION, rotated_rr_switch_block.get_x() - 1); + rotated_rr_switch_block.rotate_side_chan_node_by_direction(RIGHT, INC_DIRECTION, Fco_offset * (rotated_rr_switch_block.get_x() - 1)); /* Rotate the same nodes on the opposite side */ - rotated_rr_switch_block.rotate_side_chan_node_by_direction(LEFT, INC_DIRECTION, rotated_rr_switch_block.get_x() - 1); + rotated_rr_switch_block.rotate_side_chan_node_by_direction(LEFT, INC_DIRECTION, Fco_offset * (rotated_rr_switch_block.get_x() - 1)); } /* 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()) { - rotated_rr_switch_block.counter_rotate_side_chan_node_by_direction(BOTTOM, DEC_DIRECTION, rotated_rr_switch_block.get_y() - 1); + if ( 1 < rotated_rr_switch_block.get_y()) { + rotated_rr_switch_block.counter_rotate_side_chan_node_by_direction(BOTTOM, DEC_DIRECTION, Fco_offset * (rotated_rr_switch_block.get_y() - 1)); /* Rotate the same nodes on the opposite side */ - rotated_rr_switch_block.counter_rotate_side_chan_node_by_direction(TOP, DEC_DIRECTION, rotated_rr_switch_block.get_y() - 1); + rotated_rr_switch_block.counter_rotate_side_chan_node_by_direction(TOP, DEC_DIRECTION, Fco_offset * (rotated_rr_switch_block.get_y() - 1)); } /* 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()) { - rotated_rr_switch_block.counter_rotate_side_chan_node_by_direction(LEFT, DEC_DIRECTION, rotated_rr_switch_block.get_x() - 1); + if ( 1 < rotated_rr_switch_block.get_x()) { + rotated_rr_switch_block.counter_rotate_side_chan_node_by_direction(LEFT, DEC_DIRECTION, Fco_offset * (rotated_rr_switch_block.get_x() - 1)); /* Rotate the same nodes on the opposite side */ - rotated_rr_switch_block.counter_rotate_side_chan_node_by_direction(RIGHT, DEC_DIRECTION, rotated_rr_switch_block.get_x() - 1); + rotated_rr_switch_block.counter_rotate_side_chan_node_by_direction(RIGHT, DEC_DIRECTION, Fco_offset * (rotated_rr_switch_block.get_x() - 1)); } return rotated_rr_switch_block; } + /* Build a list of Switch blocks, each of which contains a collection of rr_nodes * We will maintain a list of unique switch blocks, which will be outputted as a Verilog module * Each switch block in the FPGA fabric will be an instance of these modules. @@ -1184,7 +1211,7 @@ DeviceRRSwitchBlock build_device_rr_switch_blocks(int LL_num_rr_nodes, t_rr_node /* For each switch block, determine the size of array */ for (size_t ix = 0; ix <= sb_range.get_x(); ++ix) { for (size_t iy = 0; iy <= sb_range.get_y(); ++iy) { - RRSwitchBlock rr_sb = build_rr_switch_block(sb_range, ix, iy, + RRSwitchBlock rr_sb = 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); @@ -1206,11 +1233,7 @@ DeviceRRSwitchBlock build_device_rr_switch_blocks(int LL_num_rr_nodes, t_rr_node for (size_t ix = 0; ix <= sb_range.get_x(); ++ix) { for (size_t iy = 0; iy <= sb_range.get_y(); ++iy) { - //RRSwitchBlock rr_sb = LL_device_rr_switch_block.get_switch_block(ix, iy); - RRSwitchBlock rr_sb = 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 rr_sb = LL_device_rr_switch_block.get_switch_block(ix, iy); RRSwitchBlock rotated_rr_sb = rotate_rr_switch_block_for_mirror(sb_range, rr_sb); DeviceCoordinator sb_coordinator = rr_sb.get_coordinator(); LL_device_rr_switch_block.add_rotatable_mirror(sb_coordinator, rotated_rr_sb); @@ -1223,6 +1246,8 @@ DeviceRRSwitchBlock build_device_rr_switch_blocks(int LL_num_rr_nodes, t_rr_node "Detect %d rotatable unique switch blocks from %d switch blocks.\n", LL_device_rr_switch_block.get_num_rotatable_mirror(), (nx + 1) * (ny + 1) ); + write_device_rr_switch_block_to_xml(LL_device_rr_switch_block); + return LL_device_rr_switch_block; } 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 c67e746e1..d1242c4e6 100644 --- a/vpr7_x2p/vpr/SRC/fpga_x2p/base/rr_blocks.cpp +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/base/rr_blocks.cpp @@ -203,7 +203,7 @@ void RRChan::rotate_by_node_direction(enum e_direction node_direction, size_t of std::vector 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)) ) { + && (seg_ids[iseg] == (size_t)get_node_segment(inode)) ) { nodes.push_back(get_node(inode)); node_segments.push_back(get_node_segment(inode)); } @@ -219,7 +219,7 @@ void RRChan::rotate_by_node_direction(enum e_direction node_direction, size_t of /* back-annotate to to the original chan nodes*/ for (size_t inode = 0; inode < get_chan_width(); ++inode) { if ( (node_direction == get_node(inode)->direction) - && (seg_ids[iseg] == get_node_segment(inode)) ) { + && (seg_ids[iseg] == (size_t)get_node_segment(inode)) ) { nodes_[inode] = nodes.front(); node_segments_[inode] = node_segments.front(); /* pop up temp vectors */ @@ -255,7 +255,7 @@ void RRChan::counter_rotate_by_node_direction(enum e_direction node_direction, s std::vector 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)) ) { + && (seg_ids[iseg] == (size_t)get_node_segment(inode)) ) { nodes.push_back(get_node(inode)); node_segments.push_back(get_node_segment(inode)); } @@ -271,7 +271,7 @@ void RRChan::counter_rotate_by_node_direction(enum e_direction node_direction, s /* back-annotate to to the original chan nodes*/ for (size_t inode = 0; inode < get_chan_width(); ++inode) { if ( (node_direction == get_node(inode)->direction) - && (seg_ids[iseg] == get_node_segment(inode)) ) { + && (seg_ids[iseg] == (size_t)get_node_segment(inode)) ) { nodes_[inode] = nodes.front(); node_segments_[inode] = node_segments.front(); /* pop up temp vectors */ @@ -1118,6 +1118,7 @@ void RRSwitchBlock::set(const RRSwitchBlock& src) { return; } + /* Set the coordinator (x,y) for the switch block */ void RRSwitchBlock::set_coordinator(size_t x, size_t y) { coordinator_.set(x, y); @@ -1857,6 +1858,9 @@ void DeviceRRSwitchBlock::add_rotatable_mirror(DeviceCoordinator& coordinator, 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; + /* + printf("Detect a rotatable mirror: SB[%lu][%lu]\n", coordinator.get_x(), coordinator.get_y()); + */ } return; diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/base/write_rr_blocks.cpp b/vpr7_x2p/vpr/SRC/fpga_x2p/base/write_rr_blocks.cpp new file mode 100644 index 000000000..3aeb59755 --- /dev/null +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/base/write_rr_blocks.cpp @@ -0,0 +1,111 @@ +/* + * Output internal structure of classes defined in rr_blocks.h to XML format + */ +#include +#include +#include + +#include "rr_blocks.h" +#include "write_rr_blocks.h" + +#include "fpga_x2p_utils.h" + +void write_rr_switch_block_to_xml(std::string fname_prefix, RRSwitchBlock& rr_sb) { + /* Create a file handler*/ + std::fstream fp; + std::string fname = fname_prefix; + fname += rr_sb.gen_verilog_instance_name(); + fname += ".xml"; + + printf("Output SB XML: %s\n", fname.c_str()); + + /* Open a file */ + fp.open(fname, std::fstream::out | std::fstream::trunc); + + /* Output location of the Switch Block */ + fp << "" << std::endl; + + /* Output each side */ + for (size_t side = 0; side < rr_sb.get_num_sides(); ++side) { + Side side_manager(side); + /* Output chan nodes */ + for (size_t inode = 0; inode < rr_sb.get_chan_width(side_manager.get_side()); ++inode) { + /* We only care OUT_PORT */ + if (OUT_PORT != rr_sb.get_chan_node_direction(side_manager.get_side(), inode)) { + continue; + } + /* Output drivers */ + size_t num_drive_rr_nodes = 0; + t_rr_node** drive_rr_nodes = 0; + t_rr_node* cur_rr_node = rr_sb.get_chan_node(side_manager.get_side(), inode); + + /* Output node information: location, index, side */ + fp << "\t<" << convert_chan_type_to_string(cur_rr_node->type) + << " side=\"" << side_manager.to_string() + << "\" index=\"" << inode << "\">" + << std::endl; + + /* Check if this node is directly connected to the node on the opposite side */ + if (true == rr_sb.is_node_imply_short_connection(cur_rr_node)) { + /* Double check if the interc lies inside a channel wire, that is interc between segments */ + assert(true == rr_sb.is_node_exist_opposite_side(cur_rr_node, side_manager.get_side())); + num_drive_rr_nodes = 0; + drive_rr_nodes = NULL; + } else { + num_drive_rr_nodes = cur_rr_node->num_drive_rr_nodes; + drive_rr_nodes = cur_rr_node->drive_rr_nodes; + } + /* Direct connection: output the node on the opposite side */ + if (0 == num_drive_rr_nodes) { + Side oppo_side = side_manager.get_opposite(); + fp << "\t\ttype) + << "\" side=\"" << oppo_side.to_string() + << "\" index=\"" << rr_sb.get_node_index(cur_rr_node, oppo_side.get_side(), IN_PORT) << "\"/>" + << std::endl; + } else { + for (size_t jnode = 0; jnode < num_drive_rr_nodes; ++jnode) { + enum e_side drive_node_side = NUM_SIDES; + int drive_node_index = -1; + rr_sb.get_node_side_and_index(drive_rr_nodes[jnode], IN_PORT, &drive_node_side, &drive_node_index); + Side drive_side(drive_node_side); + std::string node_type_str; + if (OPIN == drive_rr_nodes[jnode]->type) { + node_type_str = "opin"; + } else { + node_type_str = convert_chan_type_to_string(drive_rr_nodes[jnode]->type); + } + fp << "\t\t" + << std::endl; + } + } + fp << "\ttype) << ">" << std::endl; + } + } + + fp << "" << std::endl; + + /* close a file */ + fp.close(); + + return; +} + +/* Output each rr_switch_block to a XML file */ +void write_device_rr_switch_block_to_xml(DeviceRRSwitchBlock& LL_device_rr_switch_block) { + std::string fname_prefix("/var/tmp/xtang/sb_xml/"); + DeviceCoordinator sb_range = LL_device_rr_switch_block.get_switch_block_range(); + + /* For each switch block, an XML file will be outputted */ + for (size_t ix = 0; ix < sb_range.get_x(); ++ix) { + for (size_t iy = 0; iy < sb_range.get_y(); ++iy) { + RRSwitchBlock rr_sb = LL_device_rr_switch_block.get_switch_block(ix, iy); + write_rr_switch_block_to_xml(fname_prefix, rr_sb); + } + } + + return; +} + diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/base/write_rr_blocks.h b/vpr7_x2p/vpr/SRC/fpga_x2p/base/write_rr_blocks.h new file mode 100644 index 000000000..dd00ffb79 --- /dev/null +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/base/write_rr_blocks.h @@ -0,0 +1,8 @@ +#ifndef WRITE_RR_BLOCKS_H +#define WRITE_RR_BLOCKS_H + +void write_rr_switch_block_to_xml(std::string fname_prefix, RRSwitchBlock& rr_sb) { + +void write_device_rr_switch_block_to_xml(DeviceRRSwitchBlock& LL_device_rr_switch_block); + +#endif