add spice transistor wrapper writer

This commit is contained in:
tangxifan 2020-07-05 14:50:29 -06:00
parent b38ee0e8be
commit 462fc0d04e
8 changed files with 117 additions and 24 deletions

View File

@ -36,12 +36,13 @@ int write_fabric_spice(OpenfpgaContext& openfpga_ctx,
options.set_verbose_output(cmd_context.option_enable(cmd, opt_verbose)); options.set_verbose_output(cmd_context.option_enable(cmd, opt_verbose));
options.set_compress_routing(openfpga_ctx.flow_manager().compress_routing()); options.set_compress_routing(openfpga_ctx.flow_manager().compress_routing());
fpga_fabric_spice(openfpga_ctx.module_graph(), int status = CMD_EXEC_SUCCESS;
status = fpga_fabric_spice(openfpga_ctx.module_graph(),
openfpga_ctx.mutable_spice_netlists(), openfpga_ctx.mutable_spice_netlists(),
openfpga_ctx.arch().tech_lib,
options); options);
/* TODO: should identify the error code from internal function execution */ return status;
return CMD_EXEC_SUCCESS;
} }
} /* end namespace openfpga */ } /* end namespace openfpga */

View File

@ -7,6 +7,9 @@
#include "vtr_assert.h" #include "vtr_assert.h"
#include "vtr_time.h" #include "vtr_time.h"
/* Headers from openfpgashell library */
#include "command_exit_codes.h"
/* Headers from openfpgautil library */ /* Headers from openfpgautil library */
#include "openfpga_digest.h" #include "openfpga_digest.h"
#include "openfpga_reserved_words.h" #include "openfpga_reserved_words.h"
@ -34,8 +37,9 @@ namespace openfpga {
* It is about the fabric itself, independent from any implementation * It is about the fabric itself, independent from any implementation
* All the testbench generation should be in the function fpga_testbench_spice() * All the testbench generation should be in the function fpga_testbench_spice()
********************************************************************/ ********************************************************************/
void fpga_fabric_spice(const ModuleManager &module_manager, int fpga_fabric_spice(const ModuleManager& module_manager,
NetlistManager& netlist_manager, NetlistManager& netlist_manager,
const TechnologyLibrary& tech_lib,
const FabricSpiceOption& options) { const FabricSpiceOption& options) {
vtr::ScopedStartFinishTimer timer("Write SPICE netlists for FPGA fabric\n"); vtr::ScopedStartFinishTimer timer("Write SPICE netlists for FPGA fabric\n");
@ -64,13 +68,22 @@ void fpga_fabric_spice(const ModuleManager &module_manager,
* the module manager. * the module manager.
* Without the modules in the module manager, core logic generation is not possible!!! * Without the modules in the module manager, core logic generation is not possible!!!
*/ */
print_spice_submodule(netlist_manager, int status = CMD_EXEC_SUCCESS;
status = print_spice_submodule(netlist_manager,
tech_lib,
submodule_dir_path); submodule_dir_path);
if (CMD_EXEC_SUCCESS != status) {
return status;
}
/* Given a brief stats on how many Spice modules have been written to files */ /* Given a brief stats on how many Spice modules have been written to files */
VTR_LOGV(options.verbose_output(), VTR_LOGV(options.verbose_output(),
"Written %lu SPICE modules in total\n", "Written %lu SPICE modules in total\n",
module_manager.num_modules()); module_manager.num_modules());
return CMD_EXEC_SUCCESS;
} }
} /* end namespace openfpga */ } /* end namespace openfpga */

View File

@ -9,6 +9,7 @@
#include <vector> #include <vector>
#include "netlist_manager.h" #include "netlist_manager.h"
#include "module_manager.h" #include "module_manager.h"
#include "technology_library.h"
#include "fabric_spice_options.h" #include "fabric_spice_options.h"
/******************************************************************** /********************************************************************
@ -18,8 +19,9 @@
/* begin namespace openfpga */ /* begin namespace openfpga */
namespace openfpga { namespace openfpga {
void fpga_fabric_spice(const ModuleManager& module_manager, int fpga_fabric_spice(const ModuleManager& module_manager,
NetlistManager& netlist_manager, NetlistManager& netlist_manager,
const TechnologyLibrary& tech_lib,
const FabricSpiceOption& options); const FabricSpiceOption& options);
} /* end namespace openfpga */ } /* end namespace openfpga */

View File

@ -5,6 +5,8 @@
constexpr char* SPICE_NETLIST_FILE_POSTFIX = ".sp"; constexpr char* SPICE_NETLIST_FILE_POSTFIX = ".sp";
constexpr char* TRANSISTOR_WRAPPER_POSTFIX = "_wrapper";
constexpr char* TRANSISTORS_SPICE_FILE_NAME = "transistor.sp"; constexpr char* TRANSISTORS_SPICE_FILE_NAME = "transistor.sp";
constexpr char* ESSENTIALS_SPICE_FILE_NAME = "inv_buf_passgate.sp"; constexpr char* ESSENTIALS_SPICE_FILE_NAME = "inv_buf_passgate.sp";

View File

@ -5,11 +5,15 @@
* logic gates etc. * logic gates etc.
***********************************************/ ***********************************************/
#include <fstream> #include <fstream>
#include <iomanip>
/* Headers from vtrutil library */ /* Headers from vtrutil library */
#include "vtr_assert.h" #include "vtr_assert.h"
#include "vtr_log.h" #include "vtr_log.h"
/* Headers from openfpgashell library */
#include "command_exit_codes.h"
/* Headers from openfpgautil library */ /* Headers from openfpgautil library */
#include "openfpga_digest.h" #include "openfpga_digest.h"
@ -19,12 +23,56 @@
/* begin namespace openfpga */ /* begin namespace openfpga */
namespace openfpga { namespace openfpga {
/************************************************
* Print a SPICE model wrapper for a transistor model
***********************************************/
static
int print_spice_transistor_model_wrapper(std::fstream& fp,
const TechnologyLibrary& tech_lib,
const TechnologyModelId& model) {
if (false == valid_file_stream(fp)) {
return CMD_EXEC_FATAL_ERROR;
}
/* Transistor model followed a fixed port mapping
* [X|M]<MODEL_CARD_NAME> <DRAIN> <GATE> <SOURCE> <BULK>
* which is a standard in SPICE modeling
* We will output the pmos and nmos transistors wrappers
* which are defined in this model
*/
for (int itype = TECH_LIB_TRANSISTOR_PMOS;
itype < NUM_TECH_LIB_TRANSISTOR_TYPES;
++itype) {
const e_tech_lib_transistor_type& trans_type = static_cast<e_tech_lib_transistor_type>(itype);
fp << ".subckt ";
fp << tech_lib.transistor_model_name(model, trans_type) << TRANSISTOR_WRAPPER_POSTFIX;
fp << " drain gate source bulk";
fp << " L=" << std::setprecision(10) << tech_lib.transistor_model_chan_length(model, trans_type);
fp << " W=" << std::setprecision(10) << tech_lib.transistor_model_min_width(model, trans_type);
fp << "\n";
fp << tech_lib.model_ref(model);
fp << "1";
fp << " drain gate source bulk";
fp << " " << tech_lib.transistor_model_name(model, trans_type);
fp << " L=L W=W";
fp << "\n";
fp << ".ends";
fp << "\n";
}
return CMD_EXEC_SUCCESS;
}
/************************************************ /************************************************
* Generate the SPICE netlist for transistors * Generate the SPICE netlist for transistors
***********************************************/ ***********************************************/
void print_spice_transistor_wrapper(NetlistManager& netlist_manager, int print_spice_transistor_wrapper(NetlistManager& netlist_manager,
const TechnologyLibrary& tech_lib,
const std::string& submodule_dir) { const std::string& submodule_dir) {
std::string spice_fname = submodule_dir + std::string(ESSENTIALS_SPICE_FILE_NAME); std::string spice_fname = submodule_dir + std::string(TRANSISTORS_SPICE_FILE_NAME);
std::fstream fp; std::fstream fp;
@ -37,6 +85,18 @@ void print_spice_transistor_wrapper(NetlistManager& netlist_manager,
VTR_LOG("Generating SPICE netlist '%s' for transistor wrappers...", VTR_LOG("Generating SPICE netlist '%s' for transistor wrappers...",
spice_fname.c_str()); spice_fname.c_str());
/* Iterate over the transistor models */
for (const TechnologyModelId& model : tech_lib.models()) {
/* Focus on transistor model */
if (TECH_LIB_MODEL_TRANSISTOR != tech_lib.model_type(model)) {
continue;
}
/* Write a wrapper for the transistor model */
if (CMD_EXEC_SUCCESS == print_spice_transistor_model_wrapper(fp, tech_lib, model)) {
return CMD_EXEC_FATAL_ERROR;
}
}
/* Close file handler*/ /* Close file handler*/
fp.close(); fp.close();
@ -46,6 +106,8 @@ void print_spice_transistor_wrapper(NetlistManager& netlist_manager,
netlist_manager.set_netlist_type(nlist_id, NetlistManager::SUBMODULE_NETLIST); netlist_manager.set_netlist_type(nlist_id, NetlistManager::SUBMODULE_NETLIST);
VTR_LOG("Done\n"); VTR_LOG("Done\n");
return CMD_EXEC_SUCCESS;
} }
} /* end namespace openfpga */ } /* end namespace openfpga */

View File

@ -6,6 +6,7 @@
*******************************************************************/ *******************************************************************/
#include <string> #include <string>
#include "netlist_manager.h" #include "netlist_manager.h"
#include "technology_library.h"
/******************************************************************** /********************************************************************
* Function declaration * Function declaration
@ -14,7 +15,8 @@
/* begin namespace openfpga */ /* begin namespace openfpga */
namespace openfpga { namespace openfpga {
void print_spice_transistor_wrapper(NetlistManager& netlist_manager, int print_spice_transistor_wrapper(NetlistManager& netlist_manager,
const TechnologyLibrary& tech_lib,
const std::string& submodule_dir); const std::string& submodule_dir);
} /* end namespace openfpga */ } /* end namespace openfpga */

View File

@ -7,6 +7,9 @@
#include "vtr_assert.h" #include "vtr_assert.h"
#include "vtr_log.h" #include "vtr_log.h"
/* Headers from openfpgashell library */
#include "command_exit_codes.h"
#include "spice_essential_gates.h" #include "spice_essential_gates.h"
#include "spice_constants.h" #include "spice_constants.h"
@ -24,11 +27,17 @@ namespace openfpga {
* 5. TODO: Wires * 5. TODO: Wires
* 6. TODO: Configuration memory blocks * 6. TODO: Configuration memory blocks
********************************************************************/ ********************************************************************/
void print_spice_submodule(NetlistManager& netlist_manager, int print_spice_submodule(NetlistManager& netlist_manager,
const TechnologyLibrary& tech_lib,
const std::string& submodule_dir) { const std::string& submodule_dir) {
print_spice_transistor_wrapper(netlist_manager, int status = CMD_EXEC_SUCCESS;
status = print_spice_transistor_wrapper(netlist_manager,
tech_lib,
submodule_dir); submodule_dir);
return status;
} }
} /* end namespace openfpga */ } /* end namespace openfpga */

View File

@ -5,6 +5,7 @@
* Include header files that are required by function declaration * Include header files that are required by function declaration
*******************************************************************/ *******************************************************************/
#include "netlist_manager.h" #include "netlist_manager.h"
#include "technology_library.h"
/******************************************************************** /********************************************************************
* Function declaration * Function declaration
@ -13,7 +14,8 @@
/* begin namespace openfpga */ /* begin namespace openfpga */
namespace openfpga { namespace openfpga {
void print_spice_submodule(NetlistManager& netlist_manager, int print_spice_submodule(NetlistManager& netlist_manager,
const TechnologyLibrary& tech_lib,
const std::string& submodule_dir); const std::string& submodule_dir);
} /* end namespace openfpga */ } /* end namespace openfpga */