bring preprocessing flag Verilog netlists online

This commit is contained in:
tangxifan 2020-02-16 00:03:24 -07:00
parent 0d5292ad0d
commit 4cb61e2138
6 changed files with 281 additions and 6 deletions

View File

@ -14,6 +14,7 @@
#include "device_rr_gsb.h"
#include "verilog_constants.h"
#include "verilog_auxiliary_netlists.h"
//#include "verilog_submodules.h"
//#include "verilog_routing.h"
//#include "verilog_submodules.h"
@ -67,11 +68,11 @@ void fpga_fabric_verilog(const ModuleManager& module_manager,
create_dir_path(rr_dir_path.c_str());
/* Print Verilog files containing preprocessing flags */
//print_verilog_preprocessing_flags_netlist(std::string(src_dir_path),
// vpr_setup.FPGA_SPICE_Opts.SynVerilogOpts);
print_verilog_preprocessing_flags_netlist(std::string(src_dir_path),
options);
//print_verilog_simulation_preprocessing_flags(std::string(src_dir_path),
// vpr_setup.FPGA_SPICE_Opts.SynVerilogOpts);
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

View File

@ -0,0 +1,200 @@
/********************************************************************
* This file includes functions that are used to generate Verilog files
* or code blocks, with a focus on
* `include user-defined or auto-generated netlists in Verilog format
*******************************************************************/
#include <fstream>
/* Headers from vtrutil library */
#include "vtr_assert.h"
/* Headers from openfpgautil library */
#include "openfpga_digest.h"
#include "openfpga_naming.h"
#include "circuit_library_utils.h"
#include "verilog_constants.h"
#include "verilog_writer_utils.h"
#include "verilog_auxiliary_netlists.h"
/* begin namespace openfpga */
namespace openfpga {
/********************************************************************
* Local constant variables
*******************************************************************/
constexpr char* TOP_INCLUDE_NETLIST_FILE_NAME_POSTFIX = "_include_netlists.v";
/********************************************************************
* Print a file that includes all the netlists that have been generated
* and user-defined.
* Some netlists are open to compile under specific preprocessing flags
*******************************************************************/
void print_include_netlists(const std::string& src_dir,
const std::string& circuit_name,
const std::string& reference_benchmark_file,
const CircuitLibrary& circuit_lib) {
std::string verilog_fname = src_dir + circuit_name + std::string(TOP_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 defines: preproc flags -----"));
print_verilog_include_netlist(fp, std::string(src_dir + std::string(DEFINES_VERILOG_FILE_NAME)));
fp << std::endl;
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 all the user-defined netlists */
for (const std::string& user_defined_netlist : find_circuit_library_unique_verilog_netlists(circuit_lib)) {
print_verilog_include_netlist(fp, user_defined_netlist);
}
/* Include all the primitive modules */
print_verilog_include_netlist(fp, src_dir + std::string(DEFAULT_SUBMODULE_DIR_NAME) + std::string(SUBMODULE_VERILOG_FILE_NAME));
fp << std::endl;
/* Include all the CLB, heterogeneous block modules */
print_verilog_include_netlist(fp, src_dir + std::string(DEFAULT_LB_DIR_NAME) + std::string(LOGIC_BLOCK_VERILOG_FILE_NAME));
fp << std::endl;
/* Include all the routing architecture modules */
print_verilog_include_netlist(fp, src_dir + std::string(DEFAULT_RR_DIR_NAME) + std::string(ROUTING_VERILOG_FILE_NAME));
fp << std::endl;
/* Include FPGA top module */
print_verilog_include_netlist(fp, src_dir + generate_fpga_top_netlist_name(std::string(VERILOG_NETLIST_FILE_POSTFIX)));
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, std::string(reference_benchmark_file));
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));
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_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;
/* Close the file stream */
fp.close();
}
/********************************************************************
* Print a Verilog file containing preprocessing flags
* 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) {
std::string verilog_fname = src_dir + std::string(DEFINES_VERILOG_FILE_NAME);
/* 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("Preprocessing flags to enable/disable features in FPGA Verilog modules"));
/* To enable timing */
if (true == fpga_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()) {
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()) {
print_verilog_define_flag(fp, std::string(ICARUS_SIMULATOR_FLAG), 1);
fp << std::endl;
}
/* Close the file stream */
fp.close();
}
/********************************************************************
* 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) {
std::string verilog_fname = src_dir + std::string(DEFINES_VERILOG_SIMULATION_FILE_NAME);
/* 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("Preprocessing flags to enable/disable simulation features"));
/* To enable manualy checked simulation */
if (true == fpga_verilog_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()) {
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()) {
print_verilog_define_flag(fp, std::string(FORMAL_SIMULATION_FLAG), 1);
fp << std::endl;
}
/* Close the file stream */
fp.close();
}
} /* end namespace openfpga */

View File

@ -0,0 +1,31 @@
#ifndef VERILOG_AUXILIARY_NETLISTS_H
#define VERILOG_AUXILIARY_NETLISTS_H
/********************************************************************
* Include header files that are required by function declaration
*******************************************************************/
#include <string>
#include "circuit_library.h"
#include "verilog_options.h"
/********************************************************************
* Function declaration
*******************************************************************/
/* begin namespace openfpga */
namespace openfpga {
void print_include_netlists(const std::string& src_dir,
const std::string& circuit_name,
const std::string& reference_benchmark_file,
const CircuitLibrary& circuit_lib);
void print_verilog_preprocessing_flags_netlist(const std::string& src_dir,
const FabricVerilogOption& fpga_verilog_opts);
void print_verilog_simulation_preprocessing_flags(const std::string& src_dir,
const FabricVerilogOption& fpga_verilog_opts);
} /* end namespace openfpga */
#endif

View File

@ -8,7 +8,7 @@ constexpr float VERILOG_SIM_TIMESCALE = 1e-9; // Verilog Simulation time scale (
constexpr char* VERILOG_TIMING_PREPROC_FLAG = "ENABLE_TIMING"; // the flag to enable timing definition during compilation
constexpr char* VERILOG_SIGNAL_INIT_PREPROC_FLAG = "ENABLE_SIGNAL_INITIALIZATION"; // the flag to enable signal initialization during compilation
constexpr char* VERILOG_FORMAL_VERIFICATGION_PREPROC_FLAG = "ENABLE_FORMAL_VERIFICATION"; // the flag to enable formal verification during compilation
constexpr char* VERILOG_FORMAL_VERIFICATION_PREPROC_FLAG = "ENABLE_FORMAL_VERIFICATION"; // the flag to enable formal verification during compilation
constexpr char* INITIAL_SIMULATION_FLAG = "INITIAL_SIMULATION"; // the flag to enable initial functional verification
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
@ -19,10 +19,14 @@ constexpr char* DEFAULT_SUBMODULE_DIR_NAME = "sub_module/";
constexpr char* MODELSIM_SIMULATION_TIME_UNIT = "ms";
// Icarus variables and flag
constexpr char* ICARUS_SIMULATION_FLAG = "ICARUS_SIMULATOR"; // the flag to enable specific Verilog code in testbenches
constexpr char* ICARUS_SIMULATOR_FLAG = "ICARUS_SIMULATOR"; // the flag to enable specific Verilog code in testbenches
// End of Icarus variables and flag
constexpr char* VERILOG_TOP_POSTFIX = "_top.v";
constexpr char* FORMAL_VERIFICATION_VERILOG_FILE_POSTFIX = "_top_formal_verification.v";
constexpr char* TOP_TESTBENCH_VERILOG_FILE_POSTFIX = "_top_tb.v"; /* !!! must be consist with the modelsim_testbench_module_postfix */
constexpr char* AUTOCHECK_TOP_TESTBENCH_VERILOG_FILE_POSTFIX = "_autocheck_top_tb.v"; /* !!! must be consist with the modelsim_autocheck_testbench_module_postfix */
constexpr char* RANDOM_TOP_TESTBENCH_VERILOG_FILE_POSTFIX = "_formal_random_top_tb.v";
constexpr char* DEFINES_VERILOG_FILE_NAME = "fpga_defines.v";
constexpr char* DEFINES_VERILOG_SIMULATION_FILE_NAME = "define_simulation.v";
constexpr char* SUBMODULE_VERILOG_FILE_NAME = "sub_module.v";

View File

@ -35,6 +35,22 @@ 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::verbose_output() const {
return verbose_output_;
}
@ -66,6 +82,18 @@ 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_verbose_output(const bool& enabled) {
verbose_output_ = enabled;
}

View File

@ -24,6 +24,10 @@ class FabricVerilogOption {
bool include_signal_init() const;
bool explicit_port_mapping() const;
bool compress_routing() const;
bool print_top_testbench() const;
bool print_formal_verification_top_netlist() const;
bool print_autocheck_top_testbench() const;
std::string reference_verilog_file_path() const;
bool verbose_output() const;
public: /* Public mutators */
void set_output_directory(const std::string& output_dir);
@ -32,6 +36,9 @@ class FabricVerilogOption {
void set_include_signal_init(const bool& enabled);
void set_explicit_port_mapping(const bool& enabled);
void set_compress_routing(const bool& enabled);
void set_print_top_testbench(const bool& enabled);
void set_print_formal_verification_top_netlist(const bool& enabled);
void set_print_autocheck_top_testbench(const std::string& reference_verilog_file_path);
void set_verbose_output(const bool& enabled);
private: /* Internal Data */
std::string output_directory_;
@ -40,6 +47,10 @@ class FabricVerilogOption {
bool include_timing_;
bool explicit_port_mapping_;
bool compress_routing_;
bool print_top_testbench_;
bool print_formal_verification_top_netlist_;
/* print_autocheck_top_testbench will be enabled when reference file path is not empty */
std::string reference_verilog_file_path_;
bool verbose_output_;
};