add fabric hierarchy writer
This commit is contained in:
parent
0985c720e9
commit
6aff33dd35
|
@ -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 */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
|
@ -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
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue