OpenFPGA/openfpga/src/fabric/fabric_hierarchy_writer.cpp

152 lines
5.5 KiB
C++

/***************************************************************************************
* Output internal structure of Module Graph hierarchy to file formats
***************************************************************************************/
/* Headers from vtrutil library */
#include "vtr_log.h"
#include "vtr_assert.h"
#include "vtr_time.h"
/* Headers from openfpgautil library */
#include "openfpga_digest.h"
#include "openfpga_naming.h"
#include "fabric_hierarchy_writer.h"
/* begin namespace openfpga */
namespace openfpga {
/***************************************************************************************
* Recursively output child module of the parent_module to a text file
* We use Depth-First Search (DFS) here so that we can output a tree down to leaf first
* Add space (indent) based on the depth in hierarchy
* e.g. depth = 1 means a space as indent
***************************************************************************************/
static
int rec_output_module_hierarchy_to_text_file(std::fstream& fp,
const size_t& hie_depth_to_stop,
const size_t& current_hie_depth,
const ModuleManager& module_manager,
const ModuleId& parent_module,
const bool& verbose) {
/* Stop if hierarchy depth is beyond the stop line */
if (hie_depth_to_stop < current_hie_depth) {
return 0;
}
if (false == valid_file_stream(fp)) {
return 2;
}
/* Iterate over all the child module */
for (const ModuleId& child_module : module_manager.child_modules(parent_module)) {
if (false == write_space_to_file(fp, current_hie_depth * 2)) {
return 2;
}
if (true != module_manager.valid_module_id(child_module)) {
VTR_LOGV_ERROR(verbose,
"Unable to find the child module '%u'!\n",
size_t(child_module));
return 1;
}
fp << "- ";
fp << module_manager.module_name(child_module);
/* If this is the leaf node, we leave a new line
* Otherwise, we will leave a ':' to be compatible to YAML file format
*/
if ( (0 != module_manager.child_modules(child_module).size())
&& (hie_depth_to_stop >= current_hie_depth + 1) ) {
fp << ":";
}
fp << "\n";
/* Go to next level */
int status = rec_output_module_hierarchy_to_text_file(fp,
hie_depth_to_stop,
current_hie_depth + 1, /* Increment the depth for the next level */
module_manager,
child_module,
verbose);
if (0 != status) {
return status;
}
}
return 0;
}
/***************************************************************************************
* Write the hierarchy of modules to a plain text file
* e.g.,
* <module_name>
* <child_module_name>
* ...
* This file is mainly used by hierarchical P&R flow
*
* Return 0 if successful
* Return 1 if there are more serious bugs in the architecture
* Return 2 if fail when creating files
***************************************************************************************/
int write_fabric_hierarchy_to_text_file(const ModuleManager& module_manager,
const std::string& fname,
const size_t& hie_depth_to_stop,
const bool& verbose) {
std::string timer_message = std::string("Write fabric hierarchy to plain-text file '") + fname + std::string("'");
std::string dir_path = format_dir_path(find_path_dir_name(fname));
/* Create directories */
create_directory(dir_path);
/* Start time count */
vtr::ScopedStartFinishTimer timer(timer_message);
/* Use default name if user does not provide one */
VTR_ASSERT(true != fname.empty());
/* 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);
/* Find top-level module */
std::string top_module_name = generate_fpga_top_module_name();
ModuleId top_module = module_manager.find_module(top_module_name);
if (true != module_manager.valid_module_id(top_module)) {
VTR_LOGV_ERROR(verbose,
"Unable to find the top-level module '%s'!\n",
top_module_name.c_str());
return 1;
}
/* Record current depth of module: top module is the root with 0 depth */
size_t hie_depth = 0;
if (hie_depth_to_stop < hie_depth) {
return 0;
}
fp << top_module_name << ":" << "\n";
/* Visit child module recursively and output the hierarchy */
int err_code = rec_output_module_hierarchy_to_text_file(fp,
hie_depth_to_stop,
hie_depth + 1, /* Start with level 1 */
module_manager,
top_module,
verbose);
/* close a file */
fp.close();
return err_code;
}
} /* end namespace openfpga */