[FPGA-Bitstream] Now report_bitstream_distribution includes fabric bitstream stats
This commit is contained in:
parent
f3a50d838a
commit
6171abdf95
|
@ -23,29 +23,6 @@
|
||||||
/* begin namespace openfpga */
|
/* begin namespace openfpga */
|
||||||
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
|
* Recursively report the bitstream distribution of a block to a file
|
||||||
* This function will use a Depth-First Search in outputting bitstream
|
* 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:
|
* Notes:
|
||||||
* - The output format is a table whose format is compatible with RST files
|
* - The output format is a table whose format is compatible with RST files
|
||||||
*******************************************************************/
|
*******************************************************************/
|
||||||
int report_architecture_bitstream_distribution(const BitstreamManager& bitstream_manager,
|
int report_architecture_bitstream_distribution(std::fstream& fp,
|
||||||
const std::string& fname,
|
const BitstreamManager& bitstream_manager,
|
||||||
const bool& include_time_stamp,
|
const size_t& max_hierarchy_level,
|
||||||
const size_t& max_hierarchy_level) {
|
const size_t& hierarchy_level) {
|
||||||
/* Ensure that we have a valid file name */
|
std::string timer_message = std::string("Report architecture bitstream distribution");
|
||||||
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("'");
|
|
||||||
vtr::ScopedStartFinishTimer timer(timer_message);
|
vtr::ScopedStartFinishTimer timer(timer_message);
|
||||||
|
|
||||||
/* Create the file stream */
|
/* Check the file stream */
|
||||||
std::fstream fp;
|
valid_file_stream(fp);
|
||||||
fp.open(fname, std::fstream::out | std::fstream::trunc);
|
|
||||||
|
|
||||||
check_file_stream(fname.c_str(), fp);
|
int curr_level = hierarchy_level;
|
||||||
|
write_tab_to_file(fp, curr_level);
|
||||||
/* Put down a brief introduction */
|
fp << "<blocks>" <<std::endl;
|
||||||
report_architecture_bitstream_distribution_xml_file_head(fp, include_time_stamp);
|
|
||||||
|
|
||||||
/* Find the top block, which has not parents */
|
/* Find the top block, which has not parents */
|
||||||
std::vector<ConfigBlockId> top_block = find_bitstream_manager_top_blocks(bitstream_manager);
|
std::vector<ConfigBlockId> top_block = find_bitstream_manager_top_blocks(bitstream_manager);
|
||||||
|
@ -119,10 +88,9 @@ int report_architecture_bitstream_distribution(const BitstreamManager& bitstream
|
||||||
VTR_ASSERT(1 == top_block.size());
|
VTR_ASSERT(1 == top_block.size());
|
||||||
|
|
||||||
/* Write bitstream, block by block, in a recursive way */
|
/* 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, curr_level + 1);
|
||||||
|
|
||||||
/* Close file handler */
|
fp << "</blocks>" <<std::endl;
|
||||||
fp.close();
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,10 +14,10 @@
|
||||||
/* begin namespace openfpga */
|
/* begin namespace openfpga */
|
||||||
namespace openfpga {
|
namespace openfpga {
|
||||||
|
|
||||||
int report_architecture_bitstream_distribution(const BitstreamManager& bitstream_manager,
|
int report_architecture_bitstream_distribution(std::fstream& fp,
|
||||||
const std::string& fname,
|
const BitstreamManager& bitstream_manager,
|
||||||
const bool& include_time_stamp,
|
const size_t& max_hierarchy_level,
|
||||||
const size_t& max_hierarchy_level = 1);
|
const size_t& hierarchy_level);
|
||||||
|
|
||||||
} /* end namespace openfpga */
|
} /* end namespace openfpga */
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
* 1. parser of data structures
|
* 1. parser of data structures
|
||||||
* 2. writer of data structures
|
* 2. writer of data structures
|
||||||
*******************************************************************/
|
*******************************************************************/
|
||||||
|
#include <fstream>
|
||||||
/* Headers from vtrutils */
|
/* Headers from vtrutils */
|
||||||
#include "vtr_assert.h"
|
#include "vtr_assert.h"
|
||||||
#include "vtr_log.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
|
* This is optional only used when there is a third argument
|
||||||
*/
|
*/
|
||||||
if (4 <= argc) {
|
if (4 <= argc) {
|
||||||
openfpga::report_architecture_bitstream_distribution(test_bitstream, argv[3], true);
|
/* Create the file stream */
|
||||||
VTR_LOG("Echo the bitstream distribution (with time stamp) to an XML file: %s.\n",
|
std::fstream fp;
|
||||||
argv[3]);
|
fp.open(argv[3], std::fstream::out | std::fstream::trunc);
|
||||||
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",
|
openfpga::report_architecture_bitstream_distribution(fp, test_bitstream, 1, 0);
|
||||||
|
VTR_LOG("Echo the bitstream distribution to an XML file: %s.\n",
|
||||||
argv[3]);
|
argv[3]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
/* Headers from fpgabitstream library */
|
/* Headers from fpgabitstream library */
|
||||||
#include "read_xml_arch_bitstream.h"
|
#include "read_xml_arch_bitstream.h"
|
||||||
#include "write_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"
|
#include "openfpga_naming.h"
|
||||||
|
|
||||||
|
@ -218,10 +218,11 @@ int report_bitstream_distribution(const OpenfpgaContext& openfpga_ctx,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
status = report_architecture_bitstream_distribution(openfpga_ctx.bitstream_manager(),
|
status = report_bitstream_distribution(cmd_context.option_value(cmd, opt_file),
|
||||||
cmd_context.option_value(cmd, opt_file),
|
openfpga_ctx.bitstream_manager(),
|
||||||
!cmd_context.option_enable(cmd, opt_no_time_stamp),
|
openfpga_ctx.fabric_bitstream(),
|
||||||
depth);
|
!cmd_context.option_enable(cmd, opt_no_time_stamp),
|
||||||
|
depth);
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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