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_compress_routing(openfpga_ctx.flow_manager().compress_routing());
fpga_fabric_spice(openfpga_ctx.module_graph(),
openfpga_ctx.mutable_spice_netlists(),
options);
int status = CMD_EXEC_SUCCESS;
status = fpga_fabric_spice(openfpga_ctx.module_graph(),
openfpga_ctx.mutable_spice_netlists(),
openfpga_ctx.arch().tech_lib,
options);
/* TODO: should identify the error code from internal function execution */
return CMD_EXEC_SUCCESS;
return status;
}
} /* end namespace openfpga */

View File

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

View File

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

View File

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

View File

@ -5,11 +5,15 @@
* logic gates etc.
***********************************************/
#include <fstream>
#include <iomanip>
/* Headers from vtrutil library */
#include "vtr_assert.h"
#include "vtr_log.h"
/* Headers from openfpgashell library */
#include "command_exit_codes.h"
/* Headers from openfpgautil library */
#include "openfpga_digest.h"
@ -19,12 +23,56 @@
/* begin 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
***********************************************/
void print_spice_transistor_wrapper(NetlistManager& netlist_manager,
const std::string& submodule_dir) {
std::string spice_fname = submodule_dir + std::string(ESSENTIALS_SPICE_FILE_NAME);
int print_spice_transistor_wrapper(NetlistManager& netlist_manager,
const TechnologyLibrary& tech_lib,
const std::string& submodule_dir) {
std::string spice_fname = submodule_dir + std::string(TRANSISTORS_SPICE_FILE_NAME);
std::fstream fp;
@ -37,6 +85,18 @@ void print_spice_transistor_wrapper(NetlistManager& netlist_manager,
VTR_LOG("Generating SPICE netlist '%s' for transistor wrappers...",
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*/
fp.close();
@ -46,6 +106,8 @@ void print_spice_transistor_wrapper(NetlistManager& netlist_manager,
netlist_manager.set_netlist_type(nlist_id, NetlistManager::SUBMODULE_NETLIST);
VTR_LOG("Done\n");
return CMD_EXEC_SUCCESS;
}
} /* end namespace openfpga */

View File

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

View File

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

View File

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