diff --git a/openfpga/src/annotation/write_xml_device_rr_gsb.cpp b/openfpga/src/annotation/write_xml_device_rr_gsb.cpp new file mode 100644 index 000000000..cd3fb7b43 --- /dev/null +++ b/openfpga/src/annotation/write_xml_device_rr_gsb.cpp @@ -0,0 +1,190 @@ +/*************************************************************************************** + * Output internal structure of DeviceRRGSB to XML format + ***************************************************************************************/ +/* Headers from vtrutil library */ +#include "vtr_log.h" +#include "vtr_assert.h" +#include "vtr_time.h" + +/* Headers from openfpgautil library */ +#include "openfpga_side_manager.h" +#include "openfpga_digest.h" + +#include "openfpga_naming.h" +#include "openfpga_rr_graph_utils.h" + +#include "write_xml_device_rr_gsb.h" + +/* begin namespace openfpga */ +namespace openfpga { + +/*************************************************************************************** + * Output internal structure (only the switch block part) of a RRGSB to XML format + ***************************************************************************************/ +static +void write_rr_switch_block_to_xml(const std::string fname_prefix, + const RRGraph& rr_graph, + const RRGSB& rr_gsb) { + /* Prepare file name */ + std::string fname(fname_prefix); + vtr::Point gsb_coordinate(rr_gsb.get_sb_x(), rr_gsb.get_sb_y()); + fname += generate_switch_block_module_name(gsb_coordinate); + fname += ".xml"; + + VTR_LOG("Output internal structure of Switch Block to '%s'\r", fname.c_str()); + + /* Create a file handler*/ + std::fstream fp; + /* Open a file */ + fp.open(fname, std::fstream::out | std::fstream::trunc); + + /* Validate the file stream */ + check_file_stream(fname.c_str(), fp); + + /* Output location of the Switch Block */ + fp << "" << std::endl; + + /* Output each side */ + for (size_t side = 0; side < rr_gsb.get_num_sides(); ++side) { + SideManager gsb_side_manager(side); + enum e_side gsb_side = gsb_side_manager.get_side(); + + /* Output IPIN nodes */ + for (size_t inode = 0; inode < rr_gsb.get_num_ipin_nodes(gsb_side); ++inode) { + const RRNodeId& cur_rr_node = rr_gsb.get_ipin_node(gsb_side, inode); + /* General information of this IPIN */ + fp << "\t<" << rr_node_typename[rr_graph.node_type(cur_rr_node)] + << " side=\"" << gsb_side_manager.to_string() + << "\" index=\"" << inode + << "\" mux_size=\"" << get_rr_graph_configurable_driver_nodes(rr_graph, cur_rr_node).size() + << "\">" + << std::endl; + /* General information of each driving nodes */ + for (const RRNodeId& driver_node : get_rr_graph_configurable_driver_nodes(rr_graph, cur_rr_node)) { + /* Skip OPINs: they should be in direct connections */ + if (OPIN == rr_graph.node_type(driver_node)) { + continue; + } + + enum e_side chan_side = rr_gsb.get_cb_chan_side(gsb_side); + SideManager chan_side_manager(chan_side); + + /* For channel node, we do not know the node direction + * But we are pretty sure it is either IN_PORT or OUT_PORT + * So we just try and find what is valid + */ + int driver_node_index = rr_gsb.get_chan_node_index(chan_side, driver_node); + /* We must have a valide node index */ + VTR_ASSERT(-1 != driver_node_index); + + const RRSegmentId& des_segment_id = rr_gsb.get_chan_node_segment(chan_side, driver_node_index); + + fp << "\t\t" + << std::endl; + } + fp << "\t" + << std::endl; + } + + /* Output chan nodes */ + for (size_t inode = 0; inode < rr_gsb.get_chan_width(gsb_side); ++inode) { + /* We only care OUT_PORT */ + if (OUT_PORT != rr_gsb.get_chan_node_direction(gsb_side, inode)) { + continue; + } + /* Output drivers */ + const RRNodeId& cur_rr_node = rr_gsb.get_chan_node(gsb_side, inode); + std::vector driver_rr_nodes = get_rr_graph_configurable_driver_nodes(rr_graph, cur_rr_node); + + /* Output node information: location, index, side */ + const RRSegmentId& src_segment_id = rr_gsb.get_chan_node_segment(gsb_side, inode); + + /* Check if this node is directly connected to the node on the opposite side */ + if (true == rr_gsb.is_sb_node_passing_wire(rr_graph, gsb_side, inode)) { + driver_rr_nodes.clear(); + } + + fp << "\t<" << rr_node_typename[rr_graph.node_type(cur_rr_node)] + << " side=\"" << gsb_side_manager.to_string() + << "\" index=\"" << inode + << "\" segment_id=\"" << size_t(src_segment_id) + << "\" mux_size=\"" << driver_rr_nodes.size() + << "\">" + << std::endl; + + /* Direct connection: output the node on the opposite side */ + if (0 == driver_rr_nodes.size()) { + SideManager oppo_side = gsb_side_manager.get_opposite(); + fp << "\t\t" + << std::endl; + } else { + for (const RRNodeId& driver_rr_node : driver_rr_nodes) { + e_side driver_node_side = NUM_SIDES; + int driver_node_index = -1; + rr_gsb.get_node_side_and_index(rr_graph, driver_rr_node, IN_PORT, driver_node_side, driver_node_index); + VTR_ASSERT(-1 != driver_node_index); + SideManager driver_side(driver_node_side); + + if (OPIN == rr_graph.node_type(driver_rr_node)) { + SideManager grid_side(rr_graph.node_side(driver_rr_node)); + fp << "\t\t" + << std::endl; + } else { + const RRSegmentId& des_segment_id = rr_gsb.get_chan_node_segment(driver_node_side, driver_node_index); + fp << "\t\t" + << std::endl; + } + } + } + fp << "\t" + << std::endl; + } + } + + fp << "" + << std::endl; + + /* close a file */ + fp.close(); +} + +/*************************************************************************************** + * Output internal structure (only the switch block part) of all the RRGSBs + * in a DeviceRRGSB to XML format + ***************************************************************************************/ +void write_device_rr_gsb_to_xml(const char* sb_xml_dir, + const RRGraph& rr_graph, + const DeviceRRGSB& device_rr_gsb) { + std::string fname_prefix = format_dir_path(std::string(sb_xml_dir)); + + vtr::Point sb_range = device_rr_gsb.get_gsb_range(); + + /* For each switch block, an XML file will be outputted */ + for (size_t ix = 0; ix < sb_range.x(); ++ix) { + for (size_t iy = 0; iy < sb_range.y(); ++iy) { + const RRGSB& rr_gsb = device_rr_gsb.get_gsb(ix, iy); + write_rr_switch_block_to_xml(fname_prefix, rr_graph, rr_gsb); + } + } +} + +} /* end namespace openfpga */ diff --git a/openfpga/src/annotation/write_xml_device_rr_gsb.h b/openfpga/src/annotation/write_xml_device_rr_gsb.h new file mode 100644 index 000000000..06c9a0a89 --- /dev/null +++ b/openfpga/src/annotation/write_xml_device_rr_gsb.h @@ -0,0 +1,24 @@ +#ifndef WRITE_XML_DEVICE_RR_GSB_H +#define WRITE_XML_DEVICE_RR_GSB_H + +/******************************************************************** + * Include header files that are required by function declaration + *******************************************************************/ +#include +#include "rr_graph_obj.h" +#include "device_rr_gsb.h" + +/******************************************************************** + * Function declaration + *******************************************************************/ + +/* begin namespace openfpga */ +namespace openfpga { + +void write_device_rr_gsb_to_xml(const char* sb_xml_dir, + const RRGraph& rr_graph, + const DeviceRRGSB& device_rr_gsb); + +} /* end namespace openfpga */ + +#endif diff --git a/openfpga/src/main.cpp b/openfpga/src/main.cpp index b2c9d2e6c..eb88c2c65 100644 --- a/openfpga/src/main.cpp +++ b/openfpga/src/main.cpp @@ -2,6 +2,7 @@ * Build the OpenFPGA shell interface *******************************************************************/ /* Header file from vtrutil library */ +#include "vtr_time.h" #include "vtr_log.h" /* Header file from libopenfpgashell library */ @@ -87,11 +88,14 @@ int main(int argc, char** argv) { } else { /* Parse succeed. Start a shell */ if (true == start_cmd_context.option_enable(start_cmd, opt_interactive)) { + + vtr::ScopedStartFinishTimer timer("OpenFPGA operating"); shell.run_interactive_mode(openfpga_context); return 0; } if (true == start_cmd_context.option_enable(start_cmd, opt_script_mode)) { + vtr::ScopedStartFinishTimer timer("OpenFPGA operating"); shell.run_script_mode(start_cmd_context.option_value(start_cmd, opt_script_mode).c_str(), openfpga_context); return 0; diff --git a/openfpga/test_vpr_arch/k6_frac_N10_adder_chain_40nm.xml b/openfpga/test_vpr_arch/k6_frac_N10_adder_chain_40nm.xml index 9610fef06..eea76837f 100644 --- a/openfpga/test_vpr_arch/k6_frac_N10_adder_chain_40nm.xml +++ b/openfpga/test_vpr_arch/k6_frac_N10_adder_chain_40nm.xml @@ -161,7 +161,7 @@ - +