From 77dddaeb398ad67397e166a85d9e15b69035cf52 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Tue, 29 Jun 2021 14:26:33 -0600 Subject: [PATCH 01/19] [Tool] Remove the preprocessing flags ``FORMAL_SIMULATION`` and ``FORMAL_VERIFICAITON`` because now ``write_testbench`` command can be called many times to generate different versions --- openfpga/src/fpga_verilog/verilog_api.cpp | 16 ++-- .../verilog_auxiliary_netlists.cpp | 92 ++++++++++++------- .../fpga_verilog/verilog_auxiliary_netlists.h | 13 ++- openfpga/src/fpga_verilog/verilog_constants.h | 2 - .../verilog_preconfig_top_module.cpp | 3 +- .../fpga_verilog/verilog_testbench_utils.cpp | 34 ++++--- .../fpga_verilog/verilog_testbench_utils.h | 3 +- .../fpga_verilog/verilog_top_testbench.cpp | 3 +- 8 files changed, 96 insertions(+), 70 deletions(-) diff --git a/openfpga/src/fpga_verilog/verilog_api.cpp b/openfpga/src/fpga_verilog/verilog_api.cpp index df9cf46fc..a63132e36 100644 --- a/openfpga/src/fpga_verilog/verilog_api.cpp +++ b/openfpga/src/fpga_verilog/verilog_api.cpp @@ -192,10 +192,10 @@ int fpga_verilog_full_testbench(const ModuleManager &module_manager, options); /* Generate a Verilog file including all the netlists that have been generated */ - print_verilog_testbench_include_netlists(src_dir_path, - netlist_name, - options.fabric_netlist_file_path(), - options.reference_benchmark_file_path()); + print_verilog_full_testbench_include_netlists(src_dir_path, + netlist_name, + options.fabric_netlist_file_path(), + options.reference_benchmark_file_path()); return status; } @@ -286,10 +286,10 @@ int fpga_verilog_preconfigured_testbench(const ModuleManager &module_manager, options); /* Generate a Verilog file including all the netlists that have been generated */ - print_verilog_testbench_include_netlists(src_dir_path, - netlist_name, - options.fabric_netlist_file_path(), - options.reference_benchmark_file_path()); + print_verilog_preconfigured_testbench_include_netlists(src_dir_path, + netlist_name, + options.fabric_netlist_file_path(), + options.reference_benchmark_file_path()); return status; } diff --git a/openfpga/src/fpga_verilog/verilog_auxiliary_netlists.cpp b/openfpga/src/fpga_verilog/verilog_auxiliary_netlists.cpp index a3ac9c580..bd0d55114 100644 --- a/openfpga/src/fpga_verilog/verilog_auxiliary_netlists.cpp +++ b/openfpga/src/fpga_verilog/verilog_auxiliary_netlists.cpp @@ -90,14 +90,14 @@ void print_verilog_fabric_include_netlist(const NetlistManager& netlist_manager, /******************************************************************** * Print a file that includes all the netlists - * including the fabric netlists and testbenches + * including the fabric netlists and full testbenches * that have been generated and user-defined. * Some netlists are open to compile under specific preprocessing flags *******************************************************************/ -void print_verilog_testbench_include_netlists(const std::string& src_dir, - const std::string& circuit_name, - const std::string& fabric_netlist_file, - const std::string& reference_benchmark_file) { +void print_verilog_full_testbench_include_netlists(const std::string& src_dir, + const std::string& circuit_name, + const std::string& fabric_netlist_file, + const std::string& reference_benchmark_file) { std::string verilog_fname = src_dir + circuit_name + std::string(TOP_VERILOG_TESTBENCH_INCLUDE_NETLIST_FILE_NAME_POSTFIX); /* Create the file stream */ @@ -132,28 +132,62 @@ void print_verilog_testbench_include_netlists(const std::string& src_dir, print_verilog_endif(fp); fp << std::endl; - /* Include formal verification netlists only when formal verification flag is enable */ - print_verilog_preprocessing_flag(fp, std::string(VERILOG_FORMAL_VERIFICATION_PREPROC_FLAG)); + /* Include top-level testbench only when auto-check flag is enabled */ + print_verilog_include_netlist(fp, src_dir + circuit_name + std::string(AUTOCHECK_TOP_TESTBENCH_VERILOG_FILE_POSTFIX)); + + /* Close the file stream */ + fp.close(); +} + +/******************************************************************** + * Print a file that includes all the netlists + * including the fabric netlists and preconfigured testbenches + * that have been generated and user-defined. + * Some netlists are open to compile under specific preprocessing flags + *******************************************************************/ +void print_verilog_preconfigured_testbench_include_netlists(const std::string& src_dir, + const std::string& circuit_name, + const std::string& fabric_netlist_file, + const std::string& reference_benchmark_file) { + std::string verilog_fname = src_dir + circuit_name + std::string(TOP_VERILOG_TESTBENCH_INCLUDE_NETLIST_FILE_NAME_POSTFIX); + + /* Create the file stream */ + std::fstream fp; + fp.open(verilog_fname, std::fstream::out | std::fstream::trunc); + + /* Validate the file stream */ + check_file_stream(verilog_fname.c_str(), fp); + + /* Print the title */ + print_verilog_file_header(fp, std::string("Netlist Summary")); + + /* Print preprocessing flags */ + print_verilog_comment(fp, std::string("------ Include simulation defines -----")); + print_verilog_include_netlist(fp, src_dir + std::string(DEFINES_VERILOG_SIMULATION_FILE_NAME)); + fp << std::endl; + + /* Include FPGA top module */ + print_verilog_comment(fp, std::string("------ Include fabric top-level netlists -----")); + if (true == fabric_netlist_file.empty()) { + print_verilog_include_netlist(fp, src_dir + std::string(FABRIC_INCLUDE_VERILOG_NETLIST_FILE_NAME)); + } else { + VTR_ASSERT_SAFE(false == fabric_netlist_file.empty()); + print_verilog_include_netlist(fp, fabric_netlist_file); + } + fp << std::endl; + + /* Include reference benchmark netlist only when auto-check flag is enabled */ + print_verilog_preprocessing_flag(fp, std::string(AUTOCHECKED_SIMULATION_FLAG)); fp << "\t"; - print_verilog_include_netlist(fp, src_dir + circuit_name + std::string(FORMAL_VERIFICATION_VERILOG_FILE_POSTFIX)); - - /* Include formal verification testbench only when formal simulation flag is enabled */ - fp << "\t"; - print_verilog_preprocessing_flag(fp, std::string(FORMAL_SIMULATION_FLAG)); - fp << "\t\t"; - print_verilog_include_netlist(fp, src_dir + circuit_name + std::string(RANDOM_TOP_TESTBENCH_VERILOG_FILE_POSTFIX)); - fp << "\t"; - print_verilog_endif(fp); - + print_verilog_include_netlist(fp, std::string(reference_benchmark_file)); print_verilog_endif(fp); fp << std::endl; - /* Include top-level testbench only when auto-check flag is enabled */ - print_verilog_preprocessing_flag(fp, std::string(AUTOCHECKED_SIMULATION_FLAG)); - fp << "\t"; - print_verilog_include_netlist(fp, src_dir + circuit_name + std::string(AUTOCHECK_TOP_TESTBENCH_VERILOG_FILE_POSTFIX)); - print_verilog_endif(fp); - fp << std::endl; + /* Include formal verification netlists */ + print_verilog_include_netlist(fp, src_dir + circuit_name + std::string(FORMAL_VERIFICATION_VERILOG_FILE_POSTFIX)); + + /* Include formal verification testbench */ + print_verilog_include_netlist(fp, src_dir + circuit_name + std::string(RANDOM_TOP_TESTBENCH_VERILOG_FILE_POSTFIX)); /* Close the file stream */ fp.close(); @@ -213,18 +247,6 @@ void print_verilog_simulation_preprocessing_flags(const std::string& src_dir, fp << std::endl; } - /* To enable pre-configured FPGA simulation */ - if (true == verilog_testbench_opts.print_formal_verification_top_netlist()) { - print_verilog_define_flag(fp, std::string(VERILOG_FORMAL_VERIFICATION_PREPROC_FLAG), 1); - fp << std::endl; - } - - /* To enable pre-configured FPGA simulation */ - if (true == verilog_testbench_opts.print_preconfig_top_testbench()) { - print_verilog_define_flag(fp, std::string(FORMAL_SIMULATION_FLAG), 1); - fp << std::endl; - } - /* Close the file stream */ fp.close(); } diff --git a/openfpga/src/fpga_verilog/verilog_auxiliary_netlists.h b/openfpga/src/fpga_verilog/verilog_auxiliary_netlists.h index 0fdf2338b..e206a478b 100644 --- a/openfpga/src/fpga_verilog/verilog_auxiliary_netlists.h +++ b/openfpga/src/fpga_verilog/verilog_auxiliary_netlists.h @@ -21,10 +21,15 @@ void print_verilog_fabric_include_netlist(const NetlistManager& netlist_manager, const std::string& src_dir, const CircuitLibrary& circuit_lib); -void print_verilog_testbench_include_netlists(const std::string& src_dir, - const std::string& circuit_name, - const std::string& fabric_netlist_file, - const std::string& reference_benchmark_file); +void print_verilog_full_testbench_include_netlists(const std::string& src_dir, + const std::string& circuit_name, + const std::string& fabric_netlist_file, + const std::string& reference_benchmark_file); + +void print_verilog_preconfigured_testbench_include_netlists(const std::string& src_dir, + const std::string& circuit_name, + const std::string& fabric_netlist_file, + const std::string& reference_benchmark_file); void print_verilog_preprocessing_flags_netlist(const std::string& src_dir, const FabricVerilogOption& fabric_verilog_opts); diff --git a/openfpga/src/fpga_verilog/verilog_constants.h b/openfpga/src/fpga_verilog/verilog_constants.h index 18e23b721..aea360206 100644 --- a/openfpga/src/fpga_verilog/verilog_constants.h +++ b/openfpga/src/fpga_verilog/verilog_constants.h @@ -7,9 +7,7 @@ constexpr char* VERILOG_NETLIST_FILE_POSTFIX = ".v"; constexpr float VERILOG_SIM_TIMESCALE = 1e-9; // Verilog Simulation time scale (minimum time unit) : 1ns constexpr char* VERILOG_TIMING_PREPROC_FLAG = "ENABLE_TIMING"; // the flag to enable timing definition during compilation -constexpr char* VERILOG_FORMAL_VERIFICATION_PREPROC_FLAG = "ENABLE_FORMAL_VERIFICATION"; // the flag to enable formal verification during compilation constexpr char* AUTOCHECKED_SIMULATION_FLAG = "AUTOCHECKED_SIMULATION"; // the flag to enable autochecked functional verification -constexpr char* FORMAL_SIMULATION_FLAG = "FORMAL_SIMULATION"; // the flag to enable formal functional verification constexpr char* MODELSIM_SIMULATION_TIME_UNIT = "ms"; diff --git a/openfpga/src/fpga_verilog/verilog_preconfig_top_module.cpp b/openfpga/src/fpga_verilog/verilog_preconfig_top_module.cpp index 4c7a8d2bf..e797151a8 100644 --- a/openfpga/src/fpga_verilog/verilog_preconfig_top_module.cpp +++ b/openfpga/src/fpga_verilog/verilog_preconfig_top_module.cpp @@ -493,7 +493,8 @@ int print_verilog_preconfig_top_module(const ModuleManager &module_manager, std::string(FORMAL_VERIFICATION_TOP_MODULE_UUT_NAME), circuit_lib, module_manager, - top_module); + top_module, + false); } /* Testbench ends*/ diff --git a/openfpga/src/fpga_verilog/verilog_testbench_utils.cpp b/openfpga/src/fpga_verilog/verilog_testbench_utils.cpp index dfb1b2468..cbebc5545 100644 --- a/openfpga/src/fpga_verilog/verilog_testbench_utils.cpp +++ b/openfpga/src/fpga_verilog/verilog_testbench_utils.cpp @@ -791,7 +791,8 @@ void rec_print_verilog_testbench_primitive_module_signal_initialization(std::fst const std::vector& circuit_input_ports, const ModuleManager& module_manager, const ModuleId& parent_module, - const ModuleId& primitive_module) { + const ModuleId& primitive_module, + const bool& deposit_random_values) { /* Validate the file stream */ valid_file_stream(fp); @@ -819,7 +820,8 @@ void rec_print_verilog_testbench_primitive_module_signal_initialization(std::fst child_hie_path, circuit_lib, circuit_model, circuit_input_ports, module_manager, child_module, - primitive_module); + primitive_module, + deposit_random_values); } else { /* If the child module is the primitive module, * we output the signal initialization codes for the input ports @@ -828,7 +830,6 @@ void rec_print_verilog_testbench_primitive_module_signal_initialization(std::fst print_verilog_comment(fp, std::string("------ BEGIN driver initialization -----")); fp << "\tinitial begin" << std::endl; - fp << "\t`ifdef " << VERILOG_FORMAL_VERIFICATION_PREPROC_FLAG << std::endl; for (const auto& input_port : circuit_input_ports) { /* Only for formal verification: deposite a zero signal values */ @@ -838,22 +839,17 @@ void rec_print_verilog_testbench_primitive_module_signal_initialization(std::fst fp << "\t\t$deposit("; fp << child_hie_path << "."; fp << generate_verilog_port(VERILOG_PORT_CONKT, input_port_info, false); - fp << ", " << circuit_lib.port_size(input_port) << "'b" << std::string(circuit_lib.port_size(input_port), '0'); - fp << ");" << std::endl; - } - fp << "\t`else" << std::endl; + + if (!deposit_random_values) { - /* Regular case: deposite initial signal values: a random value */ - for (const auto& input_port : circuit_input_ports) { - BasicPort input_port_info(circuit_lib.port_lib_name(input_port), circuit_lib.port_size(input_port)); - input_port_info.set_origin_port_width(input_port_info.get_width()); - fp << "\t\t$deposit("; - fp << child_hie_path << "."; - fp << generate_verilog_port(VERILOG_PORT_CONKT, input_port_info, false); - fp << ", $random % 2 ? 1'b1 : 1'b0);" << std::endl; + fp << ", " << circuit_lib.port_size(input_port) << "'b" << std::string(circuit_lib.port_size(input_port), '0'); + fp << ");" << std::endl; + } else { + VTR_ASSERT_SAFE(deposit_random_values); + fp << ", $random % 2 ? 1'b1 : 1'b0);" << std::endl; + } } - fp << "\t`endif\n" << std::endl; fp << "\tend" << std::endl; print_verilog_comment(fp, std::string("------ END driver initialization -----")); } @@ -871,7 +867,8 @@ void print_verilog_testbench_signal_initialization(std::fstream& fp, const std::string& top_instance_name, const CircuitLibrary& circuit_lib, const ModuleManager& module_manager, - const ModuleId& top_module) { + const ModuleId& top_module, + const bool& deposit_random_values) { /* Validate the file stream */ valid_file_stream(fp); @@ -921,7 +918,8 @@ void print_verilog_testbench_signal_initialization(std::fstream& fp, top_instance_name, circuit_lib, signal_init_circuit_model, signal_init_circuit_ports.at(signal_init_circuit_model), module_manager, top_module, - primitive_module); + primitive_module, + deposit_random_values); } } diff --git a/openfpga/src/fpga_verilog/verilog_testbench_utils.h b/openfpga/src/fpga_verilog/verilog_testbench_utils.h index 1f9567481..91ade1856 100644 --- a/openfpga/src/fpga_verilog/verilog_testbench_utils.h +++ b/openfpga/src/fpga_verilog/verilog_testbench_utils.h @@ -101,7 +101,8 @@ void print_verilog_testbench_signal_initialization(std::fstream& fp, const std::string& top_instance_name, const CircuitLibrary& circuit_lib, const ModuleManager& module_manager, - const ModuleId& top_module); + const ModuleId& top_module, + const bool& deposit_random_values); } /* end namespace openfpga */ diff --git a/openfpga/src/fpga_verilog/verilog_top_testbench.cpp b/openfpga/src/fpga_verilog/verilog_top_testbench.cpp index aecf72d6f..e5bdbcf01 100644 --- a/openfpga/src/fpga_verilog/verilog_top_testbench.cpp +++ b/openfpga/src/fpga_verilog/verilog_top_testbench.cpp @@ -2029,7 +2029,8 @@ int print_verilog_full_testbench(const ModuleManager& module_manager, std::string(TOP_TESTBENCH_FPGA_INSTANCE_NAME), circuit_lib, module_manager, - top_module); + top_module, + true); } From 7ac7de789e9b31d9e91784aa37210fa7bfc70671 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Tue, 29 Jun 2021 15:26:40 -0600 Subject: [PATCH 02/19] [Tool] Add a new option ``--no_self_checking`` so that users can output a simple testbench without self checking codes --- openfpga/src/base/openfpga_verilog.cpp | 4 + .../src/base/openfpga_verilog_command.cpp | 6 ++ openfpga/src/fpga_verilog/verilog_api.cpp | 14 +--- .../verilog_auxiliary_netlists.cpp | 67 ++++------------ .../fpga_verilog/verilog_auxiliary_netlists.h | 9 +-- openfpga/src/fpga_verilog/verilog_constants.h | 3 - .../verilog_formal_random_top_testbench.cpp | 60 +++++++-------- .../verilog_simulation_info_writer.cpp | 2 +- .../verilog_testbench_options.cpp | 8 ++ .../fpga_verilog/verilog_testbench_options.h | 3 + .../fpga_verilog/verilog_testbench_utils.cpp | 24 ++---- .../fpga_verilog/verilog_testbench_utils.h | 3 +- .../fpga_verilog/verilog_top_testbench.cpp | 77 ++++++++----------- 13 files changed, 113 insertions(+), 167 deletions(-) diff --git a/openfpga/src/base/openfpga_verilog.cpp b/openfpga/src/base/openfpga_verilog.cpp index b912c518c..16016a913 100644 --- a/openfpga/src/base/openfpga_verilog.cpp +++ b/openfpga/src/base/openfpga_verilog.cpp @@ -78,6 +78,7 @@ int write_full_testbench(const OpenfpgaContext& openfpga_ctx, CommandOptionId opt_fast_configuration = cmd.option("fast_configuration"); CommandOptionId opt_explicit_port_mapping = cmd.option("explicit_port_mapping"); CommandOptionId opt_default_net_type = cmd.option("default_net_type"); + CommandOptionId opt_no_self_checking = cmd.option("no_self_checking"); CommandOptionId opt_include_signal_init = cmd.option("include_signal_init"); CommandOptionId opt_verbose = cmd.option("verbose"); @@ -93,6 +94,7 @@ int write_full_testbench(const OpenfpgaContext& openfpga_ctx, options.set_verbose_output(cmd_context.option_enable(cmd, opt_verbose)); options.set_print_top_testbench(true); options.set_include_signal_init(cmd_context.option_enable(cmd, opt_include_signal_init)); + options.set_no_self_checking(cmd_context.option_enable(cmd, opt_no_self_checking)); if (true == cmd_context.option_enable(cmd, opt_default_net_type)) { options.set_default_net_type(cmd_context.option_value(cmd, opt_default_net_type)); } @@ -184,6 +186,7 @@ int write_preconfigured_testbench(const OpenfpgaContext& openfpga_ctx, CommandOptionId opt_reference_benchmark = cmd.option("reference_benchmark_file_path"); CommandOptionId opt_explicit_port_mapping = cmd.option("explicit_port_mapping"); CommandOptionId opt_default_net_type = cmd.option("default_net_type"); + CommandOptionId opt_no_self_checking = cmd.option("no_self_checking"); CommandOptionId opt_verbose = cmd.option("verbose"); /* This is an intermediate data structure which is designed to modularize the FPGA-Verilog @@ -196,6 +199,7 @@ int write_preconfigured_testbench(const OpenfpgaContext& openfpga_ctx, 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_preconfig_top_testbench(true); + options.set_no_self_checking(cmd_context.option_enable(cmd, opt_no_self_checking)); if (true == cmd_context.option_enable(cmd, opt_default_net_type)) { options.set_default_net_type(cmd_context.option_value(cmd, opt_default_net_type)); } diff --git a/openfpga/src/base/openfpga_verilog_command.cpp b/openfpga/src/base/openfpga_verilog_command.cpp index 95c146e03..3b0c94138 100644 --- a/openfpga/src/base/openfpga_verilog_command.cpp +++ b/openfpga/src/base/openfpga_verilog_command.cpp @@ -97,6 +97,9 @@ ShellCommandId add_openfpga_write_full_testbench_command(openfpga::Shell& clock_port_names, const AtomContext& atom_ctx, const VprNetlistAnnotation& netlist_annotation, - const e_verilog_default_net_type& default_net_type) { + const VerilogTestbenchOption& options) { /* Validate the file stream */ valid_file_stream(fp); print_verilog_default_net_type_declaration(fp, - default_net_type); + options.default_net_type()); /* Print the declaration for the module */ fp << "module " << circuit_name << FORMAL_RANDOM_TOP_TESTBENCH_POSTFIX << ";" << std::endl; @@ -84,16 +84,17 @@ void print_verilog_top_random_testbench_ports(std::fstream& fp, std::string(BENCHMARK_PORT_POSTFIX), std::string(FPGA_PORT_POSTFIX), std::string(CHECKFLAG_PORT_POSTFIX), - std::string(AUTOCHECKED_SIMULATION_FLAG)); + options.no_self_checking()); /* Instantiate an integer to count the number of error * and determine if the simulation succeed or failed */ - print_verilog_comment(fp, std::string("----- Error counter -------")); - fp << "\tinteger " << ERROR_COUNTER << "= 0;" << std::endl; - - /* Add an empty line as splitter */ - fp << std::endl; + if (!options.no_self_checking()) { + print_verilog_comment(fp, std::string("----- Error counter -------")); + fp << "\tinteger " << ERROR_COUNTER << "= 0;" << std::endl; + /* Add an empty line as splitter */ + fp << std::endl; + } } /******************************************************************** @@ -108,9 +109,7 @@ void print_verilog_top_random_testbench_benchmark_instance(std::fstream& fp, /* Validate the file stream */ valid_file_stream(fp); - /* Benchmark is instanciated conditionally: only when a preprocessing flag is enable */ - print_verilog_preprocessing_flag(fp, std::string(AUTOCHECKED_SIMULATION_FLAG)); - + /* Instanciate benchmark */ print_verilog_comment(fp, std::string("----- Reference Benchmark Instanication -------")); /* Do NOT use explicit port mapping here: @@ -132,12 +131,6 @@ void print_verilog_top_random_testbench_benchmark_instance(std::fstream& fp, /* Add an empty line as splitter */ fp << std::endl; - - /* Condition ends for the benchmark instanciation */ - print_verilog_endif(fp); - - /* Add an empty line as splitter */ - fp << std::endl; } /******************************************************************** @@ -300,7 +293,7 @@ void print_verilog_random_top_testbench(const std::string& circuit_name, std::vector clock_port_names = find_atom_netlist_clock_port_names(atom_ctx.nlist, netlist_annotation); /* Start of testbench */ - print_verilog_top_random_testbench_ports(fp, circuit_name, clock_port_names, atom_ctx, netlist_annotation, options.default_net_type()); + print_verilog_top_random_testbench_ports(fp, circuit_name, clock_port_names, atom_ctx, netlist_annotation, options); /* Call defined top-level module */ print_verilog_random_testbench_fpga_instance(fp, circuit_name, @@ -308,9 +301,11 @@ void print_verilog_random_top_testbench(const std::string& circuit_name, options.explicit_port_mapping()); /* Call defined benchmark */ - print_verilog_top_random_testbench_benchmark_instance(fp, circuit_name, - atom_ctx, netlist_annotation, - options.explicit_port_mapping()); + if (!options.no_self_checking()) { + print_verilog_top_random_testbench_benchmark_instance(fp, circuit_name, + atom_ctx, netlist_annotation, + options.explicit_port_mapping()); + } /* Find clock port to be used */ std::vector clock_ports = generate_verilog_testbench_clock_port(clock_port_names, std::string(DEFAULT_CLOCK_NAME)); @@ -341,17 +336,18 @@ void print_verilog_random_top_testbench(const std::string& circuit_name, std::string(CHECKFLAG_PORT_POSTFIX), clock_ports); - print_verilog_testbench_check(fp, - std::string(AUTOCHECKED_SIMULATION_FLAG), - std::string(FORMAL_TB_SIM_START_PORT_NAME), - std::string(BENCHMARK_PORT_POSTFIX), - std::string(FPGA_PORT_POSTFIX), - std::string(CHECKFLAG_PORT_POSTFIX), - std::string(ERROR_COUNTER), - atom_ctx, - netlist_annotation, - clock_port_names, - std::string(DEFAULT_CLOCK_NAME)); + if (!options.no_self_checking()) { + print_verilog_testbench_check(fp, + std::string(FORMAL_TB_SIM_START_PORT_NAME), + std::string(BENCHMARK_PORT_POSTFIX), + std::string(FPGA_PORT_POSTFIX), + std::string(CHECKFLAG_PORT_POSTFIX), + std::string(ERROR_COUNTER), + atom_ctx, + netlist_annotation, + clock_port_names, + std::string(DEFAULT_CLOCK_NAME)); + } float simulation_time = find_operating_phase_simulation_time(simulation_parameters.num_clock_cycles(), 1./simulation_parameters.default_operating_clock_frequency(), diff --git a/openfpga/src/fpga_verilog/verilog_simulation_info_writer.cpp b/openfpga/src/fpga_verilog/verilog_simulation_info_writer.cpp index f80cce0a8..9ed82a131 100644 --- a/openfpga/src/fpga_verilog/verilog_simulation_info_writer.cpp +++ b/openfpga/src/fpga_verilog/verilog_simulation_info_writer.cpp @@ -93,7 +93,7 @@ void print_verilog_simulation_info(const std::string& ini_fname, ini["SIMULATION_DECK"]["SIMTIME "] = std::to_string(simulation_time_period); ini["SIMULATION_DECK"]["UNIT "] = unit_to_string(options.time_unit()); ini["SIMULATION_DECK"]["VERILOG_PATH "] = std::string(src_dir); - ini["SIMULATION_DECK"]["VERILOG_FILE1"] = std::string(DEFINES_VERILOG_SIMULATION_FILE_NAME); + ini["SIMULATION_DECK"]["VERILOG_FILE1"] = std::string(DEFINES_VERILOG_FILE_NAME); ini["SIMULATION_DECK"]["VERILOG_FILE2"] = std::string(circuit_name + std::string(TOP_VERILOG_TESTBENCH_INCLUDE_NETLIST_FILE_NAME_POSTFIX)); ini["SIMULATION_DECK"]["CONFIG_PROTOCOL"] = std::string(CONFIG_PROTOCOL_TYPE_STRING[config_protocol_type]); diff --git a/openfpga/src/fpga_verilog/verilog_testbench_options.cpp b/openfpga/src/fpga_verilog/verilog_testbench_options.cpp index ca936bea7..616081ad2 100644 --- a/openfpga/src/fpga_verilog/verilog_testbench_options.cpp +++ b/openfpga/src/fpga_verilog/verilog_testbench_options.cpp @@ -75,6 +75,10 @@ bool VerilogTestbenchOption::include_signal_init() const { return include_signal_init_; } +bool VerilogTestbenchOption::no_self_checking() const { + return no_self_checking_; +} + e_verilog_default_net_type VerilogTestbenchOption::default_net_type() const { return default_net_type_; } @@ -147,6 +151,10 @@ void VerilogTestbenchOption::set_include_signal_init(const bool& enabled) { include_signal_init_ = enabled; } +void VerilogTestbenchOption::set_no_self_checking(const bool& enabled) { + no_self_checking_ = enabled; +} + void VerilogTestbenchOption::set_default_net_type(const std::string& default_net_type) { /* Decode from net type string */; if (default_net_type == std::string(VERILOG_DEFAULT_NET_TYPE_STRING[VERILOG_DEFAULT_NET_TYPE_NONE])) { diff --git a/openfpga/src/fpga_verilog/verilog_testbench_options.h b/openfpga/src/fpga_verilog/verilog_testbench_options.h index ad671386d..1cee764c3 100644 --- a/openfpga/src/fpga_verilog/verilog_testbench_options.h +++ b/openfpga/src/fpga_verilog/verilog_testbench_options.h @@ -43,6 +43,7 @@ class VerilogTestbenchOption { std::string simulation_ini_path() const; bool explicit_port_mapping() const; bool include_signal_init() const; + bool no_self_checking() const; e_verilog_default_net_type default_net_type() const; e_embedded_bitstream_hdl_type embedded_bitstream_hdl_type() const; float time_unit() const; @@ -69,6 +70,7 @@ class VerilogTestbenchOption { void set_print_simulation_ini(const std::string& simulation_ini_path); void set_explicit_port_mapping(const bool& enabled); void set_include_signal_init(const bool& enabled); + void set_no_self_checking(const bool& enabled); void set_default_net_type(const std::string& default_net_type); void set_time_unit(const float& time_unit); void set_embedded_bitstream_hdl_type(const std::string& embedded_bitstream_hdl_type); @@ -85,6 +87,7 @@ class VerilogTestbenchOption { std::string simulation_ini_path_; bool explicit_port_mapping_; bool include_signal_init_; + bool no_self_checking_; e_verilog_default_net_type default_net_type_; e_embedded_bitstream_hdl_type embedded_bitstream_hdl_type_; float time_unit_; diff --git a/openfpga/src/fpga_verilog/verilog_testbench_utils.cpp b/openfpga/src/fpga_verilog/verilog_testbench_utils.cpp index cbebc5545..4422c836c 100644 --- a/openfpga/src/fpga_verilog/verilog_testbench_utils.cpp +++ b/openfpga/src/fpga_verilog/verilog_testbench_utils.cpp @@ -366,7 +366,6 @@ std::vector generate_verilog_testbench_clock_port(const std::vector clock_ports = generate_verilog_testbench_clock_port(clock_port_names, default_clock_name); @@ -460,9 +457,6 @@ void print_verilog_testbench_check(std::fstream& fp, fp << std::endl; } - /* Condition ends */ - print_verilog_endif(fp); - /* Add an empty line as splitter */ fp << std::endl; } @@ -664,7 +658,7 @@ void print_verilog_testbench_shared_ports(std::fstream& fp, const std::string& benchmark_output_port_postfix, const std::string& fpga_output_port_postfix, const std::string& check_flag_port_postfix, - const std::string& autocheck_preprocessing_flag) { + const bool& no_self_checking) { /* Validate the file stream */ valid_file_stream(fp); @@ -718,11 +712,9 @@ void print_verilog_testbench_shared_ports(std::fstream& fp, /* Add an empty line as splitter */ fp << std::endl; - /* Benchmark is instanciated conditionally: only when a preprocessing flag is enable */ - print_verilog_preprocessing_flag(fp, std::string(autocheck_preprocessing_flag)); - - /* Add an empty line as splitter */ - fp << std::endl; + if (no_self_checking) { + return; + } /* Instantiate wire for benchmark output */ print_verilog_comment(fp, std::string("----- Benchmark outputs -------")); @@ -767,12 +759,6 @@ void print_verilog_testbench_shared_ports(std::fstream& fp, /* Add an empty line as splitter */ fp << std::endl; - - /* Condition ends for the benchmark instanciation */ - print_verilog_endif(fp); - - /* Add an empty line as splitter */ - fp << std::endl; } /******************************************************************** diff --git a/openfpga/src/fpga_verilog/verilog_testbench_utils.h b/openfpga/src/fpga_verilog/verilog_testbench_utils.h index 91ade1856..7b6858ce5 100644 --- a/openfpga/src/fpga_verilog/verilog_testbench_utils.h +++ b/openfpga/src/fpga_verilog/verilog_testbench_utils.h @@ -62,7 +62,6 @@ std::vector generate_verilog_testbench_clock_port(const std::vector(1, BasicPort(std::string(TOP_TB_OP_CLOCK_PORT_NAME), 1))); - /* Add output autocheck */ - print_verilog_testbench_check(fp, - std::string(AUTOCHECKED_SIMULATION_FLAG), - std::string(TOP_TESTBENCH_SIM_START_PORT_NAME), - std::string(TOP_TESTBENCH_REFERENCE_OUTPUT_POSTFIX), - std::string(TOP_TESTBENCH_FPGA_OUTPUT_POSTFIX), - std::string(TOP_TESTBENCH_CHECKFLAG_PORT_POSTFIX), - std::string(TOP_TESTBENCH_ERROR_COUNTER), - atom_ctx, - netlist_annotation, - clock_port_names, - std::string(TOP_TB_OP_CLOCK_PORT_NAME)); + if (!options.no_self_checking()) { + /* Add output autocheck */ + print_verilog_testbench_check(fp, + std::string(TOP_TESTBENCH_SIM_START_PORT_NAME), + std::string(TOP_TESTBENCH_REFERENCE_OUTPUT_POSTFIX), + std::string(TOP_TESTBENCH_FPGA_OUTPUT_POSTFIX), + std::string(TOP_TESTBENCH_CHECKFLAG_PORT_POSTFIX), + std::string(TOP_TESTBENCH_ERROR_COUNTER), + atom_ctx, + netlist_annotation, + clock_port_names, + std::string(TOP_TB_OP_CLOCK_PORT_NAME)); - /* Add autocheck for configuration phase */ - print_verilog_top_testbench_check(fp, - std::string(AUTOCHECKED_SIMULATION_FLAG), - std::string(TOP_TB_CONFIG_DONE_PORT_NAME), - std::string(TOP_TESTBENCH_ERROR_COUNTER)); + /* Add autocheck for configuration phase */ + print_verilog_top_testbench_check(fp, + std::string(TOP_TB_CONFIG_DONE_PORT_NAME), + std::string(TOP_TESTBENCH_ERROR_COUNTER)); + } /* Find simulation time */ float simulation_time = find_simulation_time_period(VERILOG_SIM_TIMESCALE, From ac9046b7d20c560c9a8b9ab5e47f06f7e360497e Mon Sep 17 00:00:00 2001 From: tangxifan Date: Tue, 29 Jun 2021 15:38:35 -0600 Subject: [PATCH 03/19] [Doc] Remove ``define_simulation.v`` since it is no longer needed. --- .../figures/verilog_testbench_hierarchy.png | Bin 32203 -> 0 bytes .../figures/verilog_testbench_hierarchy.svg | 79 ++++++++++++++++++ docs/source/manual/fpga_verilog/testbench.rst | 19 +---- .../fpga_verilog_commands.rst | 8 +- 4 files changed, 87 insertions(+), 19 deletions(-) delete mode 100644 docs/source/manual/fpga_verilog/figures/verilog_testbench_hierarchy.png create mode 100644 docs/source/manual/fpga_verilog/figures/verilog_testbench_hierarchy.svg diff --git a/docs/source/manual/fpga_verilog/figures/verilog_testbench_hierarchy.png b/docs/source/manual/fpga_verilog/figures/verilog_testbench_hierarchy.png deleted file mode 100644 index 042fb8eaf9212cf82e1f391990108b6b23cb045f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 32203 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 z%0A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

i;E?*mXe|B-7(79gy)>zLtN6BSneq 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 Q9q><1T3M<@!YJT>0Wham)Bpeg diff --git a/docs/source/manual/fpga_verilog/figures/verilog_testbench_hierarchy.svg b/docs/source/manual/fpga_verilog/figures/verilog_testbench_hierarchy.svg new file mode 100644 index 000000000..0c0a98b3d --- /dev/null +++ b/docs/source/manual/fpga_verilog/figures/verilog_testbench_hierarchy.svg @@ -0,0 +1,79 @@ + + + + + + + + + + + + + + + + Produced by OmniGraffle 7.18.5\n2021-06-29 21:32:37 +0000 + + Canvas 1 + + Layer 1 + + + + + + + + + + + + + <bench_name>_include_netlist.v + + + + + + + <bench_name>_autocheck_top_tb.v + + + + + + + <bench_name>_formal_random_top_tb.v + + + + + + + <bench_name>_top_formal_verification.v + + + + + + + + + + + + + + Full testbench + + + + + Formal-oriented + testbench + + + + + diff --git a/docs/source/manual/fpga_verilog/testbench.rst b/docs/source/manual/fpga_verilog/testbench.rst index addf4496f..6b434e0fb 100644 --- a/docs/source/manual/fpga_verilog/testbench.rst +++ b/docs/source/manual/fpga_verilog/testbench.rst @@ -58,8 +58,8 @@ Inside the directory, the Verilog testbenches are organized as illustrated in :n .. _fig_verilog_testbench_hierarchy: -.. figure:: ./figures/verilog_testbench_hierarchy.png - :scale: 90% +.. figure:: ./figures/verilog_testbench_hierarchy.svg + :scale: 100% Hierarchy of Verilog testbenches for a FPGA fabric implemented with an application @@ -73,21 +73,6 @@ Inside the directory, the Verilog testbenches are organized as illustrated in :n .. note:: Fabric Verilog netlists are included in this file. -.. option:: define_simulation.v - - This file includes pre-processing flags required by the testbenches, to smooth HDL simulation. - It will include the folliwng pre-procesing flags: - - - ```define AUTOCHECK_SIMULATION`` When enabled, testbench will include self-testing features. The FPGA and user's RTL design (simulate using an HDL simulator) are driven by the same input stimuli, and any mismatch on their outputs will raise an error flag. - - .. note:: OpenFPGA always enable the self-testing feature. Users can disable it by commenting out the associated line in the ``define_simulation.v``. - - - ```define ENABLE_FORMAL_VERFICATION`` When enabled, the ``_include_netlist.v`` will include the pre-configured FPGA netlist for formal verification usage. This flag is added when ``--print_formal_verification_top_netlist`` option is enabled when calling the ``write_verilog_testbench`` command. - - - ```define ENABLE_FORMAL_SIMULATION`` When enabled, the ``_include_netlist.v`` will include the testbench netlist for formal-oriented simulation. This flag is added when ``--print_preconfig_top_testbench`` option is enabled when calling the ``write_verilog_testbench`` command. - - .. note:: To run full testbenches, both flags ``ENABLE_FORMAL_VERIFICATION`` and ``ENABLE_FORMAL_SIMULATION`` must be disabled! - .. option:: _autocheck_top_tb.v This is the netlist for full testbench. diff --git a/docs/source/manual/openfpga_shell/openfpga_commands/fpga_verilog_commands.rst b/docs/source/manual/openfpga_shell/openfpga_commands/fpga_verilog_commands.rst index d8e254a3e..e927d7b2c 100644 --- a/docs/source/manual/openfpga_shell/openfpga_commands/fpga_verilog_commands.rst +++ b/docs/source/manual/openfpga_shell/openfpga_commands/fpga_verilog_commands.rst @@ -51,7 +51,9 @@ write_full_testbench .. option:: --reference_benchmark_file_path - Must specify the reference benchmark Verilog file if you want to output any testbenches. For example, ``--reference_benchmark_file_path /temp/benchmark/counter_post_synthesis.v`` + Specify the reference benchmark Verilog file if you want to output any self-checking testbench. For example, ``--reference_benchmark_file_path /temp/benchmark/counter_post_synthesis.v`` + + .. note:: If not specified, the testbench will not include any self-checking feature! .. option:: --pin_constraints_file or -pcf @@ -150,7 +152,9 @@ write_preconfigured_testbench .. option:: --reference_benchmark_file_path - Must specify the reference benchmark Verilog file if you want to output any testbenches. For example, ``--reference_benchmark_file_path /temp/benchmark/counter_post_synthesis.v`` + Specify the reference benchmark Verilog file if you want to output any self-checking testbench. For example, ``--reference_benchmark_file_path /temp/benchmark/counter_post_synthesis.v`` + + .. note:: If not specified, the testbench will not include any self-checking feature! .. option:: --pin_constraints_file or -pcf From 6a260cadbfafe21f42caa06d4de61cb31f1e3223 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Tue, 29 Jun 2021 15:42:23 -0600 Subject: [PATCH 04/19] [Tool] Remove option ``--no_self_checking`` option but use the existing option ``--reference_benchmark_path`` to achieve the same purpose --- openfpga/src/base/openfpga_verilog.cpp | 4 ---- openfpga/src/base/openfpga_verilog_command.cpp | 7 ++----- openfpga/src/fpga_verilog/verilog_testbench_options.cpp | 6 +----- openfpga/src/fpga_verilog/verilog_testbench_options.h | 2 -- 4 files changed, 3 insertions(+), 16 deletions(-) diff --git a/openfpga/src/base/openfpga_verilog.cpp b/openfpga/src/base/openfpga_verilog.cpp index 16016a913..b912c518c 100644 --- a/openfpga/src/base/openfpga_verilog.cpp +++ b/openfpga/src/base/openfpga_verilog.cpp @@ -78,7 +78,6 @@ int write_full_testbench(const OpenfpgaContext& openfpga_ctx, CommandOptionId opt_fast_configuration = cmd.option("fast_configuration"); CommandOptionId opt_explicit_port_mapping = cmd.option("explicit_port_mapping"); CommandOptionId opt_default_net_type = cmd.option("default_net_type"); - CommandOptionId opt_no_self_checking = cmd.option("no_self_checking"); CommandOptionId opt_include_signal_init = cmd.option("include_signal_init"); CommandOptionId opt_verbose = cmd.option("verbose"); @@ -94,7 +93,6 @@ int write_full_testbench(const OpenfpgaContext& openfpga_ctx, options.set_verbose_output(cmd_context.option_enable(cmd, opt_verbose)); options.set_print_top_testbench(true); options.set_include_signal_init(cmd_context.option_enable(cmd, opt_include_signal_init)); - options.set_no_self_checking(cmd_context.option_enable(cmd, opt_no_self_checking)); if (true == cmd_context.option_enable(cmd, opt_default_net_type)) { options.set_default_net_type(cmd_context.option_value(cmd, opt_default_net_type)); } @@ -186,7 +184,6 @@ int write_preconfigured_testbench(const OpenfpgaContext& openfpga_ctx, CommandOptionId opt_reference_benchmark = cmd.option("reference_benchmark_file_path"); CommandOptionId opt_explicit_port_mapping = cmd.option("explicit_port_mapping"); CommandOptionId opt_default_net_type = cmd.option("default_net_type"); - CommandOptionId opt_no_self_checking = cmd.option("no_self_checking"); CommandOptionId opt_verbose = cmd.option("verbose"); /* This is an intermediate data structure which is designed to modularize the FPGA-Verilog @@ -199,7 +196,6 @@ int write_preconfigured_testbench(const OpenfpgaContext& openfpga_ctx, 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_preconfig_top_testbench(true); - options.set_no_self_checking(cmd_context.option_enable(cmd, opt_no_self_checking)); if (true == cmd_context.option_enable(cmd, opt_default_net_type)) { options.set_default_net_type(cmd_context.option_value(cmd, opt_default_net_type)); } diff --git a/openfpga/src/base/openfpga_verilog_command.cpp b/openfpga/src/base/openfpga_verilog_command.cpp index 3b0c94138..bbee67815 100644 --- a/openfpga/src/base/openfpga_verilog_command.cpp +++ b/openfpga/src/base/openfpga_verilog_command.cpp @@ -196,7 +196,7 @@ ShellCommandId add_openfpga_write_preconfigured_testbench_command(openfpga::Shel shell_cmd.set_option_require_value(pcf_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"); + CommandOptionId ref_bm_opt = shell_cmd.add_option("reference_benchmark_file_path", false, "Specify the file path to the reference Verilog netlist. If specified, the testbench will include self-checking codes"); shell_cmd.set_option_require_value(ref_bm_opt, openfpga::OPT_STRING); /* Add an option '--explicit_port_mapping' */ @@ -206,9 +206,6 @@ ShellCommandId add_openfpga_write_preconfigured_testbench_command(openfpga::Shel CommandOptionId default_net_type_opt = shell_cmd.add_option("default_net_type", false, "Set the default net type for Verilog netlists. Default value is 'none'"); shell_cmd.set_option_require_value(default_net_type_opt, openfpga::OPT_STRING); - /* Add an option '--no_self_checking' */ - shell_cmd.add_option("no_self_checking", false, "Do not generate self-checking codes for Verilog testbenches."); - /* Add an option '--verbose' */ shell_cmd.add_option("verbose", false, "Enable verbose output"); @@ -244,7 +241,7 @@ ShellCommandId add_openfpga_write_simulation_task_info_command(openfpga::Shell Date: Tue, 29 Jun 2021 15:52:42 -0600 Subject: [PATCH 05/19] [Script] Remove the post-processing on ``define_simulation.v`` since it is deprecated --- openfpga_flow/scripts/run_fpga_flow.py | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/openfpga_flow/scripts/run_fpga_flow.py b/openfpga_flow/scripts/run_fpga_flow.py index 1593d3f85..a333ebb8f 100644 --- a/openfpga_flow/scripts/run_fpga_flow.py +++ b/openfpga_flow/scripts/run_fpga_flow.py @@ -741,11 +741,6 @@ def run_netlists_verification(exit_if_fail=True): command = [cad_tools["iverilog_path"]] command += ["-o", compiled_file] - fpga_define_file = "./SRC/define_simulation.v" - fpga_define_file_bk = "./SRC/define_simulation.v.bak" - shutil.copy(fpga_define_file, fpga_define_file_bk) - with open(fpga_define_file, "r") as fp: - fpga_defines = fp.readlines() command += ["./SRC/%s_include_netlists.v" % args.top_module] command += ["-s"] @@ -753,11 +748,6 @@ def run_netlists_verification(exit_if_fail=True): command += [tb_top_formal] else: command += [tb_top_autochecked] - with open(fpga_define_file, "w") as fp: - for eachLine in fpga_defines: - if not (("ENABLE_FORMAL_VERIFICATION" in eachLine) or - "FORMAL_SIMULATION" in eachLine): - fp.write(eachLine) run_command("iverilog_verification", "iverilog_output.txt", command) vvp_command = ["vvp", compiled_file] From 01391fd81e460b80c81707253a499d592acd96b3 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Tue, 29 Jun 2021 15:56:33 -0600 Subject: [PATCH 06/19] [Script] Added example scripts that use OpenFPGA to generate testbenches without self checking features --- ...hout_self_checking_example_script.openfpga | 74 ++++++++++++++++++ ...hout_self_checking_example_script.openfpga | 75 +++++++++++++++++++ 2 files changed, 149 insertions(+) create mode 100644 openfpga_flow/openfpga_shell_scripts/full_testbench_without_self_checking_example_script.openfpga create mode 100644 openfpga_flow/openfpga_shell_scripts/preconfigure_testbench_without_self_checking_example_script.openfpga diff --git a/openfpga_flow/openfpga_shell_scripts/full_testbench_without_self_checking_example_script.openfpga b/openfpga_flow/openfpga_shell_scripts/full_testbench_without_self_checking_example_script.openfpga new file mode 100644 index 000000000..31717063b --- /dev/null +++ b/openfpga_flow/openfpga_shell_scripts/full_testbench_without_self_checking_example_script.openfpga @@ -0,0 +1,74 @@ +# Run VPR for the 'and' design +#--write_rr_graph example_rr_graph.xml +vpr ${VPR_ARCH_FILE} ${VPR_TESTBENCH_BLIF} --clock_modeling route + +# 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 clustering nets based on routing results +pb_pin_fixup --verbose + +# 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 --explicit_port_mapping --include_signal_init --bitstream fabric_bitstream.bit + +# 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 diff --git a/openfpga_flow/openfpga_shell_scripts/preconfigure_testbench_without_self_checking_example_script.openfpga b/openfpga_flow/openfpga_shell_scripts/preconfigure_testbench_without_self_checking_example_script.openfpga new file mode 100644 index 000000000..7fd7053f8 --- /dev/null +++ b/openfpga_flow/openfpga_shell_scripts/preconfigure_testbench_without_self_checking_example_script.openfpga @@ -0,0 +1,75 @@ +# Run VPR for the 'and' design +#--write_rr_graph example_rr_graph.xml +vpr ${VPR_ARCH_FILE} ${VPR_TESTBENCH_BLIF} --clock_modeling route + +# 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 clustering nets based on routing results +pb_pin_fixup --verbose + +# 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_preconfigured_fabric_wrapper --embed_bitstream iverilog --file ./SRC --explicit_port_mapping +write_preconfigured_testbench --file ./SRC --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 From 20faf82e64cac216004bab385df9226b9351ae92 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Tue, 29 Jun 2021 16:02:35 -0600 Subject: [PATCH 07/19] [Script] Rename example script --- ...gured_testbench_without_self_checking_example_script.openfpga} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename openfpga_flow/openfpga_shell_scripts/{preconfigure_testbench_without_self_checking_example_script.openfpga => preconfigured_testbench_without_self_checking_example_script.openfpga} (100%) diff --git a/openfpga_flow/openfpga_shell_scripts/preconfigure_testbench_without_self_checking_example_script.openfpga b/openfpga_flow/openfpga_shell_scripts/preconfigured_testbench_without_self_checking_example_script.openfpga similarity index 100% rename from openfpga_flow/openfpga_shell_scripts/preconfigure_testbench_without_self_checking_example_script.openfpga rename to openfpga_flow/openfpga_shell_scripts/preconfigured_testbench_without_self_checking_example_script.openfpga From 30c2f597f2c01683d7f2036879981a6b10bdc76a Mon Sep 17 00:00:00 2001 From: tangxifan Date: Tue, 29 Jun 2021 16:06:15 -0600 Subject: [PATCH 08/19] [Test] Added two cases to validate testbench generation without self checking --- .../config/task.conf | 36 +++++++++++++++++++ .../config/task.conf | 35 ++++++++++++++++++ 2 files changed, 71 insertions(+) create mode 100644 openfpga_flow/tasks/basic_tests/full_testbench/full_testbench_without_self_checking/config/task.conf create mode 100644 openfpga_flow/tasks/basic_tests/preconfig_testbench/preconfigured_testbench_without_self_checking/config/task.conf diff --git a/openfpga_flow/tasks/basic_tests/full_testbench/full_testbench_without_self_checking/config/task.conf b/openfpga_flow/tasks/basic_tests/full_testbench/full_testbench_without_self_checking/config/task.conf new file mode 100644 index 000000000..2fe7d3e62 --- /dev/null +++ b/openfpga_flow/tasks/basic_tests/full_testbench/full_testbench_without_self_checking/config/task.conf @@ -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/full_testbench_without_self_checking_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= +openfpga_fast_configuration= + +[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_latch/and2_latch.v + +[SYNTHESIS_PARAM] +bench0_top = and2_latch +bench0_chan_width = 300 + +[SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH] +end_flow_with_test= diff --git a/openfpga_flow/tasks/basic_tests/preconfig_testbench/preconfigured_testbench_without_self_checking/config/task.conf b/openfpga_flow/tasks/basic_tests/preconfig_testbench/preconfigured_testbench_without_self_checking/config/task.conf new file mode 100644 index 000000000..d511bdbb9 --- /dev/null +++ b/openfpga_flow/tasks/basic_tests/preconfig_testbench/preconfigured_testbench_without_self_checking/config/task.conf @@ -0,0 +1,35 @@ +# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +# 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/preconfigured_testbench_without_self_checking_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 + +[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_latch/and2_latch.v + +[SYNTHESIS_PARAM] +bench0_top = and2_latch +bench0_chan_width = 300 + +[SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH] +end_flow_with_test= +vpr_fpga_verilog_formal_verification_top_netlist= From cbea4a3cb6ca20050f2c861bdc05a2cdf6b3d45e Mon Sep 17 00:00:00 2001 From: tangxifan Date: Tue, 29 Jun 2021 16:08:22 -0600 Subject: [PATCH 09/19] [Test] Add the test cases to regression test --- openfpga_flow/regression_test_scripts/basic_reg_test.sh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/openfpga_flow/regression_test_scripts/basic_reg_test.sh b/openfpga_flow/regression_test_scripts/basic_reg_test.sh index b9d4039d0..0a11ed4e0 100755 --- a/openfpga_flow/regression_test_scripts/basic_reg_test.sh +++ b/openfpga_flow/regression_test_scripts/basic_reg_test.sh @@ -53,6 +53,10 @@ run-task basic_tests/full_testbench/smart_fast_memory_bank --debug --show_thread run-task basic_tests/full_testbench/smart_fast_multi_region_memory_bank --debug --show_thread_logs run-task basic_tests/preconfig_testbench/memory_bank --debug --show_thread_logs +echo -e "Testing testbenches without self checking features"; +run-task basic_tests/full_testbench/full_testbench_without_self_checking --debug --show_thread_logs +run-task basic_tests/preconfig_testbench/preconfigured_testbench_without_self_checking --debug --show_thread_logs + echo -e "Testing standalone (flatten memory) configuration protocol of a K4N4 FPGA"; run-task basic_tests/full_testbench/flatten_memory --debug --show_thread_logs run-task basic_tests/preconfig_testbench/flatten_memory --debug --show_thread_logs From b83eef47b48db73f873968a37e5f8851504ba076 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Tue, 29 Jun 2021 16:27:29 -0600 Subject: [PATCH 10/19] [Tool] Bug fix for testbench generation without self checking codes --- .../src/base/openfpga_verilog_command.cpp | 2 +- .../verilog_formal_random_top_testbench.cpp | 6 +- .../fpga_verilog/verilog_testbench_utils.cpp | 65 ++++++++++++------- .../fpga_verilog/verilog_testbench_utils.h | 6 +- .../fpga_verilog/verilog_top_testbench.cpp | 6 +- 5 files changed, 53 insertions(+), 32 deletions(-) diff --git a/openfpga/src/base/openfpga_verilog_command.cpp b/openfpga/src/base/openfpga_verilog_command.cpp index bbee67815..165a0eb38 100644 --- a/openfpga/src/base/openfpga_verilog_command.cpp +++ b/openfpga/src/base/openfpga_verilog_command.cpp @@ -84,7 +84,7 @@ ShellCommandId add_openfpga_write_full_testbench_command(openfpga::Shell& clock_port_names, const std::string& check_flag_port_postfix, - const std::vector& clock_ports) { + const std::vector& clock_ports, + const bool& no_self_checking) { /* Validate the file stream */ valid_file_stream(fp); @@ -569,25 +582,27 @@ void print_verilog_testbench_random_stimuli(std::fstream& fp, } } - /* Add an empty line as splitter */ - fp << std::endl; - /* Set 0 to registers for checking flags */ - for (const AtomBlockId& atom_blk : atom_ctx.nlist.blocks()) { - /* Bypass non-I/O atom blocks ! */ - if (AtomBlockType::OUTPAD != atom_ctx.nlist.block_type(atom_blk)) { - continue; + if (!no_self_checking) { + /* Add an empty line as splitter */ + fp << std::endl; + + for (const AtomBlockId& atom_blk : atom_ctx.nlist.blocks()) { + /* Bypass non-I/O atom blocks ! */ + if (AtomBlockType::OUTPAD != atom_ctx.nlist.block_type(atom_blk)) { + continue; + } + + /* The block may be renamed as it contains special characters which violate Verilog syntax */ + std::string block_name = atom_ctx.nlist.block_name(atom_blk); + if (true == netlist_annotation.is_block_renamed(atom_blk)) { + block_name = netlist_annotation.block_name(atom_blk); + } + + /* Each logical block assumes a single-width port */ + BasicPort output_port(std::string(block_name + check_flag_port_postfix), 1); + fp << "\t\t" << generate_verilog_port(VERILOG_PORT_CONKT, output_port) << " <= 1'b0;" << std::endl; } - - /* The block may be renamed as it contains special characters which violate Verilog syntax */ - std::string block_name = atom_ctx.nlist.block_name(atom_blk); - if (true == netlist_annotation.is_block_renamed(atom_blk)) { - block_name = netlist_annotation.block_name(atom_blk); - } - - /* Each logical block assumes a single-width port */ - BasicPort output_port(std::string(block_name + check_flag_port_postfix), 1); - fp << "\t\t" << generate_verilog_port(VERILOG_PORT_CONKT, output_port) << " <= 1'b0;" << std::endl; } fp << "\tend" << std::endl; diff --git a/openfpga/src/fpga_verilog/verilog_testbench_utils.h b/openfpga/src/fpga_verilog/verilog_testbench_utils.h index 7b6858ce5..f45452c6d 100644 --- a/openfpga/src/fpga_verilog/verilog_testbench_utils.h +++ b/openfpga/src/fpga_verilog/verilog_testbench_utils.h @@ -56,7 +56,8 @@ void print_verilog_timeout_and_vcd(std::fstream& fp, const std::string& vcd_fname, const std::string& simulation_start_counter_name, const std::string& error_counter_name, - const float& simulation_time); + const float& simulation_time, + const bool& no_self_checking); std::vector generate_verilog_testbench_clock_port(const std::vector& clock_port_names, const std::string& default_clock_name); @@ -85,7 +86,8 @@ void print_verilog_testbench_random_stimuli(std::fstream& fp, const PinConstraints& pin_constraints, const std::vector& clock_port_names, const std::string& check_flag_port_postfix, - const std::vector& clock_ports); + const std::vector& clock_ports, + const bool& no_self_checking); void print_verilog_testbench_shared_ports(std::fstream& fp, const AtomContext& atom_ctx, diff --git a/openfpga/src/fpga_verilog/verilog_top_testbench.cpp b/openfpga/src/fpga_verilog/verilog_top_testbench.cpp index 49fe46889..47300ce1e 100644 --- a/openfpga/src/fpga_verilog/verilog_top_testbench.cpp +++ b/openfpga/src/fpga_verilog/verilog_top_testbench.cpp @@ -2038,7 +2038,8 @@ int print_verilog_full_testbench(const ModuleManager& module_manager, pin_constraints, clock_port_names, std::string(TOP_TESTBENCH_CHECKFLAG_PORT_POSTFIX), - std::vector(1, BasicPort(std::string(TOP_TB_OP_CLOCK_PORT_NAME), 1))); + std::vector(1, BasicPort(std::string(TOP_TB_OP_CLOCK_PORT_NAME), 1)), + options.no_self_checking()); if (!options.no_self_checking()) { /* Add output autocheck */ @@ -2075,7 +2076,8 @@ int print_verilog_full_testbench(const ModuleManager& module_manager, std::string(circuit_name + std::string("_formal.vcd")), std::string(TOP_TESTBENCH_SIM_START_PORT_NAME), std::string(TOP_TESTBENCH_ERROR_COUNTER), - std::ceil(simulation_time)); + std::ceil(simulation_time), + options.no_self_checking()); /* Testbench ends*/ From b5df1f9aeb3f92ea3d385aaba4d1ab69d7ac93bb Mon Sep 17 00:00:00 2001 From: tangxifan Date: Tue, 29 Jun 2021 17:02:16 -0600 Subject: [PATCH 11/19] [Tool] Bug fix for redundant endif in netlists --- openfpga/src/fpga_verilog/verilog_auxiliary_netlists.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/openfpga/src/fpga_verilog/verilog_auxiliary_netlists.cpp b/openfpga/src/fpga_verilog/verilog_auxiliary_netlists.cpp index b36501102..09974ca12 100644 --- a/openfpga/src/fpga_verilog/verilog_auxiliary_netlists.cpp +++ b/openfpga/src/fpga_verilog/verilog_auxiliary_netlists.cpp @@ -123,9 +123,7 @@ void print_verilog_full_testbench_include_netlists(const std::string& src_dir, /* Include reference benchmark netlist only when auto-check flag is enabled */ if (!no_self_checking) { - fp << "\t"; print_verilog_include_netlist(fp, std::string(reference_benchmark_file)); - print_verilog_endif(fp); fp << std::endl; } @@ -171,9 +169,7 @@ void print_verilog_preconfigured_testbench_include_netlists(const std::string& s /* Include reference benchmark netlist only when auto-check flag is enabled */ if (!no_self_checking) { - fp << "\t"; print_verilog_include_netlist(fp, std::string(reference_benchmark_file)); - print_verilog_endif(fp); fp << std::endl; } From 9655bc35cb2b5829abdaac50ca2889a5b40ed7be Mon Sep 17 00:00:00 2001 From: tangxifan Date: Tue, 29 Jun 2021 17:04:19 -0600 Subject: [PATCH 12/19] [Script] Bug fix due to the full testbench generation changes --- .../generate_testbench_example_script.openfpga | 2 -- 1 file changed, 2 deletions(-) diff --git a/openfpga_flow/openfpga_shell_scripts/generate_testbench_example_script.openfpga b/openfpga_flow/openfpga_shell_scripts/generate_testbench_example_script.openfpga index b0322f105..0b5cfa232 100644 --- a/openfpga_flow/openfpga_shell_scripts/generate_testbench_example_script.openfpga +++ b/openfpga_flow/openfpga_shell_scripts/generate_testbench_example_script.openfpga @@ -52,8 +52,6 @@ write_fabric_bitstream --file fabric_bitstream.bit --format plain_text # - 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 --fabric_netlist_file_path ${OPENFPGA_FABRIC_VERILOG_NETLIST} --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 --fabric_netlist_file_path ${OPENFPGA_FABRIC_VERILOG_NETLIST} # Write the SDC to run timing analysis for a mapped FPGA fabric write_analysis_sdc --file ./SDC_analysis From 4fb34642cafb207cccb9d0cd91be223c1afa0b46 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Tue, 29 Jun 2021 17:53:56 -0600 Subject: [PATCH 13/19] [Script] Add a new example script for global tile clock running full testbench --- ...ock_full_testbench_example_script.openfpga | 76 +++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 openfpga_flow/openfpga_shell_scripts/global_tile_clock_full_testbench_example_script.openfpga diff --git a/openfpga_flow/openfpga_shell_scripts/global_tile_clock_full_testbench_example_script.openfpga b/openfpga_flow/openfpga_shell_scripts/global_tile_clock_full_testbench_example_script.openfpga new file mode 100644 index 000000000..d15fb05e5 --- /dev/null +++ b/openfpga_flow/openfpga_shell_scripts/global_tile_clock_full_testbench_example_script.openfpga @@ -0,0 +1,76 @@ +# Run VPR for the 'and' design +# When the global clock is defined as a port of a tile, clock routing in VPR should be skipped +# This is due to the Fc_in of clock port is set to 0 for global wiring +#--write_rr_graph example_rr_graph.xml +vpr ${VPR_ARCH_FILE} ${VPR_TESTBENCH_BLIF} --device ${OPENFPGA_VPR_DEVICE_LAYOUT} + +# 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 clustering nets based on routing results +pb_pin_fixup --verbose + +# 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 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 From 2c1692e6dce72e66b2b32fc5017adb3e2a4194b2 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Tue, 29 Jun 2021 17:54:25 -0600 Subject: [PATCH 14/19] [Test] Bug fix --- .../basic_tests/fixed_simulation_settings/config/task.conf | 5 +++-- .../tasks/fpga_verilog/io/registerable_io/config/task.conf | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/openfpga_flow/tasks/basic_tests/fixed_simulation_settings/config/task.conf b/openfpga_flow/tasks/basic_tests/fixed_simulation_settings/config/task.conf index 78daaf0c9..cb41e9959 100644 --- a/openfpga_flow/tasks/basic_tests/fixed_simulation_settings/config/task.conf +++ b/openfpga_flow/tasks/basic_tests/fixed_simulation_settings/config/task.conf @@ -16,9 +16,11 @@ timeout_each_job = 20*60 fpga_flow=vpr_blif [OpenFPGA_SHELL] -openfpga_shell_template=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_shell_scripts/example_script.openfpga +openfpga_shell_template=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_shell_scripts/write_full_testbench_example_script.openfpga openfpga_arch_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_arch/k4_N4_40nm_fixed_sim_openfpga.xml openfpga_sim_setting_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_simulation_settings/fixed_sim_openfpga.xml +openfpga_vpr_device_layout= +openfpga_fast_configuration= [ARCHITECTURES] arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/vpr_arch/k4_N4_tileable_40nm.xml @@ -34,4 +36,3 @@ bench0_chan_width = 300 [SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH] end_flow_with_test= -#vpr_fpga_verilog_formal_verification_top_netlist= diff --git a/openfpga_flow/tasks/fpga_verilog/io/registerable_io/config/task.conf b/openfpga_flow/tasks/fpga_verilog/io/registerable_io/config/task.conf index 700f8e3c7..9f7cd13a3 100644 --- a/openfpga_flow/tasks/fpga_verilog/io/registerable_io/config/task.conf +++ b/openfpga_flow/tasks/fpga_verilog/io/registerable_io/config/task.conf @@ -16,7 +16,7 @@ timeout_each_job = 20*60 fpga_flow=yosys_vpr [OpenFPGA_SHELL] -openfpga_shell_template=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_shell_scripts/fix_device_global_tile_clock_example_script.openfpga +openfpga_shell_template=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_shell_scripts/global_tile_clock_full_testbench_example_script.openfpga openfpga_arch_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_arch/k4_N4_40nm_GlobalTileClk_registerable_io_cc_openfpga.xml openfpga_sim_setting_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_simulation_settings/auto_sim_openfpga.xml openfpga_vpr_device_layout=2x2 From 5f5a03f17fb12b7832723767ca7c42965d6c1acb Mon Sep 17 00:00:00 2001 From: tangxifan Date: Tue, 29 Jun 2021 18:28:38 -0600 Subject: [PATCH 15/19] [Misc] Bug fix on test cases that were generating both full testbench and preconfigured testbenches --- .../generate_secure_fabric_example_script.openfpga | 2 -- .../basic_tests/fabric_key/generate_random_key/config/task.conf | 1 - 2 files changed, 3 deletions(-) diff --git a/openfpga_flow/openfpga_shell_scripts/generate_secure_fabric_example_script.openfpga b/openfpga_flow/openfpga_shell_scripts/generate_secure_fabric_example_script.openfpga index 6efc2baa5..c2107e0cb 100644 --- a/openfpga_flow/openfpga_shell_scripts/generate_secure_fabric_example_script.openfpga +++ b/openfpga_flow/openfpga_shell_scripts/generate_secure_fabric_example_script.openfpga @@ -59,8 +59,6 @@ write_fabric_verilog --file ./SRC --explicit_port_mapping --include_timing --pri # - 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 diff --git a/openfpga_flow/tasks/basic_tests/fabric_key/generate_random_key/config/task.conf b/openfpga_flow/tasks/basic_tests/fabric_key/generate_random_key/config/task.conf index 069541110..14110892b 100644 --- a/openfpga_flow/tasks/basic_tests/fabric_key/generate_random_key/config/task.conf +++ b/openfpga_flow/tasks/basic_tests/fabric_key/generate_random_key/config/task.conf @@ -34,4 +34,3 @@ bench0_chan_width = 300 [SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH] end_flow_with_test= -#vpr_fpga_verilog_formal_verification_top_netlist= From c6089385b095ffb3e607e3d00ee6aefe5308ad7e Mon Sep 17 00:00:00 2001 From: tangxifan Date: Tue, 29 Jun 2021 18:34:41 -0600 Subject: [PATCH 16/19] [Misc] Bug fix --- .../generate_secure_fabric_from_key_example_script.openfpga | 2 -- .../basic_tests/fabric_key/load_external_key/config/task.conf | 1 - 2 files changed, 3 deletions(-) diff --git a/openfpga_flow/openfpga_shell_scripts/generate_secure_fabric_from_key_example_script.openfpga b/openfpga_flow/openfpga_shell_scripts/generate_secure_fabric_from_key_example_script.openfpga index 4dd7f21c3..0431c5f75 100644 --- a/openfpga_flow/openfpga_shell_scripts/generate_secure_fabric_from_key_example_script.openfpga +++ b/openfpga_flow/openfpga_shell_scripts/generate_secure_fabric_from_key_example_script.openfpga @@ -59,8 +59,6 @@ write_fabric_verilog --file ./SRC --explicit_port_mapping --include_timing --pri # - 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 diff --git a/openfpga_flow/tasks/basic_tests/fabric_key/load_external_key/config/task.conf b/openfpga_flow/tasks/basic_tests/fabric_key/load_external_key/config/task.conf index 787e469d0..474f802dc 100644 --- a/openfpga_flow/tasks/basic_tests/fabric_key/load_external_key/config/task.conf +++ b/openfpga_flow/tasks/basic_tests/fabric_key/load_external_key/config/task.conf @@ -36,4 +36,3 @@ bench0_chan_width = 300 [SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH] end_flow_with_test= -#vpr_fpga_verilog_formal_verification_top_netlist= From 56b0428eba12713ef4ead2b619a0141296ca702b Mon Sep 17 00:00:00 2001 From: tangxifan Date: Tue, 29 Jun 2021 18:48:19 -0600 Subject: [PATCH 17/19] [Misc] Bug fix --- .../global_tile_clock_example_script.openfpga | 2 -- 1 file changed, 2 deletions(-) diff --git a/openfpga_flow/openfpga_shell_scripts/global_tile_clock_example_script.openfpga b/openfpga_flow/openfpga_shell_scripts/global_tile_clock_example_script.openfpga index db51ffe15..fe4a4abdb 100644 --- a/openfpga_flow/openfpga_shell_scripts/global_tile_clock_example_script.openfpga +++ b/openfpga_flow/openfpga_shell_scripts/global_tile_clock_example_script.openfpga @@ -58,8 +58,6 @@ write_fabric_verilog --file ./SRC --explicit_port_mapping --include_timing --pri # - 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} --include_signal_init --bitstream fabric_bitstream.bit -write_preconfigured_fabric_wrapper --embed_bitstream iverilog --file ./SRC -write_preconfigured_testbench --file ./SRC --reference_benchmark_file_path ${REFERENCE_VERILOG_TESTBENCH} # Write the SDC files for PnR backend # - Turn on every options here From f32ffb6d6197a5e487f9540df53856f7c98637c9 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Tue, 29 Jun 2021 18:51:28 -0600 Subject: [PATCH 18/19] [Test] Bug fix --- .../global_tile_clock_example_script.openfpga | 3 ++- .../global_tile_multiclock_example_script.openfpga | 1 - .../global_tile_ports/global_tile_clock/config/task.conf | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/openfpga_flow/openfpga_shell_scripts/global_tile_clock_example_script.openfpga b/openfpga_flow/openfpga_shell_scripts/global_tile_clock_example_script.openfpga index fe4a4abdb..086dc9eb0 100644 --- a/openfpga_flow/openfpga_shell_scripts/global_tile_clock_example_script.openfpga +++ b/openfpga_flow/openfpga_shell_scripts/global_tile_clock_example_script.openfpga @@ -57,7 +57,8 @@ write_fabric_verilog --file ./SRC --explicit_port_mapping --include_timing --pri # - 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} --include_signal_init --bitstream fabric_bitstream.bit +write_preconfigured_fabric_wrapper --embed_bitstream iverilog --file ./SRC +write_preconfigured_testbench --file ./SRC --reference_benchmark_file_path ${REFERENCE_VERILOG_TESTBENCH} # Write the SDC files for PnR backend # - Turn on every options here diff --git a/openfpga_flow/openfpga_shell_scripts/global_tile_multiclock_example_script.openfpga b/openfpga_flow/openfpga_shell_scripts/global_tile_multiclock_example_script.openfpga index ff0ba8d81..1b1daae4d 100644 --- a/openfpga_flow/openfpga_shell_scripts/global_tile_multiclock_example_script.openfpga +++ b/openfpga_flow/openfpga_shell_scripts/global_tile_multiclock_example_script.openfpga @@ -61,7 +61,6 @@ write_fabric_verilog --file ./SRC --explicit_port_mapping --include_timing --pri # - 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} --include_signal_init --pin_constraints_file ${OPENFPGA_PIN_CONSTRAINTS_FILE} --bitstream fabric_bitstream.bit write_preconfigured_fabric_wrapper --embed_bitstream iverilog --file ./SRC --pin_constraints_file ${OPENFPGA_PIN_CONSTRAINTS_FILE} write_preconfigured_testbench --file ./SRC --reference_benchmark_file_path ${REFERENCE_VERILOG_TESTBENCH} --pin_constraints_file ${OPENFPGA_PIN_CONSTRAINTS_FILE} diff --git a/openfpga_flow/tasks/basic_tests/global_tile_ports/global_tile_clock/config/task.conf b/openfpga_flow/tasks/basic_tests/global_tile_ports/global_tile_clock/config/task.conf index abc1be003..99b9d3f47 100644 --- a/openfpga_flow/tasks/basic_tests/global_tile_ports/global_tile_clock/config/task.conf +++ b/openfpga_flow/tasks/basic_tests/global_tile_ports/global_tile_clock/config/task.conf @@ -16,7 +16,7 @@ timeout_each_job = 20*60 fpga_flow=yosys_vpr [OpenFPGA_SHELL] -openfpga_shell_template=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_shell_scripts/global_tile_clock_example_script.openfpga +openfpga_shell_template=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_shell_scripts/global_tile_clock_full_testbench_example_script.openfpga openfpga_arch_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_arch/k4_N4_40nm_GlobalTileClk_cc_openfpga.xml openfpga_sim_setting_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_simulation_settings/auto_sim_openfpga.xml From 9eeec05a1f313c31466fd17cb33b406cab93458b Mon Sep 17 00:00:00 2001 From: tangxifan Date: Tue, 29 Jun 2021 19:55:07 -0600 Subject: [PATCH 19/19] [Test] Bug fix --- .../global_tile_ports/global_tile_clock/config/task.conf | 1 + 1 file changed, 1 insertion(+) diff --git a/openfpga_flow/tasks/basic_tests/global_tile_ports/global_tile_clock/config/task.conf b/openfpga_flow/tasks/basic_tests/global_tile_ports/global_tile_clock/config/task.conf index 99b9d3f47..ab945d768 100644 --- a/openfpga_flow/tasks/basic_tests/global_tile_ports/global_tile_clock/config/task.conf +++ b/openfpga_flow/tasks/basic_tests/global_tile_ports/global_tile_clock/config/task.conf @@ -19,6 +19,7 @@ fpga_flow=yosys_vpr openfpga_shell_template=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_shell_scripts/global_tile_clock_full_testbench_example_script.openfpga openfpga_arch_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_arch/k4_N4_40nm_GlobalTileClk_cc_openfpga.xml openfpga_sim_setting_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_simulation_settings/auto_sim_openfpga.xml +openfpga_vpr_device_layout=auto [ARCHITECTURES] arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/vpr_arch/k4_N4_tileable_GlobalTileClk_40nm.xml