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_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 */
|
||||||
|
|
|
@ -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,9 +37,10 @@ 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 FabricSpiceOption &options) {
|
const TechnologyLibrary& tech_lib,
|
||||||
|
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 */
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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";
|
||||||
|
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
Loading…
Reference in New Issue