From ebab0e91ef7c0e058f2d6fc5a8afa1921035f524 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Mon, 4 Nov 2019 20:55:30 -0700 Subject: [PATCH] refactored include netlist writer --- .../libarchfpga/SRC/circuit_library_utils.cpp | 23 ++++ .../libarchfpga/SRC/circuit_library_utils.h | 2 + .../vpr/SRC/fpga_x2p/verilog/verilog_api.c | 9 ++ .../verilog_formal_random_top_testbench.cpp | 2 - .../verilog/verilog_include_netlists.cpp | 106 ++++++++++++++++++ .../verilog/verilog_include_netlists.h | 8 ++ .../fpga_x2p/verilog/verilog_writer_utils.cpp | 2 - 7 files changed, 148 insertions(+), 4 deletions(-) create mode 100644 vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_include_netlists.cpp diff --git a/vpr7_x2p/libarchfpga/SRC/circuit_library_utils.cpp b/vpr7_x2p/libarchfpga/SRC/circuit_library_utils.cpp index cb7641b0a..7c3a24d94 100644 --- a/vpr7_x2p/libarchfpga/SRC/circuit_library_utils.cpp +++ b/vpr7_x2p/libarchfpga/SRC/circuit_library_utils.cpp @@ -240,3 +240,26 @@ std::vector find_circuit_library_global_ports(const CircuitLibrar return global_ports; } + +/******************************************************************** + * A generic function to find all the unique user-defined + * Verilog netlists in a circuit library + * Netlists with same names will be considered as one + *******************************************************************/ +std::vector find_circuit_library_unique_verilog_netlists(const CircuitLibrary& circuit_lib) { + std::vector netlists; + + for (const CircuitModelId& model : circuit_lib.models()) { + /* Skip empty netlist names */ + if (true == circuit_lib.model_verilog_netlist(model).empty()) { + continue; + } + /* See if the netlist name is already in the list */ + std::vector::iterator it = std::find(netlists.begin(), netlists.end(), circuit_lib.model_verilog_netlist(model)); + if (it == netlists.end()) { + netlists.push_back(circuit_lib.model_verilog_netlist(model)); + } + } + + return netlists; +} diff --git a/vpr7_x2p/libarchfpga/SRC/circuit_library_utils.h b/vpr7_x2p/libarchfpga/SRC/circuit_library_utils.h index c0c8251c7..056777c61 100644 --- a/vpr7_x2p/libarchfpga/SRC/circuit_library_utils.h +++ b/vpr7_x2p/libarchfpga/SRC/circuit_library_utils.h @@ -29,4 +29,6 @@ size_t find_circuit_num_config_bits(const CircuitLibrary& circuit_lib, std::vector find_circuit_library_global_ports(const CircuitLibrary& circuit_lib); +std::vector find_circuit_library_unique_verilog_netlists(const CircuitLibrary& circuit_lib); + #endif diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_api.c b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_api.c index eb6eadcca..6716cb1e4 100644 --- a/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_api.c +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_api.c @@ -505,9 +505,18 @@ void vpr_fpga_verilog(ModuleManager& module_manager, sram_verilog_orgz_info->type); } + /* TODO: this is an old function, to be shadowed */ + /* write_include_netlists(src_dir_path, chomped_circuit_name, *(Arch.spice) ); + */ + + /* TODO: new function: to be tested */ + print_include_netlists(std::string(src_dir_path), + std::string(chomped_circuit_name), + std::string(vpr_setup.FPGA_SPICE_Opts.SynVerilogOpts.reference_verilog_benchmark_file), + Arch.spice->circuit_lib); vpr_printf(TIO_MESSAGE_INFO, "Outputted %lu Verilog modules in total.\n", module_manager.num_modules()); diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_formal_random_top_testbench.cpp b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_formal_random_top_testbench.cpp index 26b86d7a1..b52d41d43 100644 --- a/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_formal_random_top_testbench.cpp +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_formal_random_top_testbench.cpp @@ -204,8 +204,6 @@ void print_verilog_random_top_testbench(const std::string& circuit_name, print_verilog_include_netlist(fp, std::string(verilog_dir + std::string(defines_verilog_simulation_file_name))); - print_verilog_include_netlist(fp, std::string(fpga_verilog_opts.reference_verilog_benchmark_file)); - /* Preparation: find all the clock ports */ std::vector clock_port_names = find_benchmark_clock_port_name(L_logical_blocks); diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_include_netlists.cpp b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_include_netlists.cpp new file mode 100644 index 000000000..814c97705 --- /dev/null +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_include_netlists.cpp @@ -0,0 +1,106 @@ +/******************************************************************** + * 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 + +#include "vtr_assert.h" + +#include "circuit_library_utils.h" + +#include "fpga_x2p_utils.h" +#include "fpga_x2p_naming.h" + +#include "verilog_writer_utils.h" +#include "verilog_include_netlists.h" + +/******************************************************************** + * 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_handler(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(); +} diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_include_netlists.h b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_include_netlists.h index 85659c56a..e0a92a2de 100644 --- a/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_include_netlists.h +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_include_netlists.h @@ -1,6 +1,14 @@ #ifndef VERILOG_INCLUDE_NETLISTS_H #define VERILOG_INCLUDE_NETLISTS_H +#include +#include "circuit_library.h" + +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 write_include_netlists (char* src_dir_formatted, char* chomped_circuit_name, t_spice spice); diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_writer_utils.cpp b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_writer_utils.cpp index 20f7c6dd0..e210a68e0 100644 --- a/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_writer_utils.cpp +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_writer_utils.cpp @@ -52,9 +52,7 @@ void print_verilog_include_netlist(std::fstream& fp, const std::string& netlist_name) { check_file_handler(fp); - fp << "//------ Include external netlist: " << netlist_name << " -----" << std::endl; fp << "`include \"" << netlist_name << "\"" << std::endl; - fp << "//------ End include external netlist: " << netlist_name << " -----" << std::endl; } /************************************************