diff --git a/openfpga/src/base/openfpga_verilog.cpp b/openfpga/src/base/openfpga_verilog.cpp index f62c9da71..f3b6a7d9a 100644 --- a/openfpga/src/base/openfpga_verilog.cpp +++ b/openfpga/src/base/openfpga_verilog.cpp @@ -250,5 +250,32 @@ int write_preconfigured_testbench(const OpenfpgaContext& openfpga_ctx, options); } +/******************************************************************** + * A wrapper function to call the simulation task information generator of FPGA-Verilog + *******************************************************************/ +int write_simulation_task_info(const OpenfpgaContext& openfpga_ctx, + const Command& cmd, const CommandContext& cmd_context) { + + CommandOptionId opt_output_dir = cmd.option("file"); + CommandOptionId opt_reference_benchmark = cmd.option("reference_benchmark_file_path"); + CommandOptionId opt_verbose = cmd.option("verbose"); + + /* This is an intermediate data structure which is designed to modularize the FPGA-Verilog + * Keep it independent from any other outside data structures + */ + VerilogTestbenchOption options; + options.set_reference_benchmark_file_path(cmd_context.option_value(cmd, opt_reference_benchmark)); + options.set_verbose_output(cmd_context.option_enable(cmd, opt_verbose)); + options.set_print_simulation_ini(cmd_context.option_value(cmd, opt_output_dir)); + + return fpga_verilog_simulation_task_info(openfpga_ctx.module_graph(), + openfpga_ctx.bitstream_manager(), + g_vpr_ctx.atom(), + g_vpr_ctx.placement(), + openfpga_ctx.io_location_map(), + openfpga_ctx.simulation_setting(), + openfpga_ctx.arch().config_protocol, + options); +} } /* end namespace openfpga */ diff --git a/openfpga/src/base/openfpga_verilog.h b/openfpga/src/base/openfpga_verilog.h index d7c0b5404..7789335a8 100644 --- a/openfpga/src/base/openfpga_verilog.h +++ b/openfpga/src/base/openfpga_verilog.h @@ -30,6 +30,9 @@ int write_preconfigured_fabric_wrapper(const OpenfpgaContext& openfpga_ctx, int write_preconfigured_testbench(const OpenfpgaContext& openfpga_ctx, const Command& cmd, const CommandContext& cmd_context); +int write_simulation_task_info(const OpenfpgaContext& openfpga_ctx, + const Command& cmd, const CommandContext& cmd_context); + } /* end namespace openfpga */ #endif diff --git a/openfpga/src/base/openfpga_verilog_command.cpp b/openfpga/src/base/openfpga_verilog_command.cpp index f9d4acc65..72115e987 100644 --- a/openfpga/src/base/openfpga_verilog_command.cpp +++ b/openfpga/src/base/openfpga_verilog_command.cpp @@ -265,6 +265,40 @@ ShellCommandId add_openfpga_write_preconfigured_testbench_command(openfpga::Shel return shell_cmd_id; } +/******************************************************************** + * - Add a command to Shell environment: write simulation task info + * - Add associated options + * - Add command dependency + *******************************************************************/ +static +ShellCommandId add_openfpga_write_simulation_task_info_command(openfpga::Shell& shell, + const ShellCommandClassId& cmd_class_id, + const std::vector& dependent_cmds) { + Command shell_cmd("write_simulation_task_info"); + + /* Add an option '--file' in short '-f'*/ + CommandOptionId output_opt = shell_cmd.add_option("file", true, "Specify the file path to output simulation-related information"); + shell_cmd.set_option_short_name(output_opt, "f"); + shell_cmd.set_option_require_value(output_opt, openfpga::OPT_STRING); + + /* Add an option '--reference_benchmark_file_path'*/ + CommandOptionId ref_bm_opt = shell_cmd.add_option("reference_benchmark_file_path", true, "Specify the file path to the reference Verilog netlist"); + shell_cmd.set_option_require_value(ref_bm_opt, openfpga::OPT_STRING); + + /* Add an option '--verbose' */ + shell_cmd.add_option("verbose", false, "Enable verbose output"); + + /* Add command to the Shell */ + ShellCommandId shell_cmd_id = shell.add_command(shell_cmd, "generate an interchangable simulation task configuration file"); + shell.set_command_class(shell_cmd_id, cmd_class_id); + shell.set_command_execute_function(shell_cmd_id, write_simulation_task_info); + + /* Add command dependency to the Shell */ + shell.set_command_dependency(shell_cmd_id, dependent_cmds); + + return shell_cmd_id; +} + void add_openfpga_verilog_commands(openfpga::Shell& shell) { /* Get the unique id of 'build_fabric' command which is to be used in creating the dependency graph */ const ShellCommandId& build_fabric_cmd_id = shell.command(std::string("build_fabric")); @@ -322,6 +356,15 @@ void add_openfpga_verilog_commands(openfpga::Shell& shell) { openfpga_verilog_cmd_class, preconfig_testbench_dependent_cmds); + /******************************** + * Command 'write_simulation_task_info' + */ + /* The command 'write_simulation_task_info' should NOT be executed before 'build_fabric' */ + std::vector sim_task_info_dependent_cmds; + sim_task_info_dependent_cmds.push_back(build_fabric_cmd_id); + add_openfpga_write_simulation_task_info_command(shell, + openfpga_verilog_cmd_class, + sim_task_info_dependent_cmds); } } /* end namespace openfpga */ diff --git a/openfpga/src/fpga_verilog/verilog_api.cpp b/openfpga/src/fpga_verilog/verilog_api.cpp index 3c1624c1a..d7ed62f64 100644 --- a/openfpga/src/fpga_verilog/verilog_api.cpp +++ b/openfpga/src/fpga_verilog/verilog_api.cpp @@ -407,5 +407,47 @@ int fpga_verilog_preconfigured_testbench(const ModuleManager &module_manager, return status; } +/******************************************************************** + * A top-level function of FPGA-Verilog which focuses on fabric Verilog generation + * This function will generate + * - An interchangable file containing simulation task configuration + ********************************************************************/ +int fpga_verilog_simulation_task_info(const ModuleManager &module_manager, + const BitstreamManager &bitstream_manager, + const AtomContext &atom_ctx, + const PlacementContext &place_ctx, + const IoLocationMap &io_location_map, + const SimulationSetting &simulation_setting, + const ConfigProtocol &config_protocol, + const VerilogTestbenchOption &options) { + + vtr::ScopedStartFinishTimer timer("Write interchangeable simulation task configuration\n"); + + std::string src_dir_path = format_dir_path(options.output_directory()); + + std::string netlist_name = atom_ctx.nlist.netlist_name(); + + int status = CMD_EXEC_SUCCESS; + + /* Create directories */ + create_directory(src_dir_path); + + /* Generate exchangeable files which contains simulation settings */ + std::string simulation_ini_file_name = options.simulation_ini_path(); + VTR_ASSERT(true != options.simulation_ini_path().empty()); + print_verilog_simulation_info(simulation_ini_file_name, + netlist_name, + src_dir_path, + atom_ctx, place_ctx, io_location_map, + module_manager, + config_protocol.type(), + bitstream_manager.num_bits(), + simulation_setting.num_clock_cycles(), + simulation_setting.programming_clock_frequency(), + simulation_setting.default_operating_clock_frequency()); + + return status; +} + } /* end namespace openfpga */ diff --git a/openfpga/src/fpga_verilog/verilog_api.h b/openfpga/src/fpga_verilog/verilog_api.h index da6685f3b..0bfb397f8 100644 --- a/openfpga/src/fpga_verilog/verilog_api.h +++ b/openfpga/src/fpga_verilog/verilog_api.h @@ -92,6 +92,15 @@ int fpga_verilog_preconfigured_testbench(const ModuleManager &module_manager, const SimulationSetting &simulation_setting, const VerilogTestbenchOption &options); +int fpga_verilog_simulation_task_info(const ModuleManager &module_manager, + const BitstreamManager &bitstream_manager, + const AtomContext &atom_ctx, + const PlacementContext &place_ctx, + const IoLocationMap &io_location_map, + const SimulationSetting &simulation_setting, + const ConfigProtocol &config_protocol, + const VerilogTestbenchOption &options); + } /* end namespace openfpga */ #endif