start transplanting FPGA-SPICE
This commit is contained in:
parent
1ad6e8292a
commit
81171a8f97
|
@ -67,6 +67,7 @@ class OpenfpgaContext : public Context {
|
|||
const openfpga::IoLocationMap& io_location_map() const { return io_location_map_; }
|
||||
const std::unordered_map<AtomNetId, t_net_power>& net_activity() const { return net_activity_; }
|
||||
const openfpga::NetlistManager& verilog_netlists() const { return verilog_netlists_; }
|
||||
const openfpga::NetlistManager& spice_netlists() const { return spice_netlists_; }
|
||||
public: /* Public mutators */
|
||||
openfpga::Arch& mutable_arch() { return arch_; }
|
||||
openfpga::SimulationSetting& mutable_simulation_setting() { return sim_setting_; }
|
||||
|
@ -86,6 +87,7 @@ class OpenfpgaContext : public Context {
|
|||
openfpga::IoLocationMap& mutable_io_location_map() { return io_location_map_; }
|
||||
std::unordered_map<AtomNetId, t_net_power>& mutable_net_activity() { return net_activity_; }
|
||||
openfpga::NetlistManager& mutable_verilog_netlists() { return verilog_netlists_; }
|
||||
openfpga::NetlistManager& mutable_spice_netlists() { return spice_netlists_; }
|
||||
private: /* Internal data */
|
||||
/* Data structure to store information from read_openfpga_arch library */
|
||||
openfpga::Arch arch_;
|
||||
|
@ -130,6 +132,7 @@ class OpenfpgaContext : public Context {
|
|||
* TODO: Each format should have an independent entry
|
||||
*/
|
||||
openfpga::NetlistManager verilog_netlists_;
|
||||
openfpga::NetlistManager spice_netlists_;
|
||||
|
||||
/* Net activities of users' implementation */
|
||||
std::unordered_map<AtomNetId, t_net_power> net_activity_;
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
/********************************************************************
|
||||
* This file includes functions to compress the hierachy of routing architecture
|
||||
*******************************************************************/
|
||||
/* Headers from vtrutil library */
|
||||
#include "vtr_time.h"
|
||||
#include "vtr_log.h"
|
||||
|
||||
/* Headers from openfpgashell library */
|
||||
#include "command_exit_codes.h"
|
||||
|
||||
#include "spice_api.h"
|
||||
#include "openfpga_spice.h"
|
||||
|
||||
/* Include global variables of VPR */
|
||||
#include "globals.h"
|
||||
|
||||
/* begin namespace openfpga */
|
||||
namespace openfpga {
|
||||
|
||||
/********************************************************************
|
||||
* A wrapper function to call the fabric SPICE generator of FPGA-SPICE
|
||||
*******************************************************************/
|
||||
int write_fabric_spice(OpenfpgaContext& openfpga_ctx,
|
||||
const Command& cmd, const CommandContext& cmd_context) {
|
||||
|
||||
CommandOptionId opt_output_dir = cmd.option("file");
|
||||
CommandOptionId opt_explicit_port_mapping = cmd.option("explicit_port_mapping");
|
||||
CommandOptionId opt_verbose = cmd.option("verbose");
|
||||
|
||||
/* This is an intermediate data structure which is designed to modularize the FPGA-SPICE
|
||||
* Keep it independent from any other outside data structures
|
||||
*/
|
||||
FabricSpiceOption options;
|
||||
options.set_output_directory(cmd_context.option_value(cmd, opt_output_dir));
|
||||
options.set_explicit_port_mapping(cmd_context.option_enable(cmd, opt_explicit_port_mapping));
|
||||
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);
|
||||
|
||||
/* TODO: should identify the error code from internal function execution */
|
||||
return CMD_EXEC_SUCCESS;
|
||||
}
|
||||
|
||||
} /* end namespace openfpga */
|
|
@ -0,0 +1,23 @@
|
|||
#ifndef OPENFPGA_SPICE_H
|
||||
#define OPENFPGA_SPICE_H
|
||||
|
||||
/********************************************************************
|
||||
* Include header files that are required by function declaration
|
||||
*******************************************************************/
|
||||
#include "command.h"
|
||||
#include "command_context.h"
|
||||
#include "openfpga_context.h"
|
||||
|
||||
/********************************************************************
|
||||
* Function declaration
|
||||
*******************************************************************/
|
||||
|
||||
/* begin namespace openfpga */
|
||||
namespace openfpga {
|
||||
|
||||
int write_fabric_spice(OpenfpgaContext& openfpga_ctx,
|
||||
const Command& cmd, const CommandContext& cmd_context);
|
||||
|
||||
} /* end namespace openfpga */
|
||||
|
||||
#endif
|
|
@ -0,0 +1,78 @@
|
|||
/********************************************************************
|
||||
* Add commands to the OpenFPGA shell interface,
|
||||
* in purpose of generate SPICE netlists modeling the full FPGA fabric
|
||||
* This is one of the core engine of openfpga, including:
|
||||
* - generate_fabric_spice : generate Verilog netlists about FPGA fabric
|
||||
* - TODO: generate_spice_top_testbench : generate SPICE testbenches for top-level module
|
||||
* - TODO: generate_spice_grid_testbench : generate SPICE testbenches for grids
|
||||
* - TODO: generate_spice_cb_testbench : generate SPICE testbenches for connection blocks
|
||||
* - TODO: generate_spice_sb_testbench : generate SPICE testbenches for switch blocks
|
||||
* - TODO: generate_spice_lut_testbench : generate SPICE testbenches for Look-Up Tables
|
||||
* - TODO: generate_spice_hard_logic_testbench : generate SPICE testbenches for all the hard logics
|
||||
* - TODO: generate_spice_local_routing_testbench : generate SPICE testbenches for local routing
|
||||
* - TODO: generate_spice_cb_routing_testbench : generate SPICE testbenches for routing circuit inside connection blocks
|
||||
* - TODO: generate_spice_sb_routing_testbench : generate SPICE testbenches for routing circuit inside switch blocks
|
||||
*******************************************************************/
|
||||
#include "openfpga_spice.h"
|
||||
#include "openfpga_spice_command.h"
|
||||
|
||||
/* begin namespace openfpga */
|
||||
namespace openfpga {
|
||||
|
||||
/********************************************************************
|
||||
* - Add a command to Shell environment: generate fabric Verilog
|
||||
* - Add associated options
|
||||
* - Add command dependency
|
||||
*******************************************************************/
|
||||
static
|
||||
ShellCommandId add_openfpga_write_fabric_spice_command(openfpga::Shell<OpenfpgaContext>& shell,
|
||||
const ShellCommandClassId& cmd_class_id,
|
||||
const std::vector<ShellCommandId>& dependent_cmds) {
|
||||
Command shell_cmd("write_fabric_spice");
|
||||
|
||||
/* Add an option '--file' in short '-f'*/
|
||||
CommandOptionId output_opt = shell_cmd.add_option("file", true, "Specify the output directory for SPICE netlists");
|
||||
shell_cmd.set_option_short_name(output_opt, "f");
|
||||
shell_cmd.set_option_require_value(output_opt, openfpga::OPT_STRING);
|
||||
|
||||
/* Add an option '--explicit_port_mapping' */
|
||||
shell_cmd.add_option("explicit_port_mapping", false, "Use explicit port mapping in Verilog netlists");
|
||||
|
||||
/* Add an option '--verbose' */
|
||||
shell_cmd.add_option("verbose", false, "Enable verbose output");
|
||||
|
||||
/* Add command 'write_fabric_spice' to the Shell */
|
||||
ShellCommandId shell_cmd_id = shell.add_command(shell_cmd, "generate SPICE netlists modeling full FPGA fabric");
|
||||
shell.set_command_class(shell_cmd_id, cmd_class_id);
|
||||
shell.set_command_execute_function(shell_cmd_id, write_fabric_spice);
|
||||
|
||||
/* Add command dependency to the Shell */
|
||||
shell.set_command_dependency(shell_cmd_id, dependent_cmds);
|
||||
|
||||
return shell_cmd_id;
|
||||
}
|
||||
|
||||
void add_openfpga_spice_commands(openfpga::Shell<OpenfpgaContext>& shell) {
|
||||
/* Get the unique id of 'build_fabric' command which is to be used in creating the dependency graph */
|
||||
const ShellCommandId& build_fabric_cmd_id = shell.command(std::string("build_fabric"));
|
||||
|
||||
/* Add a new class of commands */
|
||||
ShellCommandClassId openfpga_spice_cmd_class = shell.add_command_class("FPGA-SPICE");
|
||||
|
||||
/********************************
|
||||
* Command 'write_fabric_spice'
|
||||
*/
|
||||
/* The 'write_fabric_spice' command should NOT be executed before 'build_fabric' */
|
||||
std::vector<ShellCommandId> fabric_spice_dependent_cmds;
|
||||
fabric_spice_dependent_cmds.push_back(build_fabric_cmd_id);
|
||||
add_openfpga_write_fabric_spice_command(shell,
|
||||
openfpga_spice_cmd_class,
|
||||
fabric_spice_dependent_cmds);
|
||||
|
||||
/********************************
|
||||
* TODO: Command 'write_spice_top_testbench'
|
||||
*/
|
||||
/* The command 'write_spice_top_testbench' should NOT be executed before 'build_fabric' */
|
||||
}
|
||||
|
||||
} /* end namespace openfpga */
|
|
@ -0,0 +1,21 @@
|
|||
#ifndef OPENFPGA_SPICE_COMMAND_H
|
||||
#define OPENFPGA_SPICE_COMMAND_H
|
||||
|
||||
/********************************************************************
|
||||
* Include header files that are required by function declaration
|
||||
*******************************************************************/
|
||||
#include "shell.h"
|
||||
#include "openfpga_context.h"
|
||||
|
||||
/********************************************************************
|
||||
* Function declaration
|
||||
*******************************************************************/
|
||||
|
||||
/* begin namespace openfpga */
|
||||
namespace openfpga {
|
||||
|
||||
void add_openfpga_spice_commands(openfpga::Shell<OpenfpgaContext>& shell);
|
||||
|
||||
} /* end namespace openfpga */
|
||||
|
||||
#endif
|
|
@ -0,0 +1,59 @@
|
|||
/******************************************************************************
|
||||
* Memember functions for data structure FabricSpiceOption
|
||||
******************************************************************************/
|
||||
#include "vtr_assert.h"
|
||||
|
||||
#include "fabric_spice_options.h"
|
||||
|
||||
/* begin namespace openfpga */
|
||||
namespace openfpga {
|
||||
|
||||
/**************************************************
|
||||
* Public Constructors
|
||||
*************************************************/
|
||||
FabricSpiceOption::FabricSpiceOption() {
|
||||
output_directory_.clear();
|
||||
explicit_port_mapping_ = false;
|
||||
compress_routing_ = false;
|
||||
verbose_output_ = false;
|
||||
}
|
||||
|
||||
/**************************************************
|
||||
* Public Accessors
|
||||
*************************************************/
|
||||
std::string FabricSpiceOption::output_directory() const {
|
||||
return output_directory_;
|
||||
}
|
||||
|
||||
bool FabricSpiceOption::explicit_port_mapping() const {
|
||||
return explicit_port_mapping_;
|
||||
}
|
||||
|
||||
bool FabricSpiceOption::compress_routing() const {
|
||||
return compress_routing_;
|
||||
}
|
||||
|
||||
bool FabricSpiceOption::verbose_output() const {
|
||||
return verbose_output_;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Private Mutators
|
||||
******************************************************************************/
|
||||
void FabricSpiceOption::set_output_directory(const std::string& output_dir) {
|
||||
output_directory_ = output_dir;
|
||||
}
|
||||
|
||||
void FabricSpiceOption::set_explicit_port_mapping(const bool& enabled) {
|
||||
explicit_port_mapping_ = enabled;
|
||||
}
|
||||
|
||||
void FabricSpiceOption::set_compress_routing(const bool& enabled) {
|
||||
compress_routing_ = enabled;
|
||||
}
|
||||
|
||||
void FabricSpiceOption::set_verbose_output(const bool& enabled) {
|
||||
verbose_output_ = enabled;
|
||||
}
|
||||
|
||||
} /* end namespace openfpga */
|
|
@ -0,0 +1,38 @@
|
|||
#ifndef FABRIC_SPICE_OPTIONS_H
|
||||
#define FABRIC_SPICE_OPTIONS_H
|
||||
|
||||
/********************************************************************
|
||||
* Include header files required by the data structure definition
|
||||
*******************************************************************/
|
||||
#include <string>
|
||||
|
||||
/* Begin namespace openfpga */
|
||||
namespace openfpga {
|
||||
|
||||
/********************************************************************
|
||||
* Options for Fabric Spice generator
|
||||
*******************************************************************/
|
||||
class FabricSpiceOption {
|
||||
public: /* Public constructor */
|
||||
/* Set default options */
|
||||
FabricSpiceOption();
|
||||
public: /* Public accessors */
|
||||
std::string output_directory() const;
|
||||
bool explicit_port_mapping() const;
|
||||
bool compress_routing() const;
|
||||
bool verbose_output() const;
|
||||
public: /* Public mutators */
|
||||
void set_output_directory(const std::string& output_dir);
|
||||
void set_explicit_port_mapping(const bool& enabled);
|
||||
void set_compress_routing(const bool& enabled);
|
||||
void set_verbose_output(const bool& enabled);
|
||||
private: /* Internal Data */
|
||||
std::string output_directory_;
|
||||
bool explicit_port_mapping_;
|
||||
bool compress_routing_;
|
||||
bool verbose_output_;
|
||||
};
|
||||
|
||||
} /* End namespace openfpga*/
|
||||
|
||||
#endif
|
|
@ -0,0 +1,76 @@
|
|||
/********************************************************************
|
||||
* This file include top-level function of FPGA-SPICE
|
||||
********************************************************************/
|
||||
|
||||
/* Headers from vtrutil library */
|
||||
#include "vtr_log.h"
|
||||
#include "vtr_assert.h"
|
||||
#include "vtr_time.h"
|
||||
|
||||
/* Headers from openfpgautil library */
|
||||
#include "openfpga_digest.h"
|
||||
#include "openfpga_reserved_words.h"
|
||||
|
||||
#include "spice_constants.h"
|
||||
#include "spice_submodule.h"
|
||||
|
||||
/* Header file for this source file */
|
||||
#include "spice_api.h"
|
||||
|
||||
/* begin namespace openfpga */
|
||||
namespace openfpga {
|
||||
|
||||
/********************************************************************
|
||||
* A top-level function of FPGA-SPICE which focuses on fabric Spice generation
|
||||
* This function will generate
|
||||
* - primitive modules required by the full fabric
|
||||
* - which are LUTs, routing multiplexer, logic gates, transmission-gates etc.
|
||||
* - Routing modules, which are Switch Blocks (SBs) and Connection Blocks (CBs)
|
||||
* - Logic block modules, which are Configuration Logic Blocks (CLBs)
|
||||
* - FPGA module, which are the full FPGA fabric with configuration protocol
|
||||
*
|
||||
* Note:
|
||||
* - Please do NOT include ANY testbench generation in this function!!!
|
||||
* 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) {
|
||||
|
||||
vtr::ScopedStartFinishTimer timer("Write SPICE netlists for FPGA fabric\n");
|
||||
|
||||
std::string src_dir_path = format_dir_path(options.output_directory());
|
||||
|
||||
/* Create directories */
|
||||
create_directory(src_dir_path);
|
||||
|
||||
/* Sub directory under SRC directory to contain all the primitive block netlists */
|
||||
std::string submodule_dir_path = src_dir_path + std::string(DEFAULT_SUBMODULE_DIR_NAME);
|
||||
create_directory(submodule_dir_path);
|
||||
|
||||
/* Sub directory under SRC directory to contain all the logic block netlists */
|
||||
std::string lb_dir_path = src_dir_path + std::string(DEFAULT_LB_DIR_NAME);
|
||||
create_directory(lb_dir_path);
|
||||
|
||||
/* Sub directory under SRC directory to contain all the routing block netlists */
|
||||
std::string rr_dir_path = src_dir_path + std::string(DEFAULT_RR_DIR_NAME);
|
||||
create_directory(rr_dir_path);
|
||||
|
||||
/* Generate primitive Spice modules, which are corner stones of FPGA fabric
|
||||
* Note that this function MUST be called before Spice generation of
|
||||
* core logic (i.e., logic blocks and routing resources) !!!
|
||||
* This is because that this function will add the primitive Spice modules to
|
||||
* the module manager.
|
||||
* Without the modules in the module manager, core logic generation is not possible!!!
|
||||
*/
|
||||
print_spice_submodule(netlist_manager,
|
||||
submodule_dir_path);
|
||||
|
||||
/* 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());
|
||||
}
|
||||
|
||||
} /* end namespace openfpga */
|
|
@ -0,0 +1,27 @@
|
|||
#ifndef SPICE_API_H
|
||||
#define SPICE_API_H
|
||||
|
||||
/********************************************************************
|
||||
* Include header files that are required by function declaration
|
||||
*******************************************************************/
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "netlist_manager.h"
|
||||
#include "module_manager.h"
|
||||
#include "fabric_spice_options.h"
|
||||
|
||||
/********************************************************************
|
||||
* Function declaration
|
||||
*******************************************************************/
|
||||
|
||||
/* begin namespace openfpga */
|
||||
namespace openfpga {
|
||||
|
||||
void fpga_fabric_spice(const ModuleManager& module_manager,
|
||||
NetlistManager& netlist_manager,
|
||||
const FabricSpiceOption& options);
|
||||
|
||||
} /* end namespace openfpga */
|
||||
|
||||
#endif
|
|
@ -0,0 +1,11 @@
|
|||
#ifndef SPICE_CONSTANTS_H
|
||||
#define SPICE_CONSTANTS_H
|
||||
|
||||
/* global parameters for dumping spice netlists */
|
||||
|
||||
constexpr char* SPICE_NETLIST_FILE_POSTFIX = ".sp";
|
||||
|
||||
constexpr char* TRANSISTORS_SPICE_FILE_NAME = "transistor.sp";
|
||||
constexpr char* ESSENTIALS_SPICE_FILE_NAME = "inv_buf_passgate.sp";
|
||||
|
||||
#endif
|
|
@ -0,0 +1,51 @@
|
|||
/************************************************
|
||||
* This file includes functions on
|
||||
* outputting Verilog netlists for essential gates
|
||||
* which are inverters, buffers, transmission-gates
|
||||
* logic gates etc.
|
||||
***********************************************/
|
||||
#include <fstream>
|
||||
|
||||
/* Headers from vtrutil library */
|
||||
#include "vtr_assert.h"
|
||||
#include "vtr_log.h"
|
||||
|
||||
/* Headers from openfpgautil library */
|
||||
#include "openfpga_digest.h"
|
||||
|
||||
#include "spice_constants.h"
|
||||
#include "spice_essential_gates.h"
|
||||
|
||||
/* begin namespace openfpga */
|
||||
namespace openfpga {
|
||||
|
||||
/************************************************
|
||||
* 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);
|
||||
|
||||
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 transistor wrappers...",
|
||||
spice_fname.c_str());
|
||||
|
||||
/* 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");
|
||||
}
|
||||
|
||||
} /* end namespace openfpga */
|
|
@ -0,0 +1,22 @@
|
|||
#ifndef SPICE_ESSENTIAL_GATES_H
|
||||
#define SPICE_ESSENTIAL_GATES_H
|
||||
|
||||
/********************************************************************
|
||||
* Include header files that are required by function declaration
|
||||
*******************************************************************/
|
||||
#include <string>
|
||||
#include "netlist_manager.h"
|
||||
|
||||
/********************************************************************
|
||||
* Function declaration
|
||||
*******************************************************************/
|
||||
|
||||
/* begin namespace openfpga */
|
||||
namespace openfpga {
|
||||
|
||||
void print_spice_transistor_wrapper(NetlistManager& netlist_manager,
|
||||
const std::string& submodule_dir);
|
||||
|
||||
} /* end namespace openfpga */
|
||||
|
||||
#endif
|
|
@ -0,0 +1,34 @@
|
|||
/*********************************************************************
|
||||
* This file includes top-level function to generate Spice primitive modules
|
||||
* and print them to files
|
||||
********************************************************************/
|
||||
|
||||
/* Headers from vtrutil library */
|
||||
#include "vtr_assert.h"
|
||||
#include "vtr_log.h"
|
||||
|
||||
#include "spice_essential_gates.h"
|
||||
|
||||
#include "spice_constants.h"
|
||||
#include "spice_submodule.h"
|
||||
|
||||
/* begin namespace openfpga */
|
||||
namespace openfpga {
|
||||
|
||||
/*********************************************************************
|
||||
* Top-level function to generate primitive modules:
|
||||
* 1. Transistor wrapper
|
||||
* 2. TODO: Logic gates: AND/OR, inverter, buffer and transmission-gate/pass-transistor
|
||||
* 3. TODO: Routing multiplexers
|
||||
* 4. TODO: Local encoders for routing multiplexers
|
||||
* 5. TODO: Wires
|
||||
* 6. TODO: Configuration memory blocks
|
||||
********************************************************************/
|
||||
void print_spice_submodule(NetlistManager& netlist_manager,
|
||||
const std::string& submodule_dir) {
|
||||
|
||||
print_spice_transistor_wrapper(netlist_manager,
|
||||
submodule_dir);
|
||||
}
|
||||
|
||||
} /* end namespace openfpga */
|
|
@ -0,0 +1,21 @@
|
|||
#ifndef SPICE_SUBMODULE_H
|
||||
#define SPICE_SUBMODULE_H
|
||||
|
||||
/********************************************************************
|
||||
* Include header files that are required by function declaration
|
||||
*******************************************************************/
|
||||
#include "netlist_manager.h"
|
||||
|
||||
/********************************************************************
|
||||
* Function declaration
|
||||
*******************************************************************/
|
||||
|
||||
/* begin namespace openfpga */
|
||||
namespace openfpga {
|
||||
|
||||
void print_spice_submodule(NetlistManager& netlist_manager,
|
||||
const std::string& submodule_dir);
|
||||
|
||||
} /* end namespace openfpga */
|
||||
|
||||
#endif
|
|
@ -15,6 +15,7 @@
|
|||
#include "openfpga_setup_command.h"
|
||||
#include "openfpga_verilog_command.h"
|
||||
#include "openfpga_bitstream_command.h"
|
||||
#include "openfpga_spice_command.h"
|
||||
#include "openfpga_sdc_command.h"
|
||||
#include "basic_command.h"
|
||||
|
||||
|
@ -63,6 +64,9 @@ int main(int argc, char** argv) {
|
|||
/* Add openfpga bitstream commands */
|
||||
openfpga::add_openfpga_bitstream_commands(shell);
|
||||
|
||||
/* Add openfpga SPICE commands */
|
||||
openfpga::add_openfpga_spice_commands(shell);
|
||||
|
||||
/* Add openfpga sdc commands */
|
||||
openfpga::add_openfpga_sdc_commands(shell);
|
||||
|
||||
|
|
Loading…
Reference in New Issue