Merge pull request #1815 from lnis-uofu/victor_OpenFPGA_dbg

Add command report_reference
This commit is contained in:
tangxifan 2024-09-10 10:03:31 -07:00 committed by GitHub
commit 3517bc1856
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 422 additions and 0 deletions

View File

@ -45,3 +45,5 @@ OpenFPGA widely uses XML format for interchangeable files
fabric_pin_physical_location_file
fabric_hierarchy_file
reference_file

View File

@ -0,0 +1,80 @@
.. _file_format_reference_file:
Reference File (.yaml)
----------------------------------------
This file is generated by command :ref:`openfpga_setup_commands_report_reference`
The reference file aims to the show reference number of each child module of given parent module
By using the options of the command :ref:`openfpga_setup_commands_report_reference`, user can selectively output the reference info under the given parent module on their needs.
An example of the file is shown as follows.
.. code-block:: yaml
Date: Mon Sep 9 16:41:53 2024
#the instance names are given during netlist generation
references:
- module: grid_io_top
count: 1
instances:
- grid_io_top_1__2_
- module: grid_io_right
count: 1
instances:
- grid_io_right_2__1_
- module: grid_io_bottom
count: 1
instances:
- grid_io_bottom_1__0_
- module: grid_io_left
count: 1
instances:
- grid_io_left_0__1_
- module: grid_clb
count: 1
instances:
- grid_clb_1__1_
- module: sb_0__0_
count: 1
instances:
- sb_0__0_
- module: sb_0__1_
count: 1
instances:
- sb_0__1_
- module: sb_1__0_
count: 1
instances:
- sb_1__0_
- module: sb_1__1_
count: 1
instances:
- sb_1__1_
- module: cbx_1__0_
count: 1
instances:
- cbx_1__0_
- module: cbx_1__1_
count: 1
instances:
- cbx_1__1_
- module: cby_0__1_
count: 1
instances:
- cby_0__1_
- module: cby_1__1_
count: 1
instances:
- cby_1__1_
direct_interc
In this example, the parent module is ``fpga_top``.
The child modules under ``fpga_top`` are ``grid_io_top``, ``grid_io_right``, and etc.
The instance of the child module ``grid_io_top`` is shown as a list as below:
- grid_io_top_1__2_

View File

@ -525,3 +525,26 @@ write_fabric_pin_physical_location
.. option:: --verbose
Show verbose log
.. _openfpga_setup_commands_report_reference:
report_reference
~~~~~~~~~~~~~~~~~~~~
Write reference information of each child module under a given parent module to a YAML file
.. option:: --file <string> or -f <string>
Specify the file name to write the reference information
.. option:: --module <string>
Specify the parent module name, under which the references of each child module will be reported.
.. option:: --no_time_stamp
Do not print time stamp in output files
.. option:: --verbose
Show verbose info

View File

@ -21,6 +21,7 @@
#include "read_xml_module_name_map.h"
#include "read_xml_tile_config.h"
#include "rename_modules.h"
#include "report_reference.h"
#include "vtr_log.h"
#include "vtr_time.h"
#include "write_xml_fabric_pin_physical_location.h"
@ -472,6 +473,38 @@ 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

@ -937,6 +937,51 @@ 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 all instances of 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) {
@ -1188,6 +1233,15 @@ 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,123 @@
/***************************************************************************************
* Output internal structure of module graph to XML format
***************************************************************************************/
/* Headers from system goes first */
#include <algorithm>
#include <chrono>
#include <ctime>
#include <iomanip>
#include <string>
/* 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 "openfpga_naming.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");
ModuleId parent_module = module_manager.find_module(module_name);
if (false == module_manager.valid_module_id(parent_module)) {
VTR_LOG_ERROR("Module %s doesn't exist\n", module_name.c_str());
return CMD_EXEC_FATAL_ERROR;
}
show_reference_count(parent_module, module_manager);
return write_reference_to_file(fname, parent_module, module_manager,
include_time_stamp, verbose);
}
/********************************************************************
* show reference count of each child module under given parent module
*******************************************************************/
void show_reference_count(const ModuleId& parent_module,
const ModuleManager& module_manager) {
VTR_LOG(
"----------------------------------------------------------------------\n");
VTR_LOG(
"Module 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);
VTR_LOG("%-s %d\n", child_module_name.c_str(), 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");
}
/********************************************************************
* write reference info to a given file in YAML format
*******************************************************************/
int write_reference_to_file(const char* fname, const ModuleId& parent_module,
const ModuleManager& module_manager,
const bool& include_time_stamp,
const bool& verbose) {
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;
}
fp << "#the instance names are given during netlist generation" << std::endl;
size_t ref_cnt = 0;
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() << std::endl
<< " count: " << child_inst_vec.size() << std::endl
<< " instances:" << std::endl;
for (size_t inst_id : child_inst_vec) {
std::string inst_name =
module_manager.instance_name(parent_module, child_module, inst_id);
fp << " - ";
if (true == inst_name.empty()) {
fp << generate_instance_name(child_module_name, inst_id) << std::endl;
} else {
fp << inst_name << std::endl;
}
}
ref_cnt += child_inst_vec.size();
}
if (verbose) {
fp << std::endl
<< "Total: " << module_manager.child_modules(parent_module).size()
<< " modules " << ref_cnt << " references" << std::endl;
}
fp.close();
return CMD_EXEC_SUCCESS;
}
} /* end namespace openfpga */

View File

@ -0,0 +1,30 @@
#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);
void show_reference_count(const ModuleId& parent_module,
const ModuleManager& module_manager);
int write_reference_to_file(const char* fname, const ModuleId& parent_module,
const ModuleManager& module_manager,
const bool& include_time_stamp,
const bool& verbose);
} /* end namespace openfpga */
#endif

View File

@ -0,0 +1,37 @@
# Run VPR for the 'and' design
#--write_rr_graph example_rr_graph.xml
vpr ${VPR_ARCH_FILE} ${VPR_TESTBENCH_BLIF} --clock_modeling route --absorb_buffer_luts off
# Read OpenFPGA architecture definition
read_openfpga_arch -f ${OPENFPGA_ARCH_FILE}
# Read OpenFPGA simulation settings
read_openfpga_simulation_setting -f ${OPENFPGA_SIM_SETTING_FILE}
# Annotate the OpenFPGA architecture to VPR data base
# to debug use --verbose options
link_openfpga_arch --activity_file ${ACTIVITY_FILE} --sort_gsb_chan_node_in_edges
# Check and correct any naming conflicts in the BLIF netlist
check_netlist_naming_conflict --fix --report ./netlist_renaming.xml
# Apply fix-up to Look-Up Table truth tables based on packing results
lut_truth_table_fixup
# Build the module graph
# - Enabled compression on routing architecture modules
# - Enabled frame view creation to save runtime and memory
# Note that this is turned on when bitstream generation
# is the ONLY purpose of the flow!!!
build_fabric --compress_routing --frame_view #--verbose
# Report reference to a file
report_reference ${OPENFPGA_REPORT_REFERENCE_MODULE_OPTIONS}
report_reference ${OPENFPGA_REPORT_REFERENCE_VERBOSE_OPTIONS}
report_reference ${OPENFPGA_REPORT_REFERENCE_NO_TIME_STAMP_OPTIONS}
# Finish and exit OpenFPGA
exit
# Note :
# To run verification at the end of the flow maintain source in ./SRC directory

View File

@ -315,6 +315,10 @@ run-task basic_tests/no_time_stamp/device_1x1 $@
run-task basic_tests/no_time_stamp/device_4x4 $@
run-task basic_tests/no_time_stamp/no_cout_in_gsb $@
run-task basic_tests/no_time_stamp/dump_waveform $@
echo -e "Testing report reference to file";
run-task basic_tests/report_reference $@
# Run git-diff to ensure no changes on the golden netlists
# Switch to root path in case users are running the tests in another location
cd ${OPENFPGA_PATH}

View File

@ -0,0 +1,36 @@
# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
# Configuration file for running experiments
# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
# timeout_each_job : FPGA Task script splits fpga flow into multiple jobs
# Each job execute fpga_flow script on combination of architecture & benchmark
# timeout_each_job is timeout for each job
# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
[GENERAL]
run_engine=openfpga_shell
power_tech_file = ${PATH:OPENFPGA_PATH}/openfpga_flow/tech/PTM_45nm/45nm.xml
power_analysis = true
spice_output=false
verilog_output=true
timeout_each_job = 20*60
fpga_flow=yosys_vpr
[OpenFPGA_SHELL]
openfpga_shell_template=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_shell_scripts/report_reference_example_script.openfpga
openfpga_arch_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_arch/k6_frac_N10_40nm_openfpga.xml
openfpga_sim_setting_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_simulation_settings/auto_sim_openfpga.xml
openfpga_report_reference_module_options=--file reference_module.yaml --module fpga_top
openfpga_report_reference_verbose_options=--file reference_verbose.yaml --module fpga_top --verbose
openfpga_report_reference_no_time_stamp_options=--file reference_no_time_stamp.yaml --module grid_io_right --no_time_stamp
[ARCHITECTURES]
arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/vpr_arch/k6_frac_N10_tileable_40nm.xml
[BENCHMARKS]
bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2/and2.v
[SYNTHESIS_PARAM]
bench_read_verilog_options_common = -nolatches
bench0_top = and2
[SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH]