Add command report_reference

This commit is contained in:
Victor 2024-09-02 15:21:50 +08:00
parent feefc04d14
commit 0093d4b269
4 changed files with 205 additions and 6 deletions

View File

@ -24,6 +24,7 @@
#include "vtr_log.h"
#include "vtr_time.h"
#include "write_xml_fabric_pin_physical_location.h"
#include "report_reference.h"
#include "write_xml_module_name_map.h"
/* begin namespace openfpga */
@ -472,6 +473,39 @@ int write_fabric_pin_physical_location_template(
cmd_context.option_enable(cmd, opt_verbose));
}
/********************************************************************
* Report reference to a file
*******************************************************************/
template <class T>
int report_reference_template(
const T& openfpga_ctx, const Command& cmd,
const CommandContext& cmd_context) {
CommandOptionId opt_verbose = cmd.option("verbose");
CommandOptionId opt_no_time_stamp = cmd.option("no_time_stamp");
/* 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 file_name = cmd_context.option_value(cmd, opt_file);
std::string module_name("*"); /* Use a wildcard for everything */
CommandOptionId opt_module = cmd.option("module");
if (true == cmd_context.option_enable(cmd, opt_module)) {
module_name = cmd_context.option_value(cmd, opt_module);
}
/* Write hierarchy to a file */
return report_reference(
file_name.c_str(), module_name, openfpga_ctx.module_graph(),
!cmd_context.option_enable(cmd, opt_no_time_stamp),
cmd_context.option_enable(cmd, opt_verbose));
}
} /* end namespace openfpga */
#endif

View File

@ -710,12 +710,6 @@ ShellCommandId add_route_clock_rr_graph_command_template(
shell_cmd.set_option_short_name(opt_file, "pcf");
shell_cmd.set_option_require_value(opt_file, openfpga::OPT_STRING);
shell_cmd.add_option("disable_unused_trees", false,
"Disable entire clock trees when they are not used by "
"any clock nets. Useful to reduce clock power");
shell_cmd.add_option("disable_unused_spines", false,
"Disable part of the clock tree which are used by clock "
"nets. Useful to reduce clock power");
/* Add an option '--verbose' */
shell_cmd.add_option("verbose", false, "Show verbose outputs");
@ -930,6 +924,50 @@ ShellCommandId add_write_fabric_pin_physical_location_command_template(
return shell_cmd_id;
}
/********************************************************************
* - Add a command to Shell environment: report_reference
* - Add associated options
* - Add command dependency
*******************************************************************/
template <class T>
ShellCommandId add_report_reference_command_template(
openfpga::Shell<T>& shell, const ShellCommandClassId& cmd_class_id,
const std::vector<ShellCommandId>& dependent_cmds, const bool& hidden) {
Command shell_cmd("report_reference");
/* Add an option '--file' in short '-f'*/
CommandOptionId opt_file = shell_cmd.add_option(
"file", true,
"specify the file to output results");
shell_cmd.set_option_short_name(opt_file, "f");
shell_cmd.set_option_require_value(opt_file, openfpga::OPT_STRING);
/* Add an option '--module'*/
CommandOptionId opt_module = shell_cmd.add_option(
"module", false,
"specify the module under which the references of child modules will be reported");
shell_cmd.set_option_require_value(opt_module, openfpga::OPT_STRING);
/* Add an option '--no_time_stamp' */
shell_cmd.add_option("no_time_stamp", false,
"Do not print time stamp in output files");
shell_cmd.add_option("verbose", false, "Show verbose outputs");
/* Add command to the Shell */
ShellCommandId shell_cmd_id = shell.add_command(
shell_cmd,
"report the number of instances for each unique module, under a given module",
hidden);
shell.set_command_class(shell_cmd_id, cmd_class_id);
shell.set_command_const_execute_function(
shell_cmd_id, report_reference_template<T>);
/* Add command dependency to the Shell */
shell.set_command_dependency(shell_cmd_id, dependent_cmds);
return shell_cmd_id;
}
template <class T>
void add_setup_command_templates(openfpga::Shell<T>& shell,
const bool& hidden = false) {
@ -1181,6 +1219,17 @@ void add_setup_command_templates(openfpga::Shell<T>& shell,
add_write_fabric_pin_physical_location_command_template<T>(
shell, openfpga_setup_cmd_class,
cmd_dependency_write_fabric_pin_physical_location, hidden);
/********************************
* Command 'report_reference'
*/
/* The command should NOT be executed before 'build_fabric' */
std::vector<ShellCommandId> cmd_dependency_report_reference;
cmd_dependency_report_reference.push_back(
build_fabric_cmd_id);
add_report_reference_command_template<T>(
shell, openfpga_setup_cmd_class,
cmd_dependency_report_reference, hidden);
}
} /* end namespace openfpga */

View File

@ -0,0 +1,92 @@
/***************************************************************************************
* Output internal structure of module graph to XML format
***************************************************************************************/
/* Headers from system goes first */
#include <algorithm>
#include <chrono>
#include <ctime>
#include <string>
#include <iomanip>
/* Headers from vtrutil library */
#include "vtr_assert.h"
#include "vtr_log.h"
#include "vtr_time.h"
/* Headers from openfpgautil library */
#include "command_exit_codes.h"
#include "openfpga_digest.h"
#include "report_reference.h"
/* begin namespace openfpga */
namespace openfpga {
/********************************************************************
* Top-level function
*******************************************************************/
int report_reference(const char* fname,
const std::string& module_name,
const ModuleManager& module_manager,
const bool& include_time_stamp,
const bool& verbose) {
vtr::ScopedStartFinishTimer timer("Report reference");
std::fstream fp;
fp.open(std::string(fname), std::fstream::out | std::fstream::trunc);
openfpga::check_file_stream(fname, fp);
if (include_time_stamp) {
auto end = std::chrono::system_clock::now();
std::time_t end_time = std::chrono::system_clock::to_time_t(end);
fp << "Date: " << std::ctime(&end_time) << std::endl;
}
ModuleId parent_module = module_manager.find_module(module_name);
if (ModuleId::INVALID() == parent_module){
VTR_LOG_ERROR("Module %s doesn't exist\n", module_name.c_str());
return CMD_EXEC_MINOR_ERROR;
}
if (module_manager.child_modules(parent_module).size() < 1){
VTR_LOG_ERROR("Module %s hasn't any child module\n", module_name.c_str());
return CMD_EXEC_MINOR_ERROR;
}
VTR_LOG("------------------------------------------------------------------------------\n");
VTR_LOG("Module Reference count\n");
VTR_LOG("------------------------------------------------------------------------------\n");
size_t ref_cnt = 0;
for (ModuleId child_module : module_manager.child_modules(parent_module)){
std::string child_module_name = module_manager.module_name(child_module);
std::vector<size_t> child_inst_vec = module_manager.child_module_instances(parent_module, child_module);
for (size_t pos = 0; pos < child_module_name.length(); pos += 70){
if (pos > 0) VTR_LOG("\n");
VTR_LOG("%-70s", child_module_name.substr(pos).c_str());
}
VTR_LOG(" %7d\n", child_inst_vec.size());
ref_cnt += child_inst_vec.size();
}
VTR_LOG("------------------------------------------------------------------------------\n");
VTR_LOG("Total %zu modules %zu references\n", module_manager.child_modules(parent_module).size(), ref_cnt);
VTR_LOG("------------------------------------------------------------------------------\n");
fp << "references:" << std::endl;
for (ModuleId child_module : module_manager.child_modules(parent_module)){
std::string child_module_name = module_manager.module_name(child_module);
std::vector<size_t> child_inst_vec = module_manager.child_module_instances(parent_module, child_module);
fp << "- module: " << child_module_name.c_str() << "\n"
<< " reference count: " << child_inst_vec.size() << "\n"
<< " instances:" << "\n";
for (size_t inst_id : child_inst_vec){
std::string inst_name = module_manager.instance_name(parent_module, child_module, inst_id);
fp << " - " << inst_name.c_str() << "\n";
}
}
fp.close();
return CMD_EXEC_SUCCESS;
}
} /* end namespace openfpga */

View File

@ -0,0 +1,24 @@
#ifndef REPORT_REFERENCE_H
#define REPORT_REFERENCE_H
/********************************************************************
* Include header files that are required by function declaration
*******************************************************************/
#include <string>
#include "module_manager.h"
/********************************************************************
* Function declaration
*******************************************************************/
/* begin namespace openfpga */
namespace openfpga {
int report_reference(const char* fname,
const std::string& module_name,
const ModuleManager& module_manager,
const bool& include_time_stamp,
const bool& verbose);
} /* end namespace openfpga */
#endif