ported verilog testbench generator online. Split from fabric generator. Testing to be done

This commit is contained in:
tangxifan 2020-02-27 12:33:09 -07:00
parent 77529f4957
commit f558405887
13 changed files with 459 additions and 112 deletions

View File

@ -15,7 +15,7 @@
namespace openfpga {
/********************************************************************
* A wrapper function to call the fabric_verilog function of FPGA-Verilog
* A wrapper function to call the fabric Verilog generator of FPGA-Verilog
*******************************************************************/
void write_fabric_verilog(OpenfpgaContext& openfpga_ctx,
const Command& cmd, const CommandContext& cmd_context) {
@ -26,9 +26,6 @@ void write_fabric_verilog(OpenfpgaContext& openfpga_ctx,
CommandOptionId opt_include_signal_init = cmd.option("include_signal_init");
CommandOptionId opt_support_icarus_simulator = cmd.option("support_icarus_simulator");
CommandOptionId opt_print_user_defined_template = cmd.option("print_user_defined_template");
CommandOptionId opt_print_top_testbench = cmd.option("print_top_testbench");
CommandOptionId opt_print_formal_verification_top_netlist = cmd.option("print_formal_verification_top_netlist");
CommandOptionId opt_print_autocheck_top_testbench = cmd.option("print_autocheck_top_testbench");
CommandOptionId opt_verbose = cmd.option("verbose");
/* This is an intermediate data structure which is designed to modularize the FPGA-Verilog
@ -41,9 +38,6 @@ void write_fabric_verilog(OpenfpgaContext& openfpga_ctx,
options.set_include_signal_init(cmd_context.option_enable(cmd, opt_include_signal_init));
options.set_support_icarus_simulator(cmd_context.option_enable(cmd, opt_support_icarus_simulator));
options.set_print_user_defined_template(cmd_context.option_enable(cmd, opt_print_user_defined_template));
options.set_print_top_testbench(cmd_context.option_enable(cmd, opt_print_top_testbench));
options.set_print_formal_verification_top_netlist(cmd_context.option_enable(cmd, opt_print_formal_verification_top_netlist));
options.set_print_autocheck_top_testbench(cmd_context.option_value(cmd, opt_print_autocheck_top_testbench));
options.set_verbose_output(cmd_context.option_enable(cmd, opt_verbose));
options.set_compress_routing(openfpga_ctx.flow_manager().compress_routing());
@ -56,4 +50,42 @@ void write_fabric_verilog(OpenfpgaContext& openfpga_ctx,
options);
}
/********************************************************************
* A wrapper function to call the Verilog testbench generator of FPGA-Verilog
*******************************************************************/
void write_verilog_testbench(OpenfpgaContext& openfpga_ctx,
const Command& cmd, const CommandContext& cmd_context) {
CommandOptionId opt_output_dir = cmd.option("file");
CommandOptionId opt_reference_benchmark = cmd.option("reference_verilog_file_path");
CommandOptionId opt_print_top_testbench = cmd.option("print_top_testbench");
CommandOptionId opt_print_formal_verification_top_netlist = cmd.option("print_formal_verification_top_netlist");
CommandOptionId opt_print_preconfig_top_testbench = cmd.option("print_preconfig_top_testbench");
CommandOptionId opt_print_simulation_ini = cmd.option("print_simulation_ini");
CommandOptionId opt_verbose = cmd.option("verbose");
/* This is an intermediate data structure which is designed to modularize the FPGA-Verilog
* Keep it independent from any other outside data structures
*/
VerilogTestbenchOption options;
options.set_output_directory(cmd_context.option_value(cmd, opt_output_dir));
options.set_reference_verilog_file_path(cmd_context.option_value(cmd, opt_reference_benchmark));
options.set_print_formal_verification_top_netlist(cmd_context.option_enable(cmd, opt_print_formal_verification_top_netlist));
options.set_print_preconfig_top_testbench(cmd_context.option_enable(cmd, opt_print_preconfig_top_testbench));
options.set_print_top_testbench(cmd_context.option_enable(cmd, opt_print_top_testbench));
options.set_print_simulation_ini(cmd_context.option_value(cmd, opt_print_simulation_ini));
options.set_verbose_output(cmd_context.option_enable(cmd, opt_verbose));
fpga_verilog_testbench(openfpga_ctx.module_graph(),
openfpga_ctx.bitstream_manager(),
openfpga_ctx.fabric_bitstream(),
g_vpr_ctx.atom(),
g_vpr_ctx.placement(),
openfpga_ctx.io_location_map(),
openfpga_ctx.arch().circuit_lib,
openfpga_ctx.arch().sim_setting,
openfpga_ctx.arch().config_protocol.type(),
options);
}
} /* end namespace openfpga */

View File

@ -18,6 +18,9 @@ namespace openfpga {
void write_fabric_verilog(OpenfpgaContext& openfpga_ctx,
const Command& cmd, const CommandContext& cmd_context);
void write_verilog_testbench(OpenfpgaContext& openfpga_ctx,
const Command& cmd, const CommandContext& cmd_context);
} /* end namespace openfpga */
#endif

View File

@ -11,6 +11,99 @@
/* begin namespace openfpga */
namespace openfpga {
/********************************************************************
* - Add a command to Shell environment: generate fabric Verilog
* - Add associated options
* - Add command dependency
*******************************************************************/
static
void add_openfpga_write_fabric_verilog_command(openfpga::Shell<OpenfpgaContext>& shell,
const ShellCommandClassId& cmd_class_id,
const ShellCommandId& shell_cmd_build_fabric_id) {
Command shell_cmd("write_fabric_verilog");
/* Add an option '--file' in short '-f'*/
CommandOptionId output_opt = shell_cmd.add_option("file", true, "Specify the output directory for Verilog netlists");
shell_cmd.set_option_short_name(output_opt, "f");
shell_cmd.set_option_require_value(output_opt, openfpga::OPT_STRING);
/* Add an option '--explicit_port_mapping' */
shell_cmd.add_option("explicit_port_mapping", false, "Use explicit port mapping in Verilog netlists");
/* Add an option '--include_timing' */
shell_cmd.add_option("include_timing", false, "Enable timing annotation in Verilog netlists");
/* Add an option '--include_signal_init' */
shell_cmd.add_option("include_signal_init", false, "Initialize all the signals in Verilog netlists");
/* Add an option '--support_icarus_simulator' */
shell_cmd.add_option("support_icarus_simulator", false, "Fine-tune Verilog netlists to support icarus simulator");
/* Add an option '--print_user_defined_template' */
shell_cmd.add_option("print_user_defined_template", false, "Generate a template Verilog files for user-defined circuit models");
/* Add an option '--verbose' */
shell_cmd.add_option("verbose", false, "Enable verbose output");
/* Add command 'write_fabric_verilog' to the Shell */
ShellCommandId shell_cmd_id = shell.add_command(shell_cmd, "generate Verilog netlists modeling full FPGA fabric");
shell.set_command_class(shell_cmd_id, cmd_class_id);
shell.set_command_execute_function(shell_cmd_id, write_verilog_testbench);
/* The 'build_fabric' command should NOT be executed before 'link_openfpga_arch' */
std::vector<ShellCommandId> cmd_dependency;
cmd_dependency.push_back(shell_cmd_build_fabric_id);
shell.set_command_dependency(shell_cmd_id, cmd_dependency);
}
/********************************************************************
* - Add a command to Shell environment: write Verilog testbench
* - Add associated options
* - Add command dependency
*******************************************************************/
static
void add_openfpga_write_verilog_testbench_command(openfpga::Shell<OpenfpgaContext>& shell,
const ShellCommandClassId& cmd_class_id,
const ShellCommandId& shell_cmd_build_fabric_id) {
Command shell_cmd("write_verilog_testbench");
/* Add an option '--file' in short '-f'*/
CommandOptionId output_opt = shell_cmd.add_option("file", true, "Specify the output directory for Verilog netlists");
shell_cmd.set_option_short_name(output_opt, "f");
shell_cmd.set_option_require_value(output_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");
shell_cmd.set_option_require_value(ref_bm_opt, openfpga::OPT_STRING);
/* Add an option '--print_top_testbench' */
shell_cmd.add_option("print_top_testbench", false, "Generate a full testbench for top-level fabric module with autocheck capability");
/* Add an option '--print_formal_verification_top_netlist' */
shell_cmd.add_option("print_formal_verification_top_netlist", false, "Generate a top-level module which can be used in formal verification");
/* Add an option '--print_preconfig_top_testbench' */
CommandOptionId preconfig_tb_opt = shell_cmd.add_option("print_preconfig_top_testbench", false, "Generate a pre-configured testbench for top-level fabric module with autocheck capability");
shell_cmd.set_option_require_value(preconfig_tb_opt, openfpga::OPT_STRING);
/* Add an option '--print_simulation_ini' */
CommandOptionId sim_ini_opt = shell_cmd.add_option("print_simulation_ini", false, "Generate a .ini file as an exchangeable file to enable HDL simulations");
shell_cmd.set_option_require_value(sim_ini_opt, openfpga::OPT_STRING);
/* Add an option '--verbose' */
shell_cmd.add_option("verbose", false, "Enable verbose output");
/* Add command to the Shell */
ShellCommandId shell_cmd_id = shell.add_command(shell_cmd, "generate Verilog testbenches for full FPGA fabric");
shell.set_command_class(shell_cmd_id, cmd_class_id);
shell.set_command_execute_function(shell_cmd_id, write_fabric_verilog);
/* The command should NOT be executed before 'build_fabric' */
std::vector<ShellCommandId> cmd_dependency;
cmd_dependency.push_back(shell_cmd_build_fabric_id);
shell.set_command_dependency(shell_cmd_id, cmd_dependency);
}
void add_openfpga_verilog_commands(openfpga::Shell<OpenfpgaContext>& shell) {
/* Get the unique id of 'build_fabric' command which is to be used in creating the dependency graph */
const ShellCommandId& shell_cmd_build_fabric_id = shell.command(std::string("build_fabric"));
@ -19,42 +112,18 @@ void add_openfpga_verilog_commands(openfpga::Shell<OpenfpgaContext>& shell) {
ShellCommandClassId openfpga_verilog_cmd_class = shell.add_command_class("FPGA-Verilog");
/********************************
* Command 'wirte_fabric_verilog'
* Command 'write_fabric_verilog'
*/
Command shell_cmd_write_fabric_verilog("write_fabric_verilog");
/* Add an option '--file' in short '-f'*/
CommandOptionId fabric_verilog_output_opt = shell_cmd_write_fabric_verilog.add_option("file", true, "Specify the output directory for Verilog netlists");
shell_cmd_write_fabric_verilog.set_option_short_name(fabric_verilog_output_opt, "f");
shell_cmd_write_fabric_verilog.set_option_require_value(fabric_verilog_output_opt, openfpga::OPT_STRING);
/* Add an option '--explicit_port_mapping' */
shell_cmd_write_fabric_verilog.add_option("explicit_port_mapping", false, "Use explicit port mapping in Verilog netlists");
/* Add an option '--include_timing' */
shell_cmd_write_fabric_verilog.add_option("include_timing", false, "Enable timing annotation in Verilog netlists");
/* Add an option '--include_signal_init' */
shell_cmd_write_fabric_verilog.add_option("include_signal_init", false, "Initialize all the signals in Verilog netlists");
/* Add an option '--support_icarus_simulator' */
shell_cmd_write_fabric_verilog.add_option("support_icarus_simulator", false, "Fine-tune Verilog netlists to support icarus simulator");
/* Add an option '--print_user_defined_template' */
shell_cmd_write_fabric_verilog.add_option("print_user_defined_template", false, "Generate a template Verilog files for user-defined circuit models");
/* Add an option '--print_top_testbench' */
shell_cmd_write_fabric_verilog.add_option("print_top_testbench", false, "Generate a testbench for top-level fabric module");
/* Add an option '--print_formal_verification_top_netlist' */
shell_cmd_write_fabric_verilog.add_option("print_formal_verification_top_netlist", false, "Generate a top-level module which can be used in formal verification");
/* Add an option '--print_autocheck_top_testbench' */
CommandOptionId fabric_verilog_autocheck_tb_opt = shell_cmd_write_fabric_verilog.add_option("print_autocheck_top_testbench", false, "Generate a testbench for top-level fabric module with autocheck capability");
shell_cmd_write_fabric_verilog.set_option_require_value(fabric_verilog_autocheck_tb_opt, openfpga::OPT_STRING);
/* Add an option '--verbose' */
shell_cmd_write_fabric_verilog.add_option("verbose", false, "Enable verbose output");
/* Add command 'write_fabric_verilog' to the Shell */
ShellCommandId shell_cmd_write_fabric_verilog_id = shell.add_command(shell_cmd_write_fabric_verilog, "generate Verilog netlists modeling full FPGA fabric");
shell.set_command_class(shell_cmd_write_fabric_verilog_id, openfpga_verilog_cmd_class);
shell.set_command_execute_function(shell_cmd_write_fabric_verilog_id, write_fabric_verilog);
add_openfpga_write_fabric_verilog_command(shell,
openfpga_verilog_cmd_class,
shell_cmd_build_fabric_id);
/* The 'build_fabric' command should NOT be executed before 'link_openfpga_arch' */
std::vector<ShellCommandId> cmd_dependency_write_fabric_verilog;
cmd_dependency_write_fabric_verilog.push_back(shell_cmd_build_fabric_id);
shell.set_command_dependency(shell_cmd_write_fabric_verilog_id, cmd_dependency_write_fabric_verilog);
/********************************
* Command 'write_verilog_testbench'
*/
add_openfpga_write_verilog_testbench_command(shell,
openfpga_verilog_cmd_class,
shell_cmd_build_fabric_id);
}
} /* end namespace openfpga */

View File

@ -3,7 +3,7 @@
******************************************************************************/
#include "vtr_assert.h"
#include "verilog_options.h"
#include "fabric_verilog_options.h"
/* begin namespace openfpga */
namespace openfpga {
@ -52,22 +52,6 @@ bool FabricVerilogOption::compress_routing() const {
return compress_routing_;
}
bool FabricVerilogOption::print_top_testbench() const {
return print_top_testbench_;
}
bool FabricVerilogOption::print_formal_verification_top_netlist() const {
return print_formal_verification_top_netlist_;
}
bool FabricVerilogOption::print_autocheck_top_testbench() const {
return false == reference_verilog_file_path_.empty();
}
std::string FabricVerilogOption::reference_verilog_file_path() const {
return reference_verilog_file_path_;
}
bool FabricVerilogOption::print_user_defined_template() const {
return print_user_defined_template_;
}
@ -103,18 +87,6 @@ void FabricVerilogOption::set_compress_routing(const bool& enabled) {
compress_routing_ = enabled;
}
void FabricVerilogOption::set_print_top_testbench(const bool& enabled) {
print_top_testbench_ = enabled;
}
void FabricVerilogOption::set_print_formal_verification_top_netlist(const bool& enabled) {
print_formal_verification_top_netlist_ = enabled;
}
void FabricVerilogOption::set_print_autocheck_top_testbench(const std::string& reference_verilog_file_path) {
reference_verilog_file_path_ = reference_verilog_file_path;
}
void FabricVerilogOption::set_print_user_defined_template(const bool& enabled) {
print_user_defined_template_ = enabled;
}

View File

@ -1,5 +1,5 @@
#ifndef VERILOG_OPTIONS_H
#define VERILOG_OPTIONS_H
#ifndef FABRIC_VERILOG_OPTIONS_H
#define FABRIC_VERILOG_OPTIONS_H
/********************************************************************
* Include header files required by the data structure definition
@ -10,11 +10,7 @@
namespace openfpga {
/********************************************************************
* FlowManager aims to resolve the dependency between OpenFPGA functional
* code blocks
* It can provide flags for downstream modules about if the data structures
* they require have already been constructed
*
* Options for Fabric Verilog generator
*******************************************************************/
class FabricVerilogOption {
public: /* Public constructor */

View File

@ -20,6 +20,10 @@
#include "verilog_grid.h"
#include "verilog_top_module.h"
#include "verilog_preconfig_top_module.h"
#include "verilog_formal_random_top_testbench.h"
#include "verilog_top_testbench.h"
/* Header file for this source file */
#include "verilog_api.h"
@ -27,17 +31,18 @@
namespace openfpga {
/********************************************************************
* Top-level function of FPGA-Verilog
* A top-level function of FPGA-Verilog which focuses on fabric Verilog generation
* This function will generate
* 1. primitive modules required by the full fabric
* which are LUTs, routing multiplexer, logic gates, transmission-gates etc.
* 2. Routing modules, which are Switch Blocks (SBs) and Connection Blocks (CBs)
* 3. Logic block modules, which are Configuration Logic Blocks (CLBs)
* 4. FPGA module, which are the full FPGA fabric with configuration protocol
* 5. A wrapper module, which encapsulate the FPGA module in a Verilog module which have the same port as the input benchmark
* 6. Testbench, where a FPGA module is configured with a bitstream and then driven by input vectors
* 7. Pre-configured testbench, which can skip the configuration phase and pre-configure the FPGA module. This testbench is created for quick verification and formal verification purpose.
* 8. Verilog netlist including preprocessing flags and all the Verilog netlists that have been generated
* - primitive modules required by the full fabric
* - which are LUTs, routing multiplexer, logic gates, transmission-gates etc.
* - Routing modules, which are Switch Blocks (SBs) and Connection Blocks (CBs)
* - Logic block modules, which are Configuration Logic Blocks (CLBs)
* - FPGA module, which are the full FPGA fabric with configuration protocol
*
* Note:
* - Please do NOT include ANY testbench generation in this function!!!
* It is about the fabric itself, independent from any implementation
* All the testbench generation should be in the function fpga_testbench_verilog()
*
* TODO: We should use module manager as a constant here.
* All the modification should be done before this writer!
@ -75,9 +80,6 @@ void fpga_fabric_verilog(ModuleManager& module_manager,
print_verilog_preprocessing_flags_netlist(std::string(src_dir_path),
options);
print_verilog_simulation_preprocessing_flags(std::string(src_dir_path),
options);
/* Generate primitive Verilog modules, which are corner stones of FPGA fabric
* Note that this function MUST be called before Verilog generation of
* core logic (i.e., logic blocks and routing resources) !!!
@ -121,4 +123,106 @@ void fpga_fabric_verilog(ModuleManager& module_manager,
module_manager.num_modules());
}
/********************************************************************
* A top-level function of FPGA-Verilog which focuses on fabric Verilog generation
* This function will generate
* - A wrapper module, which encapsulate the FPGA module in a Verilog module which have the same port as the input benchmark
* - Testbench, where a FPGA module is configured with a bitstream and then driven by input vectors
* - Pre-configured testbench, which can skip the configuration phase and pre-configure the FPGA module.
* This testbench is created for quick verification and formal verification purpose.
* - Verilog netlist including preprocessing flags and all the Verilog netlists that have been generated
********************************************************************/
void fpga_verilog_testbench(const ModuleManager& module_manager,
const BitstreamManager& bitstream_manager,
const std::vector<ConfigBitId>& fabric_bitstream,
const AtomContext& atom_ctx,
const PlacementContext& place_ctx,
const IoLocationMap& io_location_map,
const CircuitLibrary& circuit_lib,
const SimulationSetting& simulation_setting,
const e_config_protocol_type& config_protocol_type,
const VerilogTestbenchOption& options) {
vtr::ScopedStartFinishTimer timer("Write Verilog testbenches for FPGA fabric\n");
std::string src_dir_path = format_dir_path(options.output_directory());
std::string netlist_name = atom_ctx.nlist.netlist_name();
/* Create directories */
create_dir_path(src_dir_path.c_str());
/* TODO: check if this works here. This function was in fabric generator */
print_verilog_simulation_preprocessing_flags(std::string(src_dir_path),
options);
/* Collect global ports from the circuit library:
* TODO: should we place this in the OpenFPGA context?
*/
std::vector<CircuitPortId> global_ports = find_circuit_library_global_ports(circuit_lib);
/* Generate wrapper module for FPGA fabric (mapped by the input benchmark and pre-configured testbench for verification */
if (true == options.print_formal_verification_top_netlist()) {
std::string formal_verification_top_netlist_file_path = src_dir_path + netlist_name
+ std::string(FORMAL_VERIFICATION_VERILOG_FILE_POSTFIX);
print_verilog_preconfig_top_module(module_manager, bitstream_manager,
circuit_lib, global_ports,
atom_ctx, place_ctx, io_location_map,
netlist_name,
formal_verification_top_netlist_file_path,
src_dir_path);
}
if (true == options.print_preconfig_top_testbench()) {
/* Generate top-level testbench using random vectors */
std::string random_top_testbench_file_path = src_dir_path + netlist_name
+ std::string(RANDOM_TOP_TESTBENCH_VERILOG_FILE_POSTFIX);
print_verilog_random_top_testbench(netlist_name,
random_top_testbench_file_path,
src_dir_path,
atom_ctx,
simulation_setting);
}
/* Generate full testbench for verification, including configuration phase and operating phase */
if (true == options.print_top_testbench()) {
std::string top_testbench_file_path = src_dir_path + netlist_name
+ std::string(AUTOCHECK_TOP_TESTBENCH_VERILOG_FILE_POSTFIX);
print_verilog_top_testbench(module_manager,
bitstream_manager, fabric_bitstream,
config_protocol_type,
circuit_lib, global_ports,
atom_ctx, place_ctx, io_location_map,
netlist_name,
top_testbench_file_path,
src_dir_path,
simulation_setting);
}
/* TODO: Generate exchangeable files which contains simulation settings
if (true == options.print_simulation_ini()) {
std::string simulation_ini_file_name;
if (true != options.simulation_ini_path()) {
simulation_ini_file_name = options.simulation_ini_path();
}
print_verilog_simulation_info(simulation_ini_file_name,
format_dir_path(chomped_parent_dir),
netlist_name,
src_dir_path,
bitstream_manager.bits().size(),
simulation_setting.num_clock_cycle(),
simulation_setting.programming_clock_frequency(),
simulation_setting.operating_clock_frequency());
}
*/
/* Generate a Verilog file including all the netlists that have been generated */
print_include_netlists(src_dir_path,
netlist_name,
options.reference_verilog_file_path(),
circuit_lib);
}
} /* end namespace openfpga */

View File

@ -7,14 +7,17 @@
#include <string>
#include <vector>
#include "vpr_types.h"
#include "mux_library.h"
#include "circuit_library.h"
#include "vpr_context.h"
#include "vpr_device_annotation.h"
#include "device_rr_gsb.h"
#include "module_manager.h"
#include "verilog_options.h"
#include "bitstream_manager.h"
#include "simulation_setting.h"
#include "io_location_map.h"
#include "fabric_verilog_options.h"
#include "verilog_testbench_options.h"
/********************************************************************
* Function declaration
@ -31,6 +34,18 @@ void fpga_fabric_verilog(ModuleManager& module_manager,
const DeviceRRGSB& device_rr_gsb,
const FabricVerilogOption& options);
void fpga_verilog_testbench(const ModuleManager& module_manager,
const BitstreamManager& bitstream_manager,
const std::vector<ConfigBitId>& fabric_bitstream,
const AtomContext& atom_ctx,
const PlacementContext& place_ctx,
const IoLocationMap& io_location_map,
const CircuitLibrary& circuit_lib,
const SimulationSetting& simulation_parameters,
const e_config_protocol_type& config_protocol_type,
const VerilogTestbenchOption& options);
} /* end namespace openfpga */
#endif

View File

@ -115,7 +115,7 @@ void print_include_netlists(const std::string& src_dir,
* which are used enable/disable some features in FPGA Verilog modules
*******************************************************************/
void print_verilog_preprocessing_flags_netlist(const std::string& src_dir,
const FabricVerilogOption& fpga_verilog_opts) {
const FabricVerilogOption& fabric_verilog_opts) {
std::string verilog_fname = src_dir + std::string(DEFINES_VERILOG_FILE_NAME);
@ -130,25 +130,19 @@ void print_verilog_preprocessing_flags_netlist(const std::string& src_dir,
print_verilog_file_header(fp, std::string("Preprocessing flags to enable/disable features in FPGA Verilog modules"));
/* To enable timing */
if (true == fpga_verilog_opts.include_timing()) {
if (true == fabric_verilog_opts.include_timing()) {
print_verilog_define_flag(fp, std::string(VERILOG_TIMING_PREPROC_FLAG), 1);
fp << std::endl;
}
/* To enable timing */
if (true == fpga_verilog_opts.include_signal_init()) {
if (true == fabric_verilog_opts.include_signal_init()) {
print_verilog_define_flag(fp, std::string(VERILOG_SIGNAL_INIT_PREPROC_FLAG), 1);
fp << std::endl;
}
/* To enable formal verfication flag */
if (true == fpga_verilog_opts.print_formal_verification_top_netlist()) {
print_verilog_define_flag(fp, std::string(VERILOG_FORMAL_VERIFICATION_PREPROC_FLAG), 1);
fp << std::endl;
}
/* To enable functional verfication with Icarus */
if (true == fpga_verilog_opts.support_icarus_simulator()) {
if (true == fabric_verilog_opts.support_icarus_simulator()) {
print_verilog_define_flag(fp, std::string(ICARUS_SIMULATOR_FLAG), 1);
fp << std::endl;
}
@ -161,7 +155,7 @@ void print_verilog_preprocessing_flags_netlist(const std::string& src_dir,
* Print a Verilog file containing simulation-related preprocessing flags
*******************************************************************/
void print_verilog_simulation_preprocessing_flags(const std::string& src_dir,
const FabricVerilogOption& fpga_verilog_opts) {
const VerilogTestbenchOption& verilog_testbench_opts) {
std::string verilog_fname = src_dir + std::string(DEFINES_VERILOG_SIMULATION_FILE_NAME);
@ -176,19 +170,20 @@ void print_verilog_simulation_preprocessing_flags(const std::string& src_dir,
print_verilog_file_header(fp, std::string("Preprocessing flags to enable/disable simulation features"));
/* To enable manualy checked simulation */
if (true == fpga_verilog_opts.print_top_testbench()) {
if (true == verilog_testbench_opts.print_top_testbench()) {
print_verilog_define_flag(fp, std::string(INITIAL_SIMULATION_FLAG), 1);
fp << std::endl;
}
/* To enable auto-checked simulation */
if (true == fpga_verilog_opts.print_autocheck_top_testbench()) {
if ( (true == verilog_testbench_opts.print_preconfig_top_testbench())
|| (true == verilog_testbench_opts.print_top_testbench()) ) {
print_verilog_define_flag(fp, std::string(AUTOCHECKED_SIMULATION_FLAG), 1);
fp << std::endl;
}
/* To enable pre-configured FPGA simulation */
if (true == fpga_verilog_opts.print_formal_verification_top_netlist()) {
if (true == verilog_testbench_opts.print_formal_verification_top_netlist()) {
print_verilog_define_flag(fp, std::string(FORMAL_SIMULATION_FLAG), 1);
fp << std::endl;
}

View File

@ -6,7 +6,8 @@
*******************************************************************/
#include <string>
#include "circuit_library.h"
#include "verilog_options.h"
#include "fabric_verilog_options.h"
#include "verilog_testbench_options.h"
/********************************************************************
* Function declaration
@ -21,10 +22,10 @@ void print_include_netlists(const std::string& src_dir,
const CircuitLibrary& circuit_lib);
void print_verilog_preprocessing_flags_netlist(const std::string& src_dir,
const FabricVerilogOption& fpga_verilog_opts);
const FabricVerilogOption& fabric_verilog_opts);
void print_verilog_simulation_preprocessing_flags(const std::string& src_dir,
const FabricVerilogOption& fpga_verilog_opts);
const VerilogTestbenchOption& verilog_testbench_opts);
} /* end namespace openfpga */

View File

@ -6,10 +6,11 @@
*******************************************************************/
#include <vector>
#include <string>
#include "circuit_types.h"
#include "vpr_types.h"
#include "circuit_library.h"
#include "vpr_context.h"
#include "module_manager.h"
#include "bitstream_manager.h"
#include "io_location_map.h"
/********************************************************************
* Function declaration

View File

@ -6,7 +6,7 @@
*******************************************************************/
#include "module_manager.h"
#include "mux_library.h"
#include "verilog_options.h"
#include "fabric_verilog_options.h"
/********************************************************************
* Function declaration

View File

@ -0,0 +1,97 @@
/******************************************************************************
* Memember functions for data structure VerilogTestbenchOption
******************************************************************************/
#include "vtr_assert.h"
#include "verilog_testbench_options.h"
/* begin namespace openfpga */
namespace openfpga {
/**************************************************
* Public Constructors
*************************************************/
VerilogTestbenchOption::VerilogTestbenchOption() {
output_directory_.clear();
reference_verilog_file_path_.clear();
print_preconfig_top_testbench_ = false;
print_formal_verification_top_netlist_ = false;
print_top_testbench_ = false;
simulation_ini_path_.clear();
verbose_output_ = false;
}
/**************************************************
* Public Accessors
*************************************************/
std::string VerilogTestbenchOption::output_directory() const {
return output_directory_;
}
std::string VerilogTestbenchOption::reference_verilog_file_path() const {
return reference_verilog_file_path_;
}
bool VerilogTestbenchOption::print_formal_verification_top_netlist() const {
return print_formal_verification_top_netlist_;
}
bool VerilogTestbenchOption::print_preconfig_top_testbench() const {
return print_preconfig_top_testbench_;
}
bool VerilogTestbenchOption::print_top_testbench() const {
return print_top_testbench_;
}
bool VerilogTestbenchOption::print_simulation_ini() const {
return !simulation_ini_path_.empty();
}
std::string VerilogTestbenchOption::simulation_ini_path() const {
return simulation_ini_path_;
}
bool VerilogTestbenchOption::verbose_output() const {
return verbose_output_;
}
/******************************************************************************
* Private Mutators
******************************************************************************/
void VerilogTestbenchOption::set_output_directory(const std::string& output_dir) {
output_directory_ = output_dir;
}
void VerilogTestbenchOption::set_reference_verilog_file_path(const std::string& reference_verilog_file_path) {
reference_verilog_file_path_ = reference_verilog_file_path;
/* Chain effect on other options:
* Enable/disable the print_preconfig_top_testbench and print_top_testbench
*/
set_print_preconfig_top_testbench(print_preconfig_top_testbench_);
set_print_top_testbench(print_top_testbench_);
}
void VerilogTestbenchOption::set_print_formal_verification_top_netlist(const bool& enabled) {
print_formal_verification_top_netlist_ = enabled;
}
void VerilogTestbenchOption::set_print_preconfig_top_testbench(const bool& enabled) {
print_preconfig_top_testbench_ = enabled
&& print_formal_verification_top_netlist_
&& (!reference_verilog_file_path_.empty());
}
void VerilogTestbenchOption::set_print_top_testbench(const bool& enabled) {
print_top_testbench_ = enabled && (!reference_verilog_file_path_.empty());
}
void VerilogTestbenchOption::set_print_simulation_ini(const std::string& simulation_ini_path) {
simulation_ini_path_ = simulation_ini_path;
}
void VerilogTestbenchOption::set_verbose_output(const bool& enabled) {
verbose_output_ = enabled;
}
} /* end namespace openfpga */

View File

@ -0,0 +1,62 @@
#ifndef VERILOG_TESTBENCH_OPTIONS_H
#define VERILOG_TESTBENCH_OPTIONS_H
/********************************************************************
* Include header files required by the data structure definition
*******************************************************************/
#include <string>
/* Begin namespace openfpga */
namespace openfpga {
/********************************************************************
* Options for Verilog Testbench generator
* Typicall usage:
* VerilogTestbench verilog_tb_opt();
* // Set options
* ...
*
*******************************************************************/
class VerilogTestbenchOption {
public: /* Public constructor */
/* Set default options */
VerilogTestbenchOption();
public: /* Public accessors */
std::string output_directory() const;
std::string reference_verilog_file_path() const;
bool print_formal_verification_top_netlist() const;
bool print_preconfig_top_testbench() const;
bool print_top_testbench() const;
bool print_simulation_ini() const;
std::string simulation_ini_path() const;
bool verbose_output() const;
public: /* Public validator */
bool validate() const;
public: /* Public mutators */
void set_output_directory(const std::string& output_dir);
/* The reference verilog file path is the key parameters that will have an impact on other options:
* - print_preconfig_top_testbench
* - print_top_testbench
* If the file path is empty, the above testbench generation will not be enabled
*/
void set_reference_verilog_file_path(const std::string& reference_verilog_file_path);
void set_print_formal_verification_top_netlist(const bool& enabled);
/* The preconfig top testbench generation can be enabled only when formal verification top netlist is enabled */
void set_print_preconfig_top_testbench(const bool& enabled);
void set_print_top_testbench(const bool& enabled);
void set_print_simulation_ini(const std::string& simulation_ini_path);
void set_verbose_output(const bool& enabled);
private: /* Internal Data */
std::string output_directory_;
std::string reference_verilog_file_path_;
bool print_formal_verification_top_netlist_;
bool print_preconfig_top_testbench_;
bool print_top_testbench_;
/* Print simulation ini is enabled only when the path is not empty */
std::string simulation_ini_path_;
bool verbose_output_;
};
} /* End namespace openfpga*/
#endif