add fabric hierarchy writer

This commit is contained in:
tangxifan 2020-05-05 14:36:27 -06:00
parent 0985c720e9
commit 6aff33dd35
8 changed files with 245 additions and 3 deletions

View File

@ -235,4 +235,20 @@ void create_directory(const std::string& dir_path, const bool& recursive) {
}
}
/********************************************************************
* Write a number of space to a file
********************************************************************/
bool write_space_to_file(std::fstream& fp,
const size_t& num_space) {
if (false == valid_file_stream(fp)) {
return false;
}
for (size_t i = 0; i < num_space; ++i) {
fp << " ";
}
return true;
}
} /* namespace openfpga ends */

View File

@ -25,6 +25,9 @@ std::string find_path_dir_name(const std::string& file_name);
void create_directory(const std::string& dir_path, const bool& recursive = true);
bool write_space_to_file(std::fstream& fp,
const size_t& num_space);
} /* namespace openfpga ends */
#endif

View File

@ -11,6 +11,7 @@
#include "device_rr_gsb.h"
#include "device_rr_gsb_utils.h"
#include "build_device_module.h"
#include "fabric_hierarchy_writer.h"
#include "openfpga_build_fabric.h"
/* Include global variables of VPR */
@ -85,4 +86,28 @@ int build_fabric(OpenfpgaContext& openfpga_ctx,
return CMD_EXEC_SUCCESS;
}
/********************************************************************
* Build the module graph for FPGA device
*******************************************************************/
int write_fabric_hierarchy(const OpenfpgaContext& openfpga_ctx,
const Command& cmd, const CommandContext& cmd_context) {
CommandOptionId opt_verbose = cmd.option("verbose");
/* Check the option '--file' is enabled or not
* Actually, it must be enabled as the shell interface will check
* before reaching this fuction
*/
CommandOptionId opt_file = cmd.option("file");
VTR_ASSERT(true == cmd_context.option_enable(cmd, opt_file));
VTR_ASSERT(false == cmd_context.option_value(cmd, opt_file).empty());
std::string hie_file_name = cmd_context.option_value(cmd, opt_file);
/* Write hierarchy to a file */
return write_fabric_hierarchy_to_text_file(openfpga_ctx.module_graph(),
hie_file_name,
cmd_context.option_enable(cmd, opt_verbose));
}
} /* end namespace openfpga */

View File

@ -18,6 +18,9 @@ namespace openfpga {
int build_fabric(OpenfpgaContext& openfpga_ctx,
const Command& cmd, const CommandContext& cmd_context);
int write_fabric_hierarchy(const OpenfpgaContext& openfpga_ctx,
const Command& cmd, const CommandContext& cmd_context);
} /* end namespace openfpga */
#endif

View File

@ -238,6 +238,37 @@ ShellCommandId add_openfpga_build_fabric_command(openfpga::Shell<OpenfpgaContext
return shell_cmd_id;
}
/********************************************************************
* - Add a command to Shell environment: write_fabric_hierarchy
* - Add associated options
* - Add command dependency
*******************************************************************/
static
ShellCommandId add_openfpga_write_fabric_hierarchy_command(openfpga::Shell<OpenfpgaContext>& shell,
const ShellCommandClassId& cmd_class_id,
const std::vector<ShellCommandId>& dependent_cmds) {
Command shell_cmd("write_fabric_hierarchy");
/* Add an option '--file' */
CommandOptionId opt_file = shell_cmd.add_option("file", true, "Specify the file name to write the hierarchy to");
shell_cmd.set_option_short_name(opt_file, "f");
shell_cmd.set_option_require_value(opt_file, openfpga::OPT_STRING);
/* Add an option '--verbose' */
shell_cmd.add_option("verbose", false, "Show verbose outputs");
/* Add command 'write_fabric_hierarchy' to the Shell */
ShellCommandId shell_cmd_id = shell.add_command(shell_cmd, "Write the hierarchy of FPGA fabric graph to a plain-text file");
shell.set_command_class(shell_cmd_id, cmd_class_id);
shell.set_command_const_execute_function(shell_cmd_id, write_fabric_hierarchy);
/* Add command dependency to the Shell */
shell.set_command_dependency(shell_cmd_id, dependent_cmds);
return shell_cmd_id;
}
void add_openfpga_setup_commands(openfpga::Shell<OpenfpgaContext>& shell) {
/* Get the unique id of 'vpr' command which is to be used in creating the dependency graph */
const ShellCommandId& vpr_cmd_id = shell.command(std::string("vpr"));
@ -317,9 +348,19 @@ void add_openfpga_setup_commands(openfpga::Shell<OpenfpgaContext>& shell) {
/* The 'build_fabric' command should NOT be executed before 'link_openfpga_arch' */
std::vector<ShellCommandId> build_fabric_dependent_cmds;
build_fabric_dependent_cmds.push_back(link_arch_cmd_id);
add_openfpga_build_fabric_command(shell,
openfpga_setup_cmd_class,
build_fabric_dependent_cmds);
ShellCommandId build_fabric_cmd_id = add_openfpga_build_fabric_command(shell,
openfpga_setup_cmd_class,
build_fabric_dependent_cmds);
/********************************
* Command 'write_fabric_hierarchy'
*/
/* The 'write_fabric_hierarchy' command should NOT be executed before 'build_fabric' */
std::vector<ShellCommandId> write_fabric_hie_dependent_cmds;
write_fabric_hie_dependent_cmds.push_back(build_fabric_cmd_id);
add_openfpga_write_fabric_hierarchy_command(shell,
openfpga_setup_cmd_class,
write_fabric_hie_dependent_cmds);
}
} /* end namespace openfpga */

View File

@ -0,0 +1,129 @@
/***************************************************************************************
* 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,
const ModuleManager& module_manager,
const ModuleId& parent_module,
const bool& verbose) {
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, hie_depth)) {
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 << module_manager.module_name(child_module);
fp << "\n";
/* Go to next level */
int status = rec_output_module_hierarchy_to_text_file(fp,
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 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;
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 + 1, /* Start with level 1 */
module_manager,
top_module,
verbose);
/* close a file */
fp.close();
return err_code;
}
} /* end namespace openfpga */

View File

@ -0,0 +1,23 @@
#ifndef FABRIC_HIERARCHY_WRITER_H
#define FABRIC_HIERARCHY_WRITER_H
/********************************************************************
* Include header files that are required by function declaration
*******************************************************************/
#include "vpr_context.h"
#include "openfpga_context.h"
/********************************************************************
* Function declaration
*******************************************************************/
/* begin namespace openfpga */
namespace openfpga {
int write_fabric_hierarchy_to_text_file(const ModuleManager& module_manager,
const std::string& fname,
const bool& verbose);
} /* end namespace openfpga */
#endif

View File

@ -24,6 +24,8 @@ lut_truth_table_fixup #--verbose
# - Enable pin duplication on grid modules
build_fabric --compress_routing --duplicate_grid_pin #--verbose
write_fabric_hierarchy --file ./fabric_hierarchy.txt
# Repack the netlist to physical pbs
# This must be done before bitstream generator and testbench generation
# Strongly recommend it is done after all the fix-up have been applied