[FPGA-SPICE] Add auxiliary SPICE netlist writer

This commit is contained in:
tangxifan 2020-09-20 12:53:28 -06:00
parent 06c0073a3e
commit 222bc86cbf
6 changed files with 140 additions and 5 deletions

View File

@ -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<const NetlistManager &>(netlist_manager),
print_spice_fabric_include_netlist(const_cast<const NetlistManager &>(netlist_manager),
src_dir_path,
circuit_lib);
*/
openfpga_arch.circuit_lib);
/* Given a brief stats on how many Spice modules have been written to files */
VTR_LOGV(options.verbose_output(),

View File

@ -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 <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 "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 */

View File

@ -0,0 +1,24 @@
#ifndef SPICE_AUXILIARY_NETLISTS_H
#define SPICE_AUXILIARY_NETLISTS_H
/********************************************************************
* Include header files that are required by function declaration
*******************************************************************/
#include <string>
#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

View File

@ -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";

View File

@ -251,6 +251,29 @@ std::vector<std::string> 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<std::string> find_circuit_library_unique_spice_netlists(const CircuitLibrary& circuit_lib) {
std::vector<std::string> 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<std::string>::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

View File

@ -39,6 +39,8 @@ std::vector<CircuitPortId> find_circuit_library_global_ports(const CircuitLibrar
std::vector<std::string> find_circuit_library_unique_verilog_netlists(const CircuitLibrary& circuit_lib);
std::vector<std::string> 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);