Merge pull request #968 from lnis-uofu/vpr_single_step
Now VPR can be run independently in OpenFPGA shell
This commit is contained in:
commit
2931e03d86
|
@ -8,4 +8,28 @@ vpr
|
|||
|
||||
OpenFPGA allows users to call ``vpr`` in the standard way as documented in the vtr_project_.
|
||||
|
||||
.. note:: This command will run vpr in a standalone way, whose results will be kept and used by other commands. Suggest to use when this is the final run of VPR.
|
||||
|
||||
For example, vpr commands may be called in the following way:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
# VPR standalone runs, no results will be kept for downstream commands
|
||||
vpr_standalone <some_options>
|
||||
vpr_standalone <some_options>
|
||||
# More standalone runs may be expected
|
||||
vpr_standalone <some_options>
|
||||
# Final VPR run, results are kept for downstream commands
|
||||
vpr <some_options>
|
||||
# Other commands that use VPR results
|
||||
|
||||
.. _vtr_project: https://github.com/verilog-to-routing/vtr-verilog-to-routing
|
||||
|
||||
vpr_standalone
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
OpenFPGA allows users to call ``vpr`` in the standard way as documented in the vtr_project_.
|
||||
|
||||
.. note:: This command will run vpr in a standalone way, whose results will **not** be kept and **not** used by other commands. Suggest to use when only some stages of VPR are needed.
|
||||
|
||||
.. _vtr_project: https://github.com/verilog-to-routing/vtr-verilog-to-routing
|
||||
|
|
|
@ -18,9 +18,23 @@ void add_vpr_commands(openfpga::Shell<OpenfpgaContext>& 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_stdalone,
|
||||
"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 */
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include <cstring>
|
||||
#include <ctime>
|
||||
|
||||
#include "command_exit_codes.h"
|
||||
#include "globals.h"
|
||||
#include "tatum/error.hpp"
|
||||
#include "vpr_api.h"
|
||||
|
@ -23,6 +24,7 @@
|
|||
namespace vpr {
|
||||
|
||||
/**
|
||||
* VPR program without clean up
|
||||
* VPR program
|
||||
* Generate FPGA architecture given architecture description
|
||||
* Pack, place, and route circuit into FPGA architecture
|
||||
|
@ -34,7 +36,7 @@ namespace vpr {
|
|||
* 3. Place-and-route and timing analysis
|
||||
* 4. Clean up
|
||||
*/
|
||||
int vpr(int argc, char** argv) {
|
||||
static int vpr(int argc, char** argv) {
|
||||
vtr::ScopedFinishTimer t("The entire flow of VPR");
|
||||
|
||||
t_options Options = t_options();
|
||||
|
@ -93,4 +95,85 @@ 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<const char**>(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 */
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -0,0 +1,80 @@
|
|||
# Run VPR for the 'and' design
|
||||
# Run packing stage only
|
||||
vpr_standalone ${VPR_ARCH_FILE} ${VPR_TESTBENCH_BLIF} --pack --device ${OPENFPGA_VPR_DEVICE_LAYOUT} --route_chan_width ${OPENFPGA_VPR_ROUTE_CHAN_WIDTH}
|
||||
# Run placement stage only
|
||||
vpr_standalone ${VPR_ARCH_FILE} ${VPR_TESTBENCH_BLIF} --place --device ${OPENFPGA_VPR_DEVICE_LAYOUT} --route_chan_width ${OPENFPGA_VPR_ROUTE_CHAN_WIDTH}
|
||||
# Run routing
|
||||
vpr_standalone ${VPR_ARCH_FILE} ${VPR_TESTBENCH_BLIF} --route --device ${OPENFPGA_VPR_DEVICE_LAYOUT} --route_chan_width ${OPENFPGA_VPR_ROUTE_CHAN_WIDTH}
|
||||
|
||||
# Run analysis as final results
|
||||
vpr ${VPR_ARCH_FILE} ${VPR_TESTBENCH_BLIF} --analysis --device ${OPENFPGA_VPR_DEVICE_LAYOUT} --route_chan_width ${OPENFPGA_VPR_ROUTE_CHAN_WIDTH}
|
||||
|
||||
# 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
|
||||
# - Enable pin duplication on grid modules
|
||||
build_fabric --compress_routing #--verbose
|
||||
|
||||
# Write the fabric hierarchy of module graph to a file
|
||||
# This is used by hierarchical PnR flows
|
||||
write_fabric_hierarchy --file ./fabric_hierarchy.txt
|
||||
|
||||
# Repack the netlist to physical pbs
|
||||
# This must be done before bitstream generator and testbench generation
|
||||
# Strongly recommend it is done after all the fix-up have been applied
|
||||
repack #--verbose
|
||||
|
||||
# Build the bitstream
|
||||
# - Output the fabric-independent bitstream to a file
|
||||
build_architecture_bitstream --verbose --write_file fabric_independent_bitstream.xml
|
||||
|
||||
# Build fabric-dependent bitstream
|
||||
build_fabric_bitstream --verbose
|
||||
|
||||
# Write fabric-dependent bitstream
|
||||
write_fabric_bitstream --file fabric_bitstream.bit --format plain_text
|
||||
|
||||
# Write the Verilog netlist for FPGA fabric
|
||||
# - Enable the use of explicit port mapping in Verilog netlist
|
||||
write_fabric_verilog --file ./SRC --explicit_port_mapping --include_timing --print_user_defined_template --verbose
|
||||
|
||||
# Write the Verilog testbench for FPGA fabric
|
||||
# - We suggest the use of same output directory as fabric Verilog netlists
|
||||
# - Must specify the reference benchmark file if you want to output any testbenches
|
||||
# - Enable top-level testbench which is a full verification including programming circuit and core logic of FPGA
|
||||
# - Enable pre-configured top-level testbench which is a fast verification skipping programming phase
|
||||
# - Simulation ini file is optional and is needed only when you need to interface different HDL simulators using openfpga flow-run scripts
|
||||
write_full_testbench --file ./SRC --reference_benchmark_file_path ${REFERENCE_VERILOG_TESTBENCH} --explicit_port_mapping --include_signal_init --bitstream fabric_bitstream.bit
|
||||
write_preconfigured_fabric_wrapper --embed_bitstream iverilog --file ./SRC --explicit_port_mapping
|
||||
write_preconfigured_testbench --file ./SRC --reference_benchmark_file_path ${REFERENCE_VERILOG_TESTBENCH} --explicit_port_mapping
|
||||
|
||||
# Write the SDC files for PnR backend
|
||||
# - Turn on every options here
|
||||
write_pnr_sdc --file ./SDC
|
||||
|
||||
# Write SDC to disable timing for configure ports
|
||||
write_sdc_disable_timing_configure_ports --file ./SDC/disable_configure_ports.sdc
|
||||
|
||||
# Write the SDC to run timing analysis for a mapped FPGA fabric
|
||||
write_analysis_sdc --file ./SDC_analysis
|
||||
|
||||
# Finish and exit OpenFPGA
|
||||
exit
|
||||
|
||||
# Note :
|
||||
# To run verification at the end of the flow maintain source in ./SRC directory
|
|
@ -8,6 +8,9 @@ PYTHON_EXEC=python3.8
|
|||
##############################################
|
||||
echo -e "Basic regression tests";
|
||||
|
||||
echo -e "Test multiple runs of vpr"
|
||||
run-task basic_tests/vpr_standalone $@
|
||||
|
||||
echo -e "Testing configuration chain of a K4N4 FPGA";
|
||||
run-task basic_tests/full_testbench/configuration_chain $@
|
||||
run-task basic_tests/full_testbench/configuration_chain_no_time_stamp $@
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
|
||||
# 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/vpr_standalone_example_script.openfpga
|
||||
openfpga_arch_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_arch/k4_N4_40nm_cc_openfpga.xml
|
||||
openfpga_sim_setting_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_simulation_settings/auto_sim_openfpga.xml
|
||||
openfpga_vpr_device_layout=2x2
|
||||
openfpga_vpr_route_chan_width=20
|
||||
|
||||
[ARCHITECTURES]
|
||||
arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/vpr_arch/k4_N4_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]
|
||||
end_flow_with_test=
|
||||
vpr_fpga_verilog_formal_verification_top_netlist=
|
Loading…
Reference in New Issue