[FPGA-SPICE] Add supply voltage generator
This commit is contained in:
parent
15df9b3893
commit
c7e3d97d1b
|
@ -8,6 +8,7 @@ constexpr char* SPICE_NETLIST_FILE_POSTFIX = ".sp";
|
||||||
constexpr char* TRANSISTOR_WRAPPER_POSTFIX = "_wrapper";
|
constexpr char* TRANSISTOR_WRAPPER_POSTFIX = "_wrapper";
|
||||||
|
|
||||||
constexpr char* TRANSISTORS_SPICE_FILE_NAME = "transistor.sp";
|
constexpr char* TRANSISTORS_SPICE_FILE_NAME = "transistor.sp";
|
||||||
|
constexpr char* SUPPLY_WRAPPER_SPICE_FILE_NAME = "supply_wrapper.sp";
|
||||||
|
|
||||||
constexpr char* SPICE_SUBCKT_VDD_PORT_NAME = "VDD";
|
constexpr char* SPICE_SUBCKT_VDD_PORT_NAME = "VDD";
|
||||||
constexpr char* SPICE_SUBCKT_GND_PORT_NAME = "VSS";
|
constexpr char* SPICE_SUBCKT_GND_PORT_NAME = "VSS";
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
/* Headers from openfpgautil library */
|
/* Headers from openfpgautil library */
|
||||||
#include "openfpga_digest.h"
|
#include "openfpga_digest.h"
|
||||||
|
|
||||||
|
#include "openfpga_naming.h"
|
||||||
#include "circuit_library_utils.h"
|
#include "circuit_library_utils.h"
|
||||||
|
|
||||||
#include "spice_constants.h"
|
#include "spice_constants.h"
|
||||||
|
@ -31,6 +32,92 @@
|
||||||
/* begin namespace openfpga */
|
/* begin namespace openfpga */
|
||||||
namespace openfpga {
|
namespace openfpga {
|
||||||
|
|
||||||
|
/************************************************
|
||||||
|
* Generate the SPICE netlist for a constant generator,
|
||||||
|
* i.e., either VDD or GND
|
||||||
|
***********************************************/
|
||||||
|
static
|
||||||
|
void print_spice_supply_wrapper_subckt(const ModuleManager& module_manager,
|
||||||
|
std::fstream& fp,
|
||||||
|
const size_t& const_value) {
|
||||||
|
/* Find the module in module manager */
|
||||||
|
std::string module_name = generate_const_value_module_name(const_value);
|
||||||
|
ModuleId const_val_module = module_manager.find_module(module_name);
|
||||||
|
VTR_ASSERT(true == module_manager.valid_module_id(const_val_module));
|
||||||
|
|
||||||
|
/* Ensure a valid file handler*/
|
||||||
|
VTR_ASSERT(true == valid_file_stream(fp));
|
||||||
|
|
||||||
|
/* dump module definition + ports */
|
||||||
|
print_spice_subckt_definition(fp, module_manager, const_val_module);
|
||||||
|
/* Finish dumping ports */
|
||||||
|
|
||||||
|
/* Find the only output*/
|
||||||
|
for (const ModulePortId& module_port_id : module_manager.module_ports(const_val_module)) {
|
||||||
|
BasicPort module_port = module_manager.module_port(const_val_module, module_port_id);
|
||||||
|
for (const auto& pin : module_port.pins()) {
|
||||||
|
BasicPort spice_pin(module_port.get_name(), pin, pin);
|
||||||
|
std::string const_pin_name = std::string(SPICE_SUBCKT_VDD_PORT_NAME);
|
||||||
|
if (0 == const_value) {
|
||||||
|
const_pin_name = std::string(SPICE_SUBCKT_GND_PORT_NAME);
|
||||||
|
} else {
|
||||||
|
VTR_ASSERT(1 == const_value);
|
||||||
|
}
|
||||||
|
|
||||||
|
print_spice_short_connection(fp,
|
||||||
|
generate_spice_port(spice_pin, true),
|
||||||
|
const_pin_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Put an end to the SPICE subcircuit */
|
||||||
|
print_spice_subckt_end(fp, module_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/********************************************************************
|
||||||
|
* Create supply voltage wrappers
|
||||||
|
* The wrappers are used for constant inputs of routing multiplexers
|
||||||
|
*
|
||||||
|
*******************************************************************/
|
||||||
|
int print_spice_supply_wrappers(NetlistManager& netlist_manager,
|
||||||
|
const ModuleManager& module_manager,
|
||||||
|
const std::string& submodule_dir) {
|
||||||
|
int status = CMD_EXEC_SUCCESS;
|
||||||
|
|
||||||
|
/* Create file stream */
|
||||||
|
std::string spice_fname = submodule_dir + std::string(SUPPLY_WRAPPER_SPICE_FILE_NAME);
|
||||||
|
|
||||||
|
std::fstream fp;
|
||||||
|
|
||||||
|
/* Create the file stream */
|
||||||
|
fp.open(spice_fname, std::fstream::out | std::fstream::trunc);
|
||||||
|
/* Check if the file stream if valid or not */
|
||||||
|
check_file_stream(spice_fname.c_str(), fp);
|
||||||
|
|
||||||
|
/* Create file */
|
||||||
|
VTR_LOG("Generating SPICE netlist '%s' for voltage supply wrappers...",
|
||||||
|
spice_fname.c_str());
|
||||||
|
|
||||||
|
print_spice_file_header(fp, std::string("Voltage Supply Wrappers"));
|
||||||
|
|
||||||
|
/* VDD */
|
||||||
|
print_spice_supply_wrapper_subckt(module_manager, fp, 0);
|
||||||
|
/* GND */
|
||||||
|
print_spice_supply_wrapper_subckt(module_manager, fp, 1);
|
||||||
|
|
||||||
|
/* Close file handler*/
|
||||||
|
fp.close();
|
||||||
|
|
||||||
|
/* Add fname to the netlist name list */
|
||||||
|
NetlistId nlist_id = netlist_manager.add_netlist(spice_fname);
|
||||||
|
VTR_ASSERT(NetlistId::INVALID() != nlist_id);
|
||||||
|
netlist_manager.set_netlist_type(nlist_id, NetlistManager::SUBMODULE_NETLIST);
|
||||||
|
|
||||||
|
VTR_LOG("Done\n");
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
/********************************************************************
|
/********************************************************************
|
||||||
* Generate the SPICE netlist for essential gates:
|
* Generate the SPICE netlist for essential gates:
|
||||||
* - inverters and their templates
|
* - inverters and their templates
|
||||||
|
|
|
@ -18,6 +18,10 @@
|
||||||
/* begin namespace openfpga */
|
/* begin namespace openfpga */
|
||||||
namespace openfpga {
|
namespace openfpga {
|
||||||
|
|
||||||
|
int print_spice_supply_wrappers(NetlistManager& netlist_manager,
|
||||||
|
const ModuleManager& module_manager,
|
||||||
|
const std::string& submodule_dir);
|
||||||
|
|
||||||
int print_spice_essential_gates(NetlistManager& netlist_manager,
|
int print_spice_essential_gates(NetlistManager& netlist_manager,
|
||||||
const ModuleManager& module_manager,
|
const ModuleManager& module_manager,
|
||||||
const CircuitLibrary& circuit_lib,
|
const CircuitLibrary& circuit_lib,
|
||||||
|
|
|
@ -25,7 +25,7 @@ namespace openfpga {
|
||||||
* 2. Logic gates: AND/OR, inverter, buffer and transmission-gate/pass-transistor
|
* 2. Logic gates: AND/OR, inverter, buffer and transmission-gate/pass-transistor
|
||||||
* 3. TODO: Routing multiplexers
|
* 3. TODO: Routing multiplexers
|
||||||
* 4. TODO: Local encoders for routing multiplexers
|
* 4. TODO: Local encoders for routing multiplexers
|
||||||
* 5. TODO: Wires
|
* 5. Wires
|
||||||
* 6. TODO: Configuration memory blocks
|
* 6. TODO: Configuration memory blocks
|
||||||
********************************************************************/
|
********************************************************************/
|
||||||
int print_spice_submodule(NetlistManager& netlist_manager,
|
int print_spice_submodule(NetlistManager& netlist_manager,
|
||||||
|
@ -35,10 +35,32 @@ int print_spice_submodule(NetlistManager& netlist_manager,
|
||||||
|
|
||||||
int status = CMD_EXEC_SUCCESS;
|
int status = CMD_EXEC_SUCCESS;
|
||||||
|
|
||||||
|
/* Transistor wrapper */
|
||||||
status = print_spice_transistor_wrapper(netlist_manager,
|
status = print_spice_transistor_wrapper(netlist_manager,
|
||||||
openfpga_arch.tech_lib,
|
openfpga_arch.tech_lib,
|
||||||
submodule_dir);
|
submodule_dir);
|
||||||
|
|
||||||
|
/* Error out if fatal errors have been reported */
|
||||||
|
if (CMD_EXEC_SUCCESS != status) {
|
||||||
|
return CMD_EXEC_FATAL_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Constant modules: VDD and GND */
|
||||||
|
status = print_spice_supply_wrappers(netlist_manager,
|
||||||
|
module_manager,
|
||||||
|
submodule_dir);
|
||||||
|
|
||||||
|
/* Error out if fatal errors have been reported */
|
||||||
|
if (CMD_EXEC_SUCCESS != status) {
|
||||||
|
return CMD_EXEC_FATAL_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Logic gates:
|
||||||
|
* - AND/OR,
|
||||||
|
* - inverter, buffer
|
||||||
|
* - transmission-gate/pass-transistor
|
||||||
|
* - wires
|
||||||
|
*/
|
||||||
status = print_spice_essential_gates(netlist_manager,
|
status = print_spice_essential_gates(netlist_manager,
|
||||||
module_manager,
|
module_manager,
|
||||||
openfpga_arch.circuit_lib,
|
openfpga_arch.circuit_lib,
|
||||||
|
@ -46,6 +68,25 @@ int print_spice_submodule(NetlistManager& netlist_manager,
|
||||||
openfpga_arch.circuit_tech_binding,
|
openfpga_arch.circuit_tech_binding,
|
||||||
submodule_dir);
|
submodule_dir);
|
||||||
|
|
||||||
|
/* Error out if fatal errors have been reported */
|
||||||
|
if (CMD_EXEC_SUCCESS != status) {
|
||||||
|
return CMD_EXEC_FATAL_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Routing multiplexers */
|
||||||
|
/*
|
||||||
|
status = print_spice_submodule_muxes(netlist_manager,
|
||||||
|
module_manager,
|
||||||
|
mux_lib,
|
||||||
|
openfpga_arch.circuit_lib,
|
||||||
|
submodule_dir);
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Error out if fatal errors have been reported */
|
||||||
|
if (CMD_EXEC_SUCCESS != status) {
|
||||||
|
return CMD_EXEC_FATAL_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue