[Tool] Add a new command 'write_preconfigured_fabric_wrapper'

This commit is contained in:
tangxifan 2021-06-08 21:28:16 -06:00
parent 5075c68418
commit 8db19c7af9
5 changed files with 180 additions and 26 deletions

View File

@ -122,7 +122,7 @@ int write_verilog_testbench(OpenfpgaContext& openfpga_ctx,
/******************************************************************** /********************************************************************
* A wrapper function to call the full testbench generator of FPGA-Verilog * A wrapper function to call the full testbench generator of FPGA-Verilog
*******************************************************************/ *******************************************************************/
int write_full_testbench(OpenfpgaContext& openfpga_ctx, int write_full_testbench(const OpenfpgaContext& openfpga_ctx,
const Command& cmd, const CommandContext& cmd_context) { const Command& cmd, const CommandContext& cmd_context) {
CommandOptionId opt_output_dir = cmd.option("file"); CommandOptionId opt_output_dir = cmd.option("file");
@ -170,5 +170,45 @@ int write_full_testbench(OpenfpgaContext& openfpga_ctx,
options); options);
} }
/********************************************************************
* A wrapper function to call the preconfigured wrapper generator of FPGA-Verilog
*******************************************************************/
int write_preconfigured_fabric_wrapper(const OpenfpgaContext& openfpga_ctx,
const Command& cmd, const CommandContext& cmd_context) {
CommandOptionId opt_output_dir = cmd.option("file");
CommandOptionId opt_fabric_netlist = cmd.option("fabric_netlist_file_path");
CommandOptionId opt_pcf = cmd.option("pin_constraints_file");
CommandOptionId opt_explicit_port_mapping = cmd.option("explicit_port_mapping");
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_output_directory(cmd_context.option_value(cmd, opt_output_dir));
options.set_fabric_netlist_file_path(cmd_context.option_value(cmd, opt_fabric_netlist));
options.set_explicit_port_mapping(cmd_context.option_enable(cmd, opt_explicit_port_mapping));
options.set_verbose_output(cmd_context.option_enable(cmd, opt_verbose));
options.set_print_formal_verification_top_netlist(true);
/* If pin constraints are enabled by command options, read the file */
PinConstraints pin_constraints;
if (true == cmd_context.option_enable(cmd, opt_pcf)) {
pin_constraints = read_xml_pin_constraints(cmd_context.option_value(cmd, opt_pcf).c_str());
}
return fpga_verilog_preconfigured_fabric_wrapper(openfpga_ctx.module_graph(),
openfpga_ctx.bitstream_manager(),
g_vpr_ctx.atom(),
g_vpr_ctx.placement(),
pin_constraints,
openfpga_ctx.io_location_map(),
openfpga_ctx.fabric_global_port_info(),
openfpga_ctx.vpr_netlist_annotation(),
openfpga_ctx.arch().circuit_lib,
openfpga_ctx.arch().config_protocol,
options);
}
} /* end namespace openfpga */ } /* end namespace openfpga */

View File

@ -21,7 +21,10 @@ int write_fabric_verilog(OpenfpgaContext& openfpga_ctx,
int write_verilog_testbench(OpenfpgaContext& openfpga_ctx, int write_verilog_testbench(OpenfpgaContext& openfpga_ctx,
const Command& cmd, const CommandContext& cmd_context); const Command& cmd, const CommandContext& cmd_context);
int write_full_testbench(OpenfpgaContext& openfpga_ctx, int write_full_testbench(const OpenfpgaContext& openfpga_ctx,
const Command& cmd, const CommandContext& cmd_context);
int write_preconfigured_fabric_wrapper(const OpenfpgaContext& openfpga_ctx,
const Command& cmd, const CommandContext& cmd_context); const Command& cmd, const CommandContext& cmd_context);
} /* end namespace openfpga */ } /* end namespace openfpga */

View File

@ -123,9 +123,9 @@ ShellCommandId add_openfpga_write_verilog_testbench_command(openfpga::Shell<Open
} }
/******************************************************************** /********************************************************************
* - Add a command to Shell environment: write full testbench * - add a command to shell environment: write full testbench
* - Add associated options * - add associated options
* - Add command dependency * - add command dependency
*******************************************************************/ *******************************************************************/
static static
ShellCommandId add_openfpga_write_full_testbench_command(openfpga::Shell<OpenfpgaContext>& shell, ShellCommandId add_openfpga_write_full_testbench_command(openfpga::Shell<OpenfpgaContext>& shell,
@ -133,46 +133,88 @@ ShellCommandId add_openfpga_write_full_testbench_command(openfpga::Shell<Openfpg
const std::vector<ShellCommandId>& dependent_cmds) { const std::vector<ShellCommandId>& dependent_cmds) {
Command shell_cmd("write_full_testbench"); Command shell_cmd("write_full_testbench");
/* Add an option '--file' in short '-f'*/ /* add an option '--file' in short '-f'*/
CommandOptionId output_opt = shell_cmd.add_option("file", true, "Specify the output directory for HDL netlists"); CommandOptionId output_opt = shell_cmd.add_option("file", true, "specify the output directory for hdl netlists");
shell_cmd.set_option_short_name(output_opt, "f"); shell_cmd.set_option_short_name(output_opt, "f");
shell_cmd.set_option_require_value(output_opt, openfpga::OPT_STRING); shell_cmd.set_option_require_value(output_opt, openfpga::OPT_STRING);
/* Add an option '--bitstream'*/ /* add an option '--bitstream'*/
CommandOptionId bitstream_opt = shell_cmd.add_option("bitstream", true, "Specify the bitstream to be loaded in the testbench"); CommandOptionId bitstream_opt = shell_cmd.add_option("bitstream", true, "specify the bitstream to be loaded in the testbench");
shell_cmd.set_option_require_value(bitstream_opt, openfpga::OPT_STRING); shell_cmd.set_option_require_value(bitstream_opt, openfpga::OPT_STRING);
/* Add an option '--fabric_netlist_file_path'*/ /* add an option '--fabric_netlist_file_path'*/
CommandOptionId fabric_netlist_opt = shell_cmd.add_option("fabric_netlist_file_path", false, "Specify the file path to the fabric HDL netlist"); CommandOptionId fabric_netlist_opt = shell_cmd.add_option("fabric_netlist_file_path", false, "specify the file path to the fabric hdl netlist");
shell_cmd.set_option_require_value(fabric_netlist_opt, openfpga::OPT_STRING); shell_cmd.set_option_require_value(fabric_netlist_opt, openfpga::OPT_STRING);
/* Add an option '--pin_constraints_file in short '-pcf' */ /* add an option '--pin_constraints_file in short '-pcf' */
CommandOptionId pcf_opt = shell_cmd.add_option("pin_constraints_file", false, "Specify the file path to the pin constraints"); CommandOptionId pcf_opt = shell_cmd.add_option("pin_constraints_file", false, "specify the file path to the pin constraints");
shell_cmd.set_option_short_name(pcf_opt, "pcf"); shell_cmd.set_option_short_name(pcf_opt, "pcf");
shell_cmd.set_option_require_value(pcf_opt, openfpga::OPT_STRING); shell_cmd.set_option_require_value(pcf_opt, openfpga::OPT_STRING);
/* Add an option '--reference_benchmark_file_path'*/ /* 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"); 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); shell_cmd.set_option_require_value(ref_bm_opt, openfpga::OPT_STRING);
/* Add an option '--fast_configuration' */ /* add an option '--fast_configuration' */
shell_cmd.add_option("fast_configuration", false, "Reduce the period of configuration by skip certain data points"); shell_cmd.add_option("fast_configuration", false, "reduce the period of configuration by skip certain data points");
/* Add an option '--explicit_port_mapping' */ /* add an option '--explicit_port_mapping' */
shell_cmd.add_option("explicit_port_mapping", false, "Use explicit port mapping in Verilog netlists"); shell_cmd.add_option("explicit_port_mapping", false, "use explicit port mapping in verilog netlists");
/* Add an option '--include_signal_init' */ /* add an option '--include_signal_init' */
shell_cmd.add_option("include_signal_init", false, "Initialize all the signals in Verilog testbenches"); shell_cmd.add_option("include_signal_init", false, "initialize all the signals in verilog testbenches");
/* Add an option '--verbose' */ /* add an option '--verbose' */
shell_cmd.add_option("verbose", false, "Enable verbose output"); shell_cmd.add_option("verbose", false, "enable verbose output");
/* Add command to the Shell */ /* add command to the shell */
ShellCommandId shell_cmd_id = shell.add_command(shell_cmd, "generate full testbenches for an FPGA fabric"); ShellCommandId shell_cmd_id = shell.add_command(shell_cmd, "generate full testbenches for an fpga fabric");
shell.set_command_class(shell_cmd_id, cmd_class_id); shell.set_command_class(shell_cmd_id, cmd_class_id);
shell.set_command_execute_function(shell_cmd_id, write_full_testbench); shell.set_command_execute_function(shell_cmd_id, write_full_testbench);
/* Add command dependency to the Shell */ /* add command dependency to the shell */
shell.set_command_dependency(shell_cmd_id, dependent_cmds);
return shell_cmd_id;
}
/********************************************************************
* - add a command to shell environment: write preconfigured fabric wrapper
* - add associated options
* - add command dependency
*******************************************************************/
static
ShellCommandId add_openfpga_write_preconfigured_fabric_wrapper_command(openfpga::Shell<OpenfpgaContext>& shell,
const ShellCommandClassId& cmd_class_id,
const std::vector<ShellCommandId>& dependent_cmds) {
Command shell_cmd("write_preconfigured_fabric_wrapper");
/* add an option '--file' in short '-f'*/
CommandOptionId output_opt = shell_cmd.add_option("file", true, "specify the output directory for hdl netlists");
shell_cmd.set_option_short_name(output_opt, "f");
shell_cmd.set_option_require_value(output_opt, openfpga::OPT_STRING);
/* add an option '--fabric_netlist_file_path'*/
CommandOptionId fabric_netlist_opt = shell_cmd.add_option("fabric_netlist_file_path", false, "specify the file path to the fabric hdl netlist");
shell_cmd.set_option_require_value(fabric_netlist_opt, openfpga::OPT_STRING);
/* add an option '--pin_constraints_file in short '-pcf' */
CommandOptionId pcf_opt = shell_cmd.add_option("pin_constraints_file", false, "specify the file path to the pin constraints");
shell_cmd.set_option_short_name(pcf_opt, "pcf");
shell_cmd.set_option_require_value(pcf_opt, openfpga::OPT_STRING);
/* add an option '--explicit_port_mapping' */
shell_cmd.add_option("explicit_port_mapping", false, "use explicit port mapping in verilog netlists");
/* 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 a wrapper for a pre-configured fpga fabric");
shell.set_command_class(shell_cmd_id, cmd_class_id);
shell.set_command_execute_function(shell_cmd_id, write_preconfigured_fabric_wrapper);
/* add command dependency to the shell */
shell.set_command_dependency(shell_cmd_id, dependent_cmds); shell.set_command_dependency(shell_cmd_id, dependent_cmds);
return shell_cmd_id; return shell_cmd_id;
@ -214,6 +256,17 @@ void add_openfpga_verilog_commands(openfpga::Shell<OpenfpgaContext>& shell) {
add_openfpga_write_full_testbench_command(shell, add_openfpga_write_full_testbench_command(shell,
openfpga_verilog_cmd_class, openfpga_verilog_cmd_class,
full_testbench_dependent_cmds); full_testbench_dependent_cmds);
/********************************
* Command 'write_preconfigured_fabric_wrapper'
*/
/* The command 'write_preconfigured_fabric_wrapper' should NOT be executed before 'build_fabric' */
std::vector<ShellCommandId> preconfig_wrapper_dependent_cmds;
preconfig_wrapper_dependent_cmds.push_back(build_fabric_cmd_id);
add_openfpga_write_preconfigured_fabric_wrapper_command(shell,
openfpga_verilog_cmd_class,
preconfig_wrapper_dependent_cmds);
} }
} /* end namespace openfpga */ } /* end namespace openfpga */

View File

@ -313,4 +313,49 @@ int fpga_verilog_full_testbench(const ModuleManager &module_manager,
return status; return status;
} }
/********************************************************************
* A top-level function of FPGA-Verilog which focuses on full testbench generation
* This function will generate
* - A wrapper module, which encapsulate the FPGA module in a Verilog module which have the same port as the input benchmark
********************************************************************/
int fpga_verilog_preconfigured_fabric_wrapper(const ModuleManager &module_manager,
const BitstreamManager &bitstream_manager,
const AtomContext &atom_ctx,
const PlacementContext &place_ctx,
const PinConstraints& pin_constraints,
const IoLocationMap &io_location_map,
const FabricGlobalPortInfo &fabric_global_port_info,
const VprNetlistAnnotation &netlist_annotation,
const CircuitLibrary &circuit_lib,
const ConfigProtocol &config_protocol,
const VerilogTestbenchOption &options) {
vtr::ScopedStartFinishTimer timer("Write a wrapper module for a preconfigured FPGA fabric\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 wrapper module for FPGA fabric (mapped by the input benchmark and pre-configured testbench for verification */
std::string formal_verification_top_netlist_file_path = src_dir_path + netlist_name + std::string(FORMAL_VERIFICATION_VERILOG_FILE_POSTFIX);
status = print_verilog_preconfig_top_module(module_manager, bitstream_manager,
config_protocol,
circuit_lib, fabric_global_port_info,
atom_ctx, place_ctx,
pin_constraints,
io_location_map,
netlist_annotation,
netlist_name,
formal_verification_top_netlist_file_path,
options.explicit_port_mapping());
return status;
}
} /* end namespace openfpga */ } /* end namespace openfpga */

View File

@ -72,6 +72,19 @@ int fpga_verilog_full_testbench(const ModuleManager& module_manager,
const ConfigProtocol& config_protocol, const ConfigProtocol& config_protocol,
const VerilogTestbenchOption& options); const VerilogTestbenchOption& options);
int fpga_verilog_preconfigured_fabric_wrapper(const ModuleManager &module_manager,
const BitstreamManager &bitstream_manager,
const AtomContext &atom_ctx,
const PlacementContext &place_ctx,
const PinConstraints& pin_constraints,
const IoLocationMap &io_location_map,
const FabricGlobalPortInfo &fabric_global_port_info,
const VprNetlistAnnotation &netlist_annotation,
const CircuitLibrary &circuit_lib,
const ConfigProtocol &config_protocol,
const VerilogTestbenchOption &options);
} /* end namespace openfpga */ } /* end namespace openfpga */
#endif #endif