From 222bc86cbfaa00bb5ad54df6c2f28008b58f0b12 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Sun, 20 Sep 2020 12:53:28 -0600 Subject: [PATCH] [FPGA-SPICE] Add auxiliary SPICE netlist writer --- openfpga/src/fpga_spice/spice_api.cpp | 9 +- .../fpga_spice/spice_auxiliary_netlists.cpp | 86 +++++++++++++++++++ .../src/fpga_spice/spice_auxiliary_netlists.h | 24 ++++++ openfpga/src/fpga_spice/spice_constants.h | 1 + openfpga/src/utils/circuit_library_utils.cpp | 23 +++++ openfpga/src/utils/circuit_library_utils.h | 2 + 6 files changed, 140 insertions(+), 5 deletions(-) create mode 100644 openfpga/src/fpga_spice/spice_auxiliary_netlists.cpp create mode 100644 openfpga/src/fpga_spice/spice_auxiliary_netlists.h diff --git a/openfpga/src/fpga_spice/spice_api.cpp b/openfpga/src/fpga_spice/spice_api.cpp index a06a3fb8e..22c433bd6 100644 --- a/openfpga/src/fpga_spice/spice_api.cpp +++ b/openfpga/src/fpga_spice/spice_api.cpp @@ -19,6 +19,7 @@ #include "spice_routing.h" #include "spice_grid.h" #include "spice_top_module.h" +#include "spice_auxiliary_netlists.h" /* Header file for this source file */ #include "spice_api.h" @@ -114,11 +115,9 @@ int fpga_fabric_spice(const ModuleManager& module_manager, src_dir_path); /* Generate an netlist including all the fabric-related netlists */ - /* - print_fabric_include_netlist(const_cast(netlist_manager), - src_dir_path, - circuit_lib); - */ + print_spice_fabric_include_netlist(const_cast(netlist_manager), + src_dir_path, + openfpga_arch.circuit_lib); /* Given a brief stats on how many Spice modules have been written to files */ VTR_LOGV(options.verbose_output(), diff --git a/openfpga/src/fpga_spice/spice_auxiliary_netlists.cpp b/openfpga/src/fpga_spice/spice_auxiliary_netlists.cpp new file mode 100644 index 000000000..f76464898 --- /dev/null +++ b/openfpga/src/fpga_spice/spice_auxiliary_netlists.cpp @@ -0,0 +1,86 @@ +/******************************************************************** + * This file includes functions that are used to generate SPICE files + * or code blocks, with a focus on + * `include user-defined or auto-generated netlists in SPICE format + *******************************************************************/ +#include + +/* 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 "spice_constants.h" +#include "spice_writer_utils.h" +#include "spice_auxiliary_netlists.h" + +/* begin namespace openfpga */ +namespace openfpga { + +/******************************************************************** + * Local constant variables + *******************************************************************/ + +/******************************************************************** + * Print a file that includes all the fabric netlists + * that have been generated and user-defined. + * This does NOT include any testbenches! + * Some netlists are open to compile under specific preprocessing flags + *******************************************************************/ +void print_spice_fabric_include_netlist(const NetlistManager& netlist_manager, + const std::string& src_dir, + const CircuitLibrary& circuit_lib) { + std::string spice_fname = src_dir + std::string(FABRIC_INCLUDE_SPICE_NETLIST_FILE_NAME); + + /* Create the file stream */ + std::fstream fp; + fp.open(spice_fname, std::fstream::out | std::fstream::trunc); + + /* Validate the file stream */ + check_file_stream(spice_fname.c_str(), fp); + + /* Print the title */ + print_spice_file_header(fp, std::string("Fabric Netlist Summary")); + + /* Include all the user-defined netlists */ + print_spice_comment(fp, std::string("Include user-defined netlists")); + for (const std::string& user_defined_netlist : find_circuit_library_unique_spice_netlists(circuit_lib)) { + print_spice_include_netlist(fp, user_defined_netlist); + } + + /* Include all the primitive modules */ + print_spice_comment(fp, std::string("Include primitive module netlists")); + for (const NetlistId& nlist_id : netlist_manager.netlists_by_type(NetlistManager::SUBMODULE_NETLIST)) { + print_spice_include_netlist(fp, netlist_manager.netlist_name(nlist_id)); + } + fp << std::endl; + + /* Include all the CLB, heterogeneous block modules */ + print_spice_comment(fp, std::string("Include logic block netlists")); + for (const NetlistId& nlist_id : netlist_manager.netlists_by_type(NetlistManager::LOGIC_BLOCK_NETLIST)) { + print_spice_include_netlist(fp, netlist_manager.netlist_name(nlist_id)); + } + fp << std::endl; + + /* Include all the routing architecture modules */ + print_spice_comment(fp, std::string("Include routing module netlists")); + for (const NetlistId& nlist_id : netlist_manager.netlists_by_type(NetlistManager::ROUTING_MODULE_NETLIST)) { + print_spice_include_netlist(fp, netlist_manager.netlist_name(nlist_id)); + } + fp << std::endl; + + /* Include FPGA top module */ + print_spice_comment(fp, std::string("Include fabric top-level netlists")); + for (const NetlistId& nlist_id : netlist_manager.netlists_by_type(NetlistManager::TOP_MODULE_NETLIST)) { + print_spice_include_netlist(fp, netlist_manager.netlist_name(nlist_id)); + } + fp << std::endl; + + /* Close the file stream */ + fp.close(); +} + +} /* end namespace openfpga */ diff --git a/openfpga/src/fpga_spice/spice_auxiliary_netlists.h b/openfpga/src/fpga_spice/spice_auxiliary_netlists.h new file mode 100644 index 000000000..aa04a54b9 --- /dev/null +++ b/openfpga/src/fpga_spice/spice_auxiliary_netlists.h @@ -0,0 +1,24 @@ +#ifndef SPICE_AUXILIARY_NETLISTS_H +#define SPICE_AUXILIARY_NETLISTS_H + +/******************************************************************** + * Include header files that are required by function declaration + *******************************************************************/ +#include +#include "circuit_library.h" +#include "netlist_manager.h" + +/******************************************************************** + * Function declaration + *******************************************************************/ + +/* begin namespace openfpga */ +namespace openfpga { + +void print_spice_fabric_include_netlist(const NetlistManager& netlist_manager, + const std::string& src_dir, + const CircuitLibrary& circuit_lib); + +} /* end namespace openfpga */ + +#endif diff --git a/openfpga/src/fpga_spice/spice_constants.h b/openfpga/src/fpga_spice/spice_constants.h index 97b1733c2..68026a0be 100644 --- a/openfpga/src/fpga_spice/spice_constants.h +++ b/openfpga/src/fpga_spice/spice_constants.h @@ -12,6 +12,7 @@ constexpr char* SUPPLY_WRAPPER_SPICE_FILE_NAME = "supply_wrapper.sp"; constexpr char* MUXES_SPICE_FILE_NAME = "muxes.sp"; constexpr char* LUTS_SPICE_FILE_NAME = "luts.sp"; constexpr char* MEMORIES_SPICE_FILE_NAME = "memories.sp"; +constexpr char* FABRIC_INCLUDE_SPICE_NETLIST_FILE_NAME = "fabric_netlists.sp"; constexpr char* SPICE_SUBCKT_VDD_PORT_NAME = "VDD"; constexpr char* SPICE_SUBCKT_GND_PORT_NAME = "VSS"; diff --git a/openfpga/src/utils/circuit_library_utils.cpp b/openfpga/src/utils/circuit_library_utils.cpp index cd59545ae..8fb5aa7bc 100644 --- a/openfpga/src/utils/circuit_library_utils.cpp +++ b/openfpga/src/utils/circuit_library_utils.cpp @@ -251,6 +251,29 @@ std::vector find_circuit_library_unique_verilog_netlists(const Circ return netlists; } +/******************************************************************** + * 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_spice_netlists(const CircuitLibrary& circuit_lib) { + std::vector netlists; + + for (const CircuitModelId& model : circuit_lib.models()) { + /* Skip empty netlist names */ + if (true == circuit_lib.model_spice_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_spice_netlist(model)); + if (it == netlists.end()) { + netlists.push_back(circuit_lib.model_spice_netlist(model)); + } + } + + return netlists; +} + /************************************************************************ * Advanced check if the circuit model of configurable memory * satisfy the needs of configuration protocol diff --git a/openfpga/src/utils/circuit_library_utils.h b/openfpga/src/utils/circuit_library_utils.h index 584871868..dc7fd0e34 100644 --- a/openfpga/src/utils/circuit_library_utils.h +++ b/openfpga/src/utils/circuit_library_utils.h @@ -39,6 +39,8 @@ std::vector find_circuit_library_global_ports(const CircuitLibrar std::vector find_circuit_library_unique_verilog_netlists(const CircuitLibrary& circuit_lib); +std::vector find_circuit_library_unique_spice_netlists(const CircuitLibrary& circuit_lib); + bool check_configurable_memory_circuit_model(const e_config_protocol_type& config_protocol_type, const CircuitLibrary& circuit_lib, const CircuitModelId& config_mem_circuit_model);