From 0093d4b269ca368a6241393a12f6a8125e8de1c7 Mon Sep 17 00:00:00 2001 From: Victor Date: Mon, 2 Sep 2024 15:21:50 +0800 Subject: [PATCH] Add command report_reference --- .../src/base/openfpga_build_fabric_template.h | 34 +++++++ .../base/openfpga_setup_command_template.h | 61 ++++++++++-- openfpga/src/utils/report_reference.cpp | 92 +++++++++++++++++++ openfpga/src/utils/report_reference.h | 24 +++++ 4 files changed, 205 insertions(+), 6 deletions(-) create mode 100644 openfpga/src/utils/report_reference.cpp create mode 100644 openfpga/src/utils/report_reference.h diff --git a/openfpga/src/base/openfpga_build_fabric_template.h b/openfpga/src/base/openfpga_build_fabric_template.h index b36903a22..988ac3117 100644 --- a/openfpga/src/base/openfpga_build_fabric_template.h +++ b/openfpga/src/base/openfpga_build_fabric_template.h @@ -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 +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 diff --git a/openfpga/src/base/openfpga_setup_command_template.h b/openfpga/src/base/openfpga_setup_command_template.h index 53e43f00f..3f66c9ebe 100644 --- a/openfpga/src/base/openfpga_setup_command_template.h +++ b/openfpga/src/base/openfpga_setup_command_template.h @@ -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 +ShellCommandId add_report_reference_command_template( + openfpga::Shell& shell, const ShellCommandClassId& cmd_class_id, + const std::vector& 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); + + /* Add command dependency to the Shell */ + shell.set_command_dependency(shell_cmd_id, dependent_cmds); + + return shell_cmd_id; +} + template void add_setup_command_templates(openfpga::Shell& shell, const bool& hidden = false) { @@ -1181,6 +1219,17 @@ void add_setup_command_templates(openfpga::Shell& shell, add_write_fabric_pin_physical_location_command_template( 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 cmd_dependency_report_reference; + cmd_dependency_report_reference.push_back( + build_fabric_cmd_id); + add_report_reference_command_template( + shell, openfpga_setup_cmd_class, + cmd_dependency_report_reference, hidden); } } /* end namespace openfpga */ diff --git a/openfpga/src/utils/report_reference.cpp b/openfpga/src/utils/report_reference.cpp new file mode 100644 index 000000000..e7e0cf9b7 --- /dev/null +++ b/openfpga/src/utils/report_reference.cpp @@ -0,0 +1,92 @@ +/*************************************************************************************** + * Output internal structure of module graph to XML format + ***************************************************************************************/ +/* Headers from system goes first */ +#include +#include +#include +#include +#include + +/* 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 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 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 */ diff --git a/openfpga/src/utils/report_reference.h b/openfpga/src/utils/report_reference.h new file mode 100644 index 000000000..6bed89b90 --- /dev/null +++ b/openfpga/src/utils/report_reference.h @@ -0,0 +1,24 @@ +#ifndef REPORT_REFERENCE_H +#define REPORT_REFERENCE_H + +/******************************************************************** + * Include header files that are required by function declaration + *******************************************************************/ +#include + +#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