[Tool] Add report bitstream distribution functionality to architecture bitstream library

This commit is contained in:
tangxifan 2021-05-07 11:22:01 -06:00
parent 9f58f926c8
commit 01b3a96e4b
5 changed files with 182 additions and 3 deletions

View File

@ -71,5 +71,27 @@ size_t find_bitstream_manager_config_bit_index_in_parent_block(const BitstreamMa
return curr_index;
}
/********************************************************************
* Find the total number of configuration bits under a block
* As configuration bits are stored only under the leaf blocks,
* this function will recursively visit all the child blocks
* until reaching a leaf block, where we collect the number of bits
*******************************************************************/
size_t rec_find_bitstream_manager_block_sum_of_bits(const BitstreamManager& bitstream_manager,
const ConfigBlockId& block) {
/* For leaf block, return directly with the number of bits, because it has not child block */
if (0 < bitstream_manager.block_bits(block).size()) {
VTR_ASSERT_SAFE(bitstream_manager.block_children(block).empty());
return bitstream_manager.block_bits(block).size();
}
size_t sum_of_bits = 0;
/* Dive to child blocks if this block has any */
for (const ConfigBlockId& child_block : bitstream_manager.block_children(block)) {
sum_of_bits += rec_find_bitstream_manager_block_sum_of_bits(bitstream_manager, child_block);
}
return sum_of_bits;
}
} /* end namespace openfpga */

View File

@ -22,6 +22,9 @@ std::vector<ConfigBlockId> find_bitstream_manager_top_blocks(const BitstreamMana
size_t find_bitstream_manager_config_bit_index_in_parent_block(const BitstreamManager& bitstream_manager,
const ConfigBitId& bit_id);
size_t rec_find_bitstream_manager_block_sum_of_bits(const BitstreamManager& bitstream_manager,
const ConfigBlockId& block);
} /* end namespace openfpga */
#endif

View File

@ -0,0 +1,121 @@
/********************************************************************
* This file includes functions that report distribution of bitstream by blocks
*******************************************************************/
#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_arch_bitstream_distribution.h"
/* 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) {
valid_file_stream(fp);
auto end = std::chrono::system_clock::now();
std::time_t end_time = std::chrono::system_clock::to_time_t(end);
fp << "<!-- " << std::endl;
fp << "\t- Report Architecture Bitstream Distribution" << std::endl;
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
* 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 rec_report_block_bitstream_distribution_to_xml_file(std::fstream& fp,
const BitstreamManager& bitstream_manager,
const ConfigBlockId& block,
const size_t& max_hierarchy_level,
const size_t& hierarchy_level) {
valid_file_stream(fp);
if (hierarchy_level > max_hierarchy_level) {
return;
}
/* Write the bitstream distribution of this block */
write_tab_to_file(fp, hierarchy_level);
fp << "<block";
fp << " name=\"" << bitstream_manager.block_name(block)<< "\"";
fp << " number_of_bits=\"" << rec_find_bitstream_manager_block_sum_of_bits(bitstream_manager, block) << "\"";
fp << ">" << std::endl;
/* Dive to child blocks if this block has any */
for (const ConfigBlockId& child_block : bitstream_manager.block_children(block)) {
rec_report_block_bitstream_distribution_to_xml_file(fp, bitstream_manager, child_block,
max_hierarchy_level, hierarchy_level + 1);
}
write_tab_to_file(fp, hierarchy_level);
fp << "</block>" <<std::endl;
}
/********************************************************************
* Report the distribution of bitstream by blocks, e.g., the number of
* configuration bits per SB/CB/CLB
* This function can generate a report to a file
*
* Notes:
* - The output format is a table whose format is compatible with RST files
*******************************************************************/
void report_architecture_bitstream_distribution(const BitstreamManager& bitstream_manager,
const std::string& fname,
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");
}
std::string timer_message = std::string("Report architecture 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_architecture_bitstream_distribution_xml_file_head(fp);
/* Find the top block, which has not parents */
std::vector<ConfigBlockId> top_block = find_bitstream_manager_top_blocks(bitstream_manager);
/* Make sure we have only 1 top block */
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);
/* Close file handler */
fp.close();
}
} /* end namespace openfpga */

View File

@ -0,0 +1,23 @@
#ifndef REPORT_ARCH_BITSTREAM_DISTRIBUTION_H
#define REPORT_ARCH_BITSTREAM_DISTRIBUTION_H
/********************************************************************
* Include header files that are required by function declaration
*******************************************************************/
#include <string>
#include "bitstream_manager.h"
/********************************************************************
* Function declaration
*******************************************************************/
/* begin namespace openfpga */
namespace openfpga {
void report_architecture_bitstream_distribution(const BitstreamManager& bitstream_manager,
const std::string& fname,
const size_t& max_hierarchy_level = 1);
} /* end namespace openfpga */
#endif

View File

@ -10,17 +10,18 @@
/* Headers from fabric key */
#include "read_xml_arch_bitstream.h"
#include "write_xml_arch_bitstream.h"
#include "report_arch_bitstream_distribution.h"
int main(int argc, const char** argv) {
/* Ensure we have only one or two argument */
VTR_ASSERT((2 == argc) || (3 == argc));
/* Ensure we have only one or two or 3 argument */
VTR_ASSERT((2 == argc) || (3 == argc) || (4 == argc));
/* Parse the bitstream from an XML file */
openfpga::BitstreamManager test_bitstream = openfpga::read_xml_architecture_bitstream(argv[1]);
VTR_LOG("Read the bitstream from an XML file: %s.\n",
argv[1]);
/* Output the circuit library to an XML file
/* Output the bitstream database to an XML file
* This is optional only used when there is a second argument
*/
if (3 <= argc) {
@ -28,6 +29,15 @@ int main(int argc, const char** argv) {
VTR_LOG("Echo the bitstream to an XML file: %s.\n",
argv[2]);
}
/* Output the bitstream distribution to an XML file
* This is optional only used when there is a third argument
*/
if (4 <= argc) {
openfpga::report_architecture_bitstream_distribution(test_bitstream, argv[3]);
VTR_LOG("Echo the bitstream distribution to an XML file: %s.\n",
argv[3]);
}
}