add spice transistor wrapper writer
This commit is contained in:
parent
b38ee0e8be
commit
462fc0d04e
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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";
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
Loading…
Reference in New Issue