Merge pull request #608 from lnis-uofu/bit_dist
Include Configuration Region Statistics in Bitstream Distribution Report File
This commit is contained in:
commit
b887b68938
|
@ -5,15 +5,25 @@ Bitstream Distribution File (.xml)
|
|||
|
||||
The bitstream distribution file aims to show
|
||||
|
||||
- The total number of configuration bits under each block
|
||||
- The number of configuration bits per block
|
||||
- region-level bitstream distribution
|
||||
- The total number of configuration bits under each region
|
||||
|
||||
An example of design constraints is shown as follows.
|
||||
- block-level bitstream distribution
|
||||
- The total number of configuration bits under each block
|
||||
- The number of configuration bits per block
|
||||
|
||||
An example of the file is shown as follows.
|
||||
|
||||
.. code-block:: xml
|
||||
|
||||
<block name="fpga_top" number_of_bits="527">
|
||||
<block name="grid_clb_1__1_" number_of_bits="136">
|
||||
<bitstream_distribution>
|
||||
<regions>
|
||||
<region id="0" number_of_bits="2250">
|
||||
</region>
|
||||
</regions>
|
||||
<blocks>
|
||||
<block name="fpga_top" number_of_bits="2250">
|
||||
<block name="grid_clb_1__1_" number_of_bits="1700">
|
||||
</block>
|
||||
<block name="grid_io_top_1__2_" number_of_bits="8">
|
||||
</block>
|
||||
|
@ -23,23 +33,43 @@ An example of design constraints is shown as follows.
|
|||
</block>
|
||||
<block name="grid_io_left_0__1_" number_of_bits="8">
|
||||
</block>
|
||||
<block name="sb_0__0_" number_of_bits="58">
|
||||
<block name="sb_0__0_" number_of_bits="40">
|
||||
</block>
|
||||
<block name="sb_0__1_" number_of_bits="57">
|
||||
<block name="sb_0__1_" number_of_bits="40">
|
||||
</block>
|
||||
<block name="sb_1__0_" number_of_bits="59">
|
||||
<block name="sb_1__0_" number_of_bits="40">
|
||||
</block>
|
||||
<block name="sb_1__1_" number_of_bits="56">
|
||||
<block name="sb_1__1_" number_of_bits="40">
|
||||
</block>
|
||||
<block name="cbx_1__0_" number_of_bits="33">
|
||||
<block name="cbx_1__0_" number_of_bits="88">
|
||||
</block>
|
||||
<block name="cbx_1__1_" number_of_bits="33">
|
||||
<block name="cbx_1__1_" number_of_bits="94">
|
||||
</block>
|
||||
<block name="cby_0__1_" number_of_bits="30">
|
||||
<block name="cby_0__1_" number_of_bits="88">
|
||||
</block>
|
||||
<block name="cby_1__1_" number_of_bits="33">
|
||||
<block name="cby_1__1_" number_of_bits="88">
|
||||
</block>
|
||||
</block>
|
||||
</blocks>
|
||||
</bitstream_distribution>
|
||||
|
||||
Region-Level Bitstream Distribution
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Region-level bitstream distribution is shown under the ``<regions>`` code block
|
||||
|
||||
.. option:: id="<string>"
|
||||
|
||||
The unique index of the region, which can be found in the :ref:`file_formats_fabric_key`
|
||||
|
||||
.. option:: number_of_bits="<string>"
|
||||
|
||||
The total number of configuration bits in this region
|
||||
|
||||
Block-Level Bitstream Distribution
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Block-level bitstream distribution is shown under the ``<blocks>`` code block
|
||||
|
||||
.. option:: name="<string>"
|
||||
|
||||
|
|
|
@ -23,29 +23,6 @@
|
|||
/* begin namespace openfpga */
|
||||
namespace openfpga {
|
||||
|
||||
/********************************************************************
|
||||
* This function write header information for an XML file of bitstream distribution
|
||||
*******************************************************************/
|
||||
static
|
||||
void report_architecture_bitstream_distribution_xml_file_head(std::fstream& fp,
|
||||
const bool& include_time_stamp) {
|
||||
valid_file_stream(fp);
|
||||
|
||||
fp << "<!-- " << std::endl;
|
||||
fp << "\t- Report Architecture Bitstream Distribution" << std::endl;
|
||||
|
||||
if (include_time_stamp) {
|
||||
auto end = std::chrono::system_clock::now();
|
||||
std::time_t end_time = std::chrono::system_clock::to_time_t(end);
|
||||
/* Note that version is also a type of time stamp */
|
||||
fp << "\t- Version: " << openfpga::VERSION << std::endl;
|
||||
fp << "\t- Date: " << std::ctime(&end_time) ;
|
||||
}
|
||||
|
||||
fp << "--> " << std::endl;
|
||||
fp << std::endl;
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
* Recursively report the bitstream distribution of a block to a file
|
||||
* This function will use a Depth-First Search in outputting bitstream
|
||||
|
@ -91,27 +68,19 @@ void rec_report_block_bitstream_distribution_to_xml_file(std::fstream& fp,
|
|||
* Notes:
|
||||
* - The output format is a table whose format is compatible with RST files
|
||||
*******************************************************************/
|
||||
int report_architecture_bitstream_distribution(const BitstreamManager& bitstream_manager,
|
||||
const std::string& fname,
|
||||
const bool& include_time_stamp,
|
||||
const size_t& max_hierarchy_level) {
|
||||
/* Ensure that we have a valid file name */
|
||||
if (true == fname.empty()) {
|
||||
VTR_LOG_ERROR("Received empty file name to report bitstream!\n\tPlease specify a valid file name.\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
std::string timer_message = std::string("Report architecture bitstream distribution into XML file '") + fname + std::string("'");
|
||||
int report_architecture_bitstream_distribution(std::fstream& fp,
|
||||
const BitstreamManager& bitstream_manager,
|
||||
const size_t& max_hierarchy_level,
|
||||
const size_t& hierarchy_level) {
|
||||
std::string timer_message = std::string("Report architecture bitstream distribution");
|
||||
vtr::ScopedStartFinishTimer timer(timer_message);
|
||||
|
||||
/* Create the file stream */
|
||||
std::fstream fp;
|
||||
fp.open(fname, std::fstream::out | std::fstream::trunc);
|
||||
/* Check the file stream */
|
||||
valid_file_stream(fp);
|
||||
|
||||
check_file_stream(fname.c_str(), fp);
|
||||
|
||||
/* Put down a brief introduction */
|
||||
report_architecture_bitstream_distribution_xml_file_head(fp, include_time_stamp);
|
||||
int curr_level = hierarchy_level;
|
||||
write_tab_to_file(fp, curr_level);
|
||||
fp << "<blocks>" <<std::endl;
|
||||
|
||||
/* Find the top block, which has not parents */
|
||||
std::vector<ConfigBlockId> top_block = find_bitstream_manager_top_blocks(bitstream_manager);
|
||||
|
@ -119,10 +88,10 @@ int report_architecture_bitstream_distribution(const BitstreamManager& bitstream
|
|||
VTR_ASSERT(1 == top_block.size());
|
||||
|
||||
/* Write bitstream, block by block, in a recursive way */
|
||||
rec_report_block_bitstream_distribution_to_xml_file(fp, bitstream_manager, top_block[0], max_hierarchy_level, 0);
|
||||
rec_report_block_bitstream_distribution_to_xml_file(fp, bitstream_manager, top_block[0], max_hierarchy_level + 2, curr_level + 1);
|
||||
|
||||
/* Close file handler */
|
||||
fp.close();
|
||||
write_tab_to_file(fp, curr_level);
|
||||
fp << "</blocks>" <<std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -14,10 +14,10 @@
|
|||
/* begin namespace openfpga */
|
||||
namespace openfpga {
|
||||
|
||||
int report_architecture_bitstream_distribution(const BitstreamManager& bitstream_manager,
|
||||
const std::string& fname,
|
||||
const bool& include_time_stamp,
|
||||
const size_t& max_hierarchy_level = 1);
|
||||
int report_architecture_bitstream_distribution(std::fstream& fp,
|
||||
const BitstreamManager& bitstream_manager,
|
||||
const size_t& max_hierarchy_level,
|
||||
const size_t& hierarchy_level);
|
||||
|
||||
} /* end namespace openfpga */
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
* 1. parser of data structures
|
||||
* 2. writer of data structures
|
||||
*******************************************************************/
|
||||
#include <fstream>
|
||||
/* Headers from vtrutils */
|
||||
#include "vtr_assert.h"
|
||||
#include "vtr_log.h"
|
||||
|
@ -36,11 +37,12 @@ int main(int argc, const char** argv) {
|
|||
* This is optional only used when there is a third argument
|
||||
*/
|
||||
if (4 <= argc) {
|
||||
openfpga::report_architecture_bitstream_distribution(test_bitstream, argv[3], true);
|
||||
VTR_LOG("Echo the bitstream distribution (with time stamp) to an XML file: %s.\n",
|
||||
argv[3]);
|
||||
openfpga::report_architecture_bitstream_distribution(test_bitstream, argv[3], false);
|
||||
VTR_LOG("Echo the bitstream distribution (w/o time stamp) to an XML file: %s.\n",
|
||||
/* Create the file stream */
|
||||
std::fstream fp;
|
||||
fp.open(argv[3], std::fstream::out | std::fstream::trunc);
|
||||
|
||||
openfpga::report_architecture_bitstream_distribution(fp, test_bitstream, 1, 0);
|
||||
VTR_LOG("Echo the bitstream distribution to an XML file: %s.\n",
|
||||
argv[3]);
|
||||
}
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
/* Headers from fpgabitstream library */
|
||||
#include "read_xml_arch_bitstream.h"
|
||||
#include "write_xml_arch_bitstream.h"
|
||||
#include "report_arch_bitstream_distribution.h"
|
||||
#include "report_bitstream_distribution.h"
|
||||
|
||||
#include "openfpga_naming.h"
|
||||
|
||||
|
@ -218,8 +218,9 @@ int report_bitstream_distribution(const OpenfpgaContext& openfpga_ctx,
|
|||
}
|
||||
}
|
||||
|
||||
status = report_architecture_bitstream_distribution(openfpga_ctx.bitstream_manager(),
|
||||
cmd_context.option_value(cmd, opt_file),
|
||||
status = report_bitstream_distribution(cmd_context.option_value(cmd, opt_file),
|
||||
openfpga_ctx.bitstream_manager(),
|
||||
openfpga_ctx.fabric_bitstream(),
|
||||
!cmd_context.option_enable(cmd, opt_no_time_stamp),
|
||||
depth);
|
||||
|
||||
|
|
|
@ -0,0 +1,96 @@
|
|||
/********************************************************************
|
||||
* This file includes functions that report distribution of bitstream by regions
|
||||
*******************************************************************/
|
||||
#include <chrono>
|
||||
#include <ctime>
|
||||
#include <fstream>
|
||||
|
||||
/* Headers from vtrutil library */
|
||||
#include "vtr_assert.h"
|
||||
#include "vtr_log.h"
|
||||
#include "vtr_time.h"
|
||||
|
||||
/* Headers from openfpgautil library */
|
||||
#include "openfpga_digest.h"
|
||||
#include "openfpga_tokenizer.h"
|
||||
#include "openfpga_version.h"
|
||||
|
||||
#include "openfpga_reserved_words.h"
|
||||
|
||||
#include "report_arch_bitstream_distribution.h"
|
||||
#include "report_fabric_bitstream_distribution.h"
|
||||
#include "report_bitstream_distribution.h"
|
||||
|
||||
/* begin namespace openfpga */
|
||||
namespace openfpga {
|
||||
|
||||
/********************************************************************
|
||||
* This function write header information for an XML file of bitstream distribution
|
||||
*******************************************************************/
|
||||
static
|
||||
void report_bitstream_distribution_xml_file_head(std::fstream& fp,
|
||||
const bool& include_time_stamp) {
|
||||
valid_file_stream(fp);
|
||||
|
||||
fp << "<!-- " << std::endl;
|
||||
fp << "\t- Report Bitstream Distribution" << std::endl;
|
||||
|
||||
if (include_time_stamp) {
|
||||
auto end = std::chrono::system_clock::now();
|
||||
std::time_t end_time = std::chrono::system_clock::to_time_t(end);
|
||||
/* Note that version is also a type of time stamp */
|
||||
fp << "\t- Version: " << openfpga::VERSION << std::endl;
|
||||
fp << "\t- Date: " << std::ctime(&end_time) ;
|
||||
}
|
||||
|
||||
fp << "--> " << std::endl;
|
||||
fp << std::endl;
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
* Report the distribution of bitstream at architecture-level and fabric-level
|
||||
* This function can generate a report to a file
|
||||
*******************************************************************/
|
||||
int report_bitstream_distribution(const std::string& fname,
|
||||
const BitstreamManager& bitstream_manager,
|
||||
const FabricBitstream& fabric_bitstream,
|
||||
const bool& include_time_stamp,
|
||||
const size_t& max_hierarchy_level) {
|
||||
/* Ensure that we have a valid file name */
|
||||
if (true == fname.empty()) {
|
||||
VTR_LOG_ERROR("Received empty file name to report bitstream!\n\tPlease specify a valid file name.\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
std::string timer_message = std::string("Report bitstream distribution into XML file '") + fname + std::string("'");
|
||||
vtr::ScopedStartFinishTimer timer(timer_message);
|
||||
|
||||
/* Create the file stream */
|
||||
std::fstream fp;
|
||||
fp.open(fname, std::fstream::out | std::fstream::trunc);
|
||||
|
||||
check_file_stream(fname.c_str(), fp);
|
||||
|
||||
/* Put down a brief introduction */
|
||||
report_bitstream_distribution_xml_file_head(fp, include_time_stamp);
|
||||
|
||||
int curr_level = 0;
|
||||
write_tab_to_file(fp, curr_level);
|
||||
fp << "<bitstream_distribution>" <<std::endl;
|
||||
|
||||
int status = 0;
|
||||
status = report_fabric_bitstream_distribution(fp, fabric_bitstream, curr_level + 1);
|
||||
if (status == 1) {
|
||||
return status;
|
||||
}
|
||||
status = report_architecture_bitstream_distribution(fp, bitstream_manager, max_hierarchy_level, curr_level + 1);
|
||||
|
||||
fp << "</bitstream_distribution>" <<std::endl;
|
||||
|
||||
/* Close file handler */
|
||||
fp.close();
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
} /* end namespace openfpga */
|
|
@ -0,0 +1,25 @@
|
|||
#ifndef REPORT_BITSTREAM_DISTRIBUTION_H
|
||||
#define REPORT_BITSTREAM_DISTRIBUTION_H
|
||||
|
||||
/********************************************************************
|
||||
* Include header files that are required by function declaration
|
||||
*******************************************************************/
|
||||
#include <string>
|
||||
#include "fabric_bitstream.h"
|
||||
|
||||
/********************************************************************
|
||||
* Function declaration
|
||||
*******************************************************************/
|
||||
|
||||
/* begin namespace openfpga */
|
||||
namespace openfpga {
|
||||
|
||||
int report_bitstream_distribution(const std::string& fname,
|
||||
const BitstreamManager& bitstream_manager,
|
||||
const FabricBitstream& fabric_bitstream,
|
||||
const bool& include_time_stamp,
|
||||
const size_t& max_hierarchy_level = 1);
|
||||
|
||||
} /* end namespace openfpga */
|
||||
|
||||
#endif
|
|
@ -0,0 +1,78 @@
|
|||
/********************************************************************
|
||||
* This file includes functions that report distribution of bitstream by regions
|
||||
*******************************************************************/
|
||||
#include <chrono>
|
||||
#include <ctime>
|
||||
#include <fstream>
|
||||
|
||||
/* Headers from vtrutil library */
|
||||
#include "vtr_assert.h"
|
||||
#include "vtr_log.h"
|
||||
#include "vtr_time.h"
|
||||
|
||||
/* Headers from openfpgautil library */
|
||||
#include "openfpga_digest.h"
|
||||
#include "openfpga_tokenizer.h"
|
||||
#include "openfpga_version.h"
|
||||
|
||||
#include "openfpga_reserved_words.h"
|
||||
|
||||
#include "bitstream_manager_utils.h"
|
||||
#include "report_fabric_bitstream_distribution.h"
|
||||
|
||||
/* begin namespace openfpga */
|
||||
namespace openfpga {
|
||||
|
||||
/********************************************************************
|
||||
* Recursively report the bitstream distribution of a block to a file
|
||||
* This function will use a Depth-First Search in outputting bitstream
|
||||
* for each block
|
||||
* For block with child blocks, we visit each child recursively
|
||||
* The reporting can be stopped at a given maximum hierarchy level
|
||||
* which is used to limit the length of the report
|
||||
*******************************************************************/
|
||||
static
|
||||
void report_region_bitstream_distribution_to_xml_file(std::fstream& fp,
|
||||
const FabricBitstream& fabric_bitstream,
|
||||
const FabricBitRegionId& region,
|
||||
const int& hierarchy_level) {
|
||||
valid_file_stream(fp);
|
||||
|
||||
/* Write the bitstream distribution of this block */
|
||||
write_tab_to_file(fp, hierarchy_level);
|
||||
fp << "<region";
|
||||
fp << " id=\"" << size_t(region) << "\"";
|
||||
fp << " number_of_bits=\"" << fabric_bitstream.region_bits(region).size() << "\"";
|
||||
fp << ">" << std::endl;
|
||||
|
||||
write_tab_to_file(fp, hierarchy_level);
|
||||
fp << "</region>" <<std::endl;
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
* Report the distribution of bitstream by regions
|
||||
* This function can generate a report to a file
|
||||
*******************************************************************/
|
||||
int report_fabric_bitstream_distribution(std::fstream& fp,
|
||||
const FabricBitstream& fabric_bitstream,
|
||||
const int& hierarchy_level) {
|
||||
std::string timer_message = std::string("Report fabric bitstream distribution");
|
||||
vtr::ScopedStartFinishTimer timer(timer_message);
|
||||
|
||||
valid_file_stream(fp);
|
||||
|
||||
/* Write bitstream, region by region, in a recursive way */
|
||||
int curr_level = hierarchy_level;
|
||||
for (const FabricBitRegionId& region : fabric_bitstream.regions()) {
|
||||
write_tab_to_file(fp, curr_level);
|
||||
fp << "<regions>" <<std::endl;
|
||||
report_region_bitstream_distribution_to_xml_file(fp, fabric_bitstream, region, curr_level + 1);
|
||||
write_tab_to_file(fp, curr_level);
|
||||
fp << "</regions>" <<std::endl;
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
} /* end namespace openfpga */
|
|
@ -0,0 +1,23 @@
|
|||
#ifndef REPORT_FABRIC_BITSTREAM_DISTRIBUTION_H
|
||||
#define REPORT_FABRIC_BITSTREAM_DISTRIBUTION_H
|
||||
|
||||
/********************************************************************
|
||||
* Include header files that are required by function declaration
|
||||
*******************************************************************/
|
||||
#include <string>
|
||||
#include "fabric_bitstream.h"
|
||||
|
||||
/********************************************************************
|
||||
* Function declaration
|
||||
*******************************************************************/
|
||||
|
||||
/* begin namespace openfpga */
|
||||
namespace openfpga {
|
||||
|
||||
int report_fabric_bitstream_distribution(std::fstream& fp,
|
||||
const FabricBitstream& fabric_bitstream,
|
||||
const int& hierarchy_level);
|
||||
|
||||
} /* end namespace openfpga */
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue