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 c41887484..88cf33bc6 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 @@ -173,6 +173,14 @@ write_simulation_task_info 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`` + .. option:: --testbench_type + + Specify the type of testbenches [``preconfigured_testbench``|``full_testbench``]. By default, it is the ``preconfigured_testbench``. + + .. option:: --time_unit + + Specify a time unit to be used in SDC files. Acceptable values are string: ``as`` | ``fs`` | ``ps`` | ``ns`` | ``us`` | ``ms`` | ``ks`` | ``Ms``. By default, we will consider second (``ms``). + .. option:: --verbose Show verbose log diff --git a/openfpga/src/base/openfpga_verilog.cpp b/openfpga/src/base/openfpga_verilog.cpp index 3d853c18c..3821c407f 100644 --- a/openfpga/src/base/openfpga_verilog.cpp +++ b/openfpga/src/base/openfpga_verilog.cpp @@ -8,6 +8,9 @@ /* Headers from openfpgashell library */ #include "command_exit_codes.h" +/* Headers from openfpgautil library */ +#include "openfpga_scale.h" + #include "verilog_api.h" #include "openfpga_verilog.h" @@ -219,6 +222,8 @@ int write_simulation_task_info(const OpenfpgaContext& openfpga_ctx, CommandOptionId opt_file = cmd.option("file"); CommandOptionId opt_hdl_dir = cmd.option("hdl_dir"); CommandOptionId opt_reference_benchmark = cmd.option("reference_benchmark_file_path"); + CommandOptionId opt_tb_type = cmd.option("testbench_type"); + CommandOptionId opt_time_unit = cmd.option("time_unit"); CommandOptionId opt_verbose = cmd.option("verbose"); /* This is an intermediate data structure which is designed to modularize the FPGA-Verilog @@ -230,6 +235,32 @@ int write_simulation_task_info(const OpenfpgaContext& openfpga_ctx, options.set_verbose_output(cmd_context.option_enable(cmd, opt_verbose)); options.set_print_simulation_ini(cmd_context.option_value(cmd, opt_file)); + if (true == cmd_context.option_enable(cmd, opt_time_unit)) { + options.set_time_unit(string_to_time_unit(cmd_context.option_value(cmd, opt_time_unit))); + } + + /* Identify testbench type */ + std::string full_tb_tag("full_testbench"); + std::string preconfig_tb_tag("preconfigured_testbench"); + if (true == cmd_context.option_enable(cmd, opt_tb_type)) { + if (std::string("preconfigured_testbench") == cmd_context.option_value(cmd, opt_tb_type)) { + options.set_print_preconfig_top_testbench(true); + } else if (std::string("full_testbench") == cmd_context.option_value(cmd, opt_tb_type)) { + options.set_print_preconfig_top_testbench(false); + options.set_print_top_testbench(true); + } else { + /* Invalid option, error out */ + VTR_LOG_ERROR("Invalid option value for testbench type: '%s'! Should be either '%s' or '%s'\n", + cmd_context.option_value(cmd, opt_tb_type).c_str(), + full_tb_tag.c_str(), + preconfig_tb_tag.c_str()); + return CMD_EXEC_FATAL_ERROR; + } + } else { + /* Deposit default type which is the preconfigured testbench */ + options.set_print_preconfig_top_testbench(true); + } + return fpga_verilog_simulation_task_info(openfpga_ctx.module_graph(), openfpga_ctx.bitstream_manager(), g_vpr_ctx.atom(), diff --git a/openfpga/src/base/openfpga_verilog_command.cpp b/openfpga/src/base/openfpga_verilog_command.cpp index d2410bff3..c78d69595 100644 --- a/openfpga/src/base/openfpga_verilog_command.cpp +++ b/openfpga/src/base/openfpga_verilog_command.cpp @@ -243,6 +243,14 @@ ShellCommandId add_openfpga_write_simulation_task_info_command(openfpga::Shell units_map; - // units_map['s']=1; // units_map['ms']=1E-3; // units_map['us']=1E-6; - // units_map['ns']=1E-9; // units_map['ps']=1E-12; // units_map['fs']=1E-15; - /* Compute simulation time period */ - float simulation_time_period = find_simulation_time_period(1E-3, - num_program_clock_cycles, - 1. / prog_clock_freq, - num_operating_clock_cycles, - 1. / op_clock_freq); + /* Compute simulation time period: full testbench and pre-configured testbench has different length + * Currently, we only support the two types. And one of them must be enabled when outputting this file + */ + float simulation_time_period = 0.; + if (options.print_top_testbench()) { + simulation_time_period = find_simulation_time_period(options.time_unit(), + num_program_clock_cycles, + 1. / prog_clock_freq, + num_operating_clock_cycles, + 1. / op_clock_freq); + } else { + VTR_ASSERT(options.print_preconfig_top_testbench()); + simulation_time_period = find_operating_phase_simulation_time(1., + num_operating_clock_cycles, + 1. / op_clock_freq, + options.time_unit()); + } + /* Identify the testbench file name depending on the type */ + std::string top_tb_name; + if (options.print_top_testbench()) { + top_tb_name = circuit_name + std::string(AUTOCHECK_TOP_TESTBENCH_VERILOG_FILE_POSTFIX); + } else { + VTR_ASSERT(options.print_preconfig_top_testbench()); + top_tb_name = circuit_name + std::string(FORMAL_RANDOM_TOP_TESTBENCH_POSTFIX); + } /* Basic information */ ini["SIMULATION_DECK"]["PROJECTNAME "] = "ModelSimProject"; ini["SIMULATION_DECK"]["BENCHMARK "] = circuit_name; - ini["SIMULATION_DECK"]["TOP_TB"] = circuit_name + std::string(FORMAL_RANDOM_TOP_TESTBENCH_POSTFIX); + ini["SIMULATION_DECK"]["TOP_TB"] = top_tb_name; ini["SIMULATION_DECK"]["SIMTIME "] = std::to_string(simulation_time_period); - ini["SIMULATION_DECK"]["UNIT "] = "ms"; + 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_FILE_NAME); + ini["SIMULATION_DECK"]["VERILOG_FILE1"] = std::string(DEFINES_VERILOG_SIMULATION_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_simulation_info_writer.h b/openfpga/src/fpga_verilog/verilog_simulation_info_writer.h index 8806a71ac..9493a4e68 100644 --- a/openfpga/src/fpga_verilog/verilog_simulation_info_writer.h +++ b/openfpga/src/fpga_verilog/verilog_simulation_info_writer.h @@ -9,6 +9,7 @@ #include "config_protocol.h" #include "vpr_context.h" #include "io_location_map.h" +#include "verilog_testbench_options.h" /******************************************************************** * Function declaration @@ -18,6 +19,7 @@ namespace openfpga { void print_verilog_simulation_info(const std::string& ini_fname, + const VerilogTestbenchOption& options, const std::string& circuit_name, const std::string& src_dir, const AtomContext& atom_ctx, diff --git a/openfpga/src/fpga_verilog/verilog_testbench_options.cpp b/openfpga/src/fpga_verilog/verilog_testbench_options.cpp index cce9338cf..49d14dee6 100644 --- a/openfpga/src/fpga_verilog/verilog_testbench_options.cpp +++ b/openfpga/src/fpga_verilog/verilog_testbench_options.cpp @@ -24,6 +24,7 @@ VerilogTestbenchOption::VerilogTestbenchOption() { support_icarus_simulator_ = false; include_signal_init_ = false; default_net_type_ = VERILOG_DEFAULT_NET_TYPE_NONE; + time_unit_ = 1E-3; verbose_output_ = false; } @@ -82,6 +83,10 @@ e_verilog_default_net_type VerilogTestbenchOption::default_net_type() const { return default_net_type_; } +float VerilogTestbenchOption::time_unit() const { + return time_unit_; +} + bool VerilogTestbenchOption::verbose_output() const { return verbose_output_; } @@ -160,6 +165,10 @@ void VerilogTestbenchOption::set_default_net_type(const std::string& default_net } } +void VerilogTestbenchOption::set_time_unit(const float& time_unit) { + time_unit_ = time_unit; +} + void VerilogTestbenchOption::set_verbose_output(const bool& enabled) { verbose_output_ = enabled; } diff --git a/openfpga/src/fpga_verilog/verilog_testbench_options.h b/openfpga/src/fpga_verilog/verilog_testbench_options.h index 6b46d8316..a68a44bd2 100644 --- a/openfpga/src/fpga_verilog/verilog_testbench_options.h +++ b/openfpga/src/fpga_verilog/verilog_testbench_options.h @@ -36,6 +36,7 @@ class VerilogTestbenchOption { bool include_signal_init() const; bool support_icarus_simulator() const; e_verilog_default_net_type default_net_type() const; + float time_unit() const; bool verbose_output() const; public: /* Public validator */ bool validate() const; @@ -61,6 +62,7 @@ class VerilogTestbenchOption { void set_include_signal_init(const bool& enabled); void set_support_icarus_simulator(const bool& enabled); void set_default_net_type(const std::string& default_net_type); + void set_time_unit(const float& time_unit); void set_verbose_output(const bool& enabled); private: /* Internal Data */ std::string output_directory_; @@ -76,6 +78,7 @@ class VerilogTestbenchOption { bool support_icarus_simulator_; bool include_signal_init_; e_verilog_default_net_type default_net_type_; + float time_unit_; bool verbose_output_; };