diff --git a/openfpga/src/vpr_wrapper/vpr_command.cpp b/openfpga/src/vpr_wrapper/vpr_command.cpp index fd4b4d4c6..0f0782b52 100644 --- a/openfpga/src/vpr_wrapper/vpr_command.cpp +++ b/openfpga/src/vpr_wrapper/vpr_command.cpp @@ -18,9 +18,19 @@ void add_vpr_commands(openfpga::Shell& shell) { ShellCommandId shell_cmd_vpr_id = shell.add_command(shell_cmd_vpr, "Start VPR core engine to pack, place and route a BLIF " - "design on a FPGA architecture"); + "design on a FPGA architecture; Note that this command will keep VPR results!"); shell.set_command_class(shell_cmd_vpr_id, vpr_cmd_class); - shell.set_command_execute_function(shell_cmd_vpr_id, vpr::vpr); + shell.set_command_execute_function(shell_cmd_vpr_id, vpr::vpr_wrapper); + + /* Create a macro command of 'vpr_standalone' which will call the main engine of vpr in a standalone way + */ + Command shell_cmd_vpr_stdalone("vpr_standalone"); + ShellCommandId shell_cmd_vpr_stdalone_id = + shell.add_command(shell_cmd_vpr, + "Start a standalone VPR core engine to pack, place and route a BLIF " + "design on a FPGA architecture; Note that this command will NOT keep VPR results!"); + shell.set_command_class(shell_cmd_vpr_stdalone_id, vpr_cmd_class); + shell.set_command_execute_function(shell_cmd_vpr_stdalone_id, vpr::vpr_standalone_wrapper); } } /* end namespace openfpga */ diff --git a/openfpga/src/vpr_wrapper/vpr_main.cpp b/openfpga/src/vpr_wrapper/vpr_main.cpp index 0ed10398a..8f9d00394 100644 --- a/openfpga/src/vpr_wrapper/vpr_main.cpp +++ b/openfpga/src/vpr_wrapper/vpr_main.cpp @@ -19,10 +19,12 @@ #include "vtr_log.h" #include "vtr_memory.h" #include "vtr_time.h" +#include "command_exit_codes.h" namespace vpr { /** + * VPR program without clean up * VPR program * Generate FPGA architecture given architecture description * Pack, place, and route circuit into FPGA architecture @@ -34,6 +36,7 @@ namespace vpr { * 3. Place-and-route and timing analysis * 4. Clean up */ +static int vpr(int argc, char** argv) { vtr::ScopedFinishTimer t("The entire flow of VPR"); @@ -93,4 +96,86 @@ int vpr(int argc, char** argv) { return SUCCESS_EXIT_CODE; } +/* A wrapper to return proper codes for openfpga shell */ +int vpr_wrapper(int argc, char** argv) { + if (SUCCESS_EXIT_CODE != vpr(argc, argv)) { + return openfpga::CMD_EXEC_FATAL_ERROR; + } + return openfpga::CMD_EXEC_SUCCESS; +} + +/** + * VPR program with clean up + */ +static +int vpr_standalone(int argc, char** argv) { + vtr::ScopedFinishTimer t("The entire flow of VPR"); + + t_options Options = t_options(); + t_arch Arch = t_arch(); + t_vpr_setup vpr_setup = t_vpr_setup(); + + try { + vpr_install_signal_handler(); + + /* Read options, architecture, and circuit netlist */ + vpr_init(argc, const_cast(argv), &Options, &vpr_setup, &Arch); + + if (Options.show_version) { + vpr_free_all(Arch, vpr_setup); + return SUCCESS_EXIT_CODE; + } + + bool flow_succeeded = vpr_flow(vpr_setup, Arch); + if (!flow_succeeded) { + VTR_LOG("VPR failed to implement circuit\n"); + vpr_free_all(Arch, vpr_setup); + return UNIMPLEMENTABLE_EXIT_CODE; + } + + auto& timing_ctx = g_vpr_ctx.timing(); + print_timing_stats("Flow", timing_ctx.stats); + + /* free data structures */ + vpr_free_all(Arch, vpr_setup); + + VTR_LOG("VPR succeeded\n"); + + } catch (const tatum::Error& tatum_error) { + VTR_LOG_ERROR("%s\n", format_tatum_error(tatum_error).c_str()); + vpr_free_all(Arch, vpr_setup); + + return ERROR_EXIT_CODE; + + } catch (const VprError& vpr_error) { + vpr_print_error(vpr_error); + + if (vpr_error.type() == VPR_ERROR_INTERRUPTED) { + vpr_free_all(Arch, vpr_setup); + return INTERRUPTED_EXIT_CODE; + } else { + vpr_free_all(Arch, vpr_setup); + return ERROR_EXIT_CODE; + } + + } catch (const vtr::VtrError& vtr_error) { + VTR_LOG_ERROR("%s:%d %s\n", vtr_error.filename_c_str(), vtr_error.line(), vtr_error.what()); + vpr_free_all(Arch, vpr_setup); + + return ERROR_EXIT_CODE; + } + + /* Signal success to scripts */ + return SUCCESS_EXIT_CODE; +} + +/* A wrapper to return proper codes for openfpga shell */ +int vpr_standalone_wrapper(int argc, char** argv) { + if (SUCCESS_EXIT_CODE != vpr_standalone(argc, argv)) { + return openfpga::CMD_EXEC_FATAL_ERROR; + } + return openfpga::CMD_EXEC_SUCCESS; +} + + } /* End namespace vpr */ diff --git a/openfpga/src/vpr_wrapper/vpr_main.h b/openfpga/src/vpr_wrapper/vpr_main.h index 056a4732f..3105b09ea 100644 --- a/openfpga/src/vpr_wrapper/vpr_main.h +++ b/openfpga/src/vpr_wrapper/vpr_main.h @@ -4,7 +4,9 @@ /* Begin namespace vpr */ namespace vpr { -int vpr(int argc, char** argv); +int vpr_wrapper(int argc, char** argv); + +int vpr_standalone_wrapper(int argc, char** argv); } /* End namespace vpr */