Merge branch 'refactoring' into dev
This commit is contained in:
commit
2035afc34b
|
@ -2,6 +2,9 @@
|
|||
* This file includes functions that handles the file outputting
|
||||
* in OpenFPGA framework
|
||||
*******************************************************************/
|
||||
#include <sys/stat.h>
|
||||
#include <algorithm>
|
||||
|
||||
/* Headers from vtrutil library */
|
||||
#include "vtr_log.h"
|
||||
|
||||
|
@ -37,4 +40,114 @@ void check_file_stream(const char* fname,
|
|||
}
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
* Format a directory path:
|
||||
* 1. Replace "\" with "/"
|
||||
* 2. add a "/" if the string does not end with a "/"
|
||||
*******************************************************************/
|
||||
std::string format_dir_path(const std::string& dir_path_to_format) {
|
||||
std::string formatted_dir_path = dir_path_to_format;
|
||||
|
||||
char illegal_back_slash = '\\';
|
||||
char legal_back_slash = '/';
|
||||
|
||||
#ifdef _WIN32
|
||||
/* For windows OS, replace any '/' with '\' */
|
||||
char illegal_back_slash = '/';
|
||||
char legal_back_slash = '\\';
|
||||
#endif
|
||||
|
||||
/* Replace "\" with "/" */
|
||||
std::replace(formatted_dir_path.begin(), formatted_dir_path.end(), illegal_back_slash, legal_back_slash);
|
||||
|
||||
/* Add a back slash the string is not ended like this! */
|
||||
if (legal_back_slash != formatted_dir_path.back()) {
|
||||
formatted_dir_path.push_back(legal_back_slash);
|
||||
}
|
||||
|
||||
return formatted_dir_path;
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
* Extract full file name from a full path of file
|
||||
* For example: <dir_path>/<file_name>
|
||||
* This function will return <file_name>
|
||||
********************************************************************/
|
||||
std::string find_path_file_name(const std::string& file_name) {
|
||||
|
||||
char back_slash = '/';
|
||||
|
||||
#ifdef _WIN32
|
||||
/* For windows OS, replace any '/' with '\' */
|
||||
char back_slash = '\\';
|
||||
#endif
|
||||
|
||||
/* Find the last '/' in the string and return the left part */
|
||||
size_t found = file_name.rfind(back_slash);
|
||||
if (found != std::string::npos) {
|
||||
return file_name.substr(found + 1);
|
||||
}
|
||||
/* Not found. The input is the file name! Return the original string */
|
||||
return file_name;
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
* Extract full directory path from a full path of file
|
||||
* For example: <dir_path>/<file_name>
|
||||
* This function will return <dir_path>
|
||||
********************************************************************/
|
||||
std::string find_path_dir_name(const std::string& file_name) {
|
||||
|
||||
char back_slash = '/';
|
||||
|
||||
#ifdef _WIN32
|
||||
/* For windows OS, replace any '/' with '\' */
|
||||
char back_slash = '\\';
|
||||
#endif
|
||||
|
||||
/* Find the last '/' in the string and return the left part */
|
||||
size_t found = file_name.rfind(back_slash);
|
||||
if (found != std::string::npos) {
|
||||
return file_name.substr(0, found);
|
||||
}
|
||||
/* Not found, return an empty string */
|
||||
return std::string();
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
* Create a directory with a given path
|
||||
********************************************************************/
|
||||
bool create_dir_path(const char* dir_path) {
|
||||
/* Give up if the path is empty */
|
||||
if (nullptr == dir_path) {
|
||||
VTR_LOG_ERROR("dir_path is empty and nothing is created.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Try to create a directory */
|
||||
int ret = mkdir(dir_path, S_IRWXU|S_IRWXG|S_IROTH|S_IXOTH);
|
||||
|
||||
/* Analyze the return flag and output status */
|
||||
switch (ret) {
|
||||
case 0:
|
||||
VTR_LOG("Succeed to create directory '%s'\n",
|
||||
dir_path);
|
||||
return true;
|
||||
case -1:
|
||||
if (EEXIST == errno) {
|
||||
VTR_LOG_ERROR("Directory '%s' already exists. Will overwrite contents\n",
|
||||
dir_path);
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
VTR_LOG_ERROR("Create directory '%s'...Failed!\n",
|
||||
dir_path);
|
||||
exit(1);
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
} /* namespace openfpga ends */
|
||||
|
|
|
@ -17,6 +17,14 @@ bool valid_file_stream(std::fstream& fp);
|
|||
void check_file_stream(const char* fname,
|
||||
std::fstream& fp);
|
||||
|
||||
std::string format_dir_path(const std::string& dir_path_to_format);
|
||||
|
||||
std::string find_path_file_name(const std::string& file_name);
|
||||
|
||||
std::string find_path_dir_name(const std::string& file_name);
|
||||
|
||||
bool create_dir_path(const char* dir_path);
|
||||
|
||||
} /* namespace openfpga ends */
|
||||
|
||||
#endif
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include "mux_library.h"
|
||||
#include "tile_direct.h"
|
||||
#include "module_manager.h"
|
||||
#include "openfpga_flow_manager.h"
|
||||
#include "device_rr_gsb.h"
|
||||
|
||||
/********************************************************************
|
||||
|
@ -50,6 +51,7 @@ class OpenfpgaContext : public Context {
|
|||
const openfpga::MuxLibrary& mux_lib() const { return mux_lib_; }
|
||||
const openfpga::TileDirect& tile_direct() const { return tile_direct_; }
|
||||
const openfpga::ModuleManager& module_graph() const { return module_graph_; }
|
||||
const openfpga::FlowManager& flow_manager() const { return flow_manager_; }
|
||||
public: /* Public mutators */
|
||||
openfpga::Arch& mutable_arch() { return arch_; }
|
||||
openfpga::VprDeviceAnnotation& mutable_vpr_device_annotation() { return vpr_device_annotation_; }
|
||||
|
@ -60,6 +62,7 @@ class OpenfpgaContext : public Context {
|
|||
openfpga::MuxLibrary& mutable_mux_lib() { return mux_lib_; }
|
||||
openfpga::TileDirect& mutable_tile_direct() { return tile_direct_; }
|
||||
openfpga::ModuleManager& mutable_module_graph() { return module_graph_; }
|
||||
openfpga::FlowManager& mutable_flow_manager() { return flow_manager_; }
|
||||
private: /* Internal data */
|
||||
/* Data structure to store information from read_openfpga_arch library */
|
||||
openfpga::Arch arch_;
|
||||
|
@ -87,6 +90,9 @@ class OpenfpgaContext : public Context {
|
|||
|
||||
/* Fabric module graph */
|
||||
openfpga::ModuleManager module_graph_;
|
||||
|
||||
/* Flow status */
|
||||
openfpga::FlowManager flow_manager_;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
/******************************************************************************
|
||||
* Memember functions for data structure FlowManager
|
||||
******************************************************************************/
|
||||
#include "vtr_assert.h"
|
||||
|
||||
#include "openfpga_flow_manager.h"
|
||||
|
||||
/* begin namespace openfpga */
|
||||
namespace openfpga {
|
||||
|
||||
/**************************************************
|
||||
* Public Accessors
|
||||
*************************************************/
|
||||
bool FlowManager::compress_routing() const {
|
||||
return compress_routing_;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Private Mutators
|
||||
******************************************************************************/
|
||||
void FlowManager::set_compress_routing(const bool& enabled) {
|
||||
compress_routing_ = enabled;
|
||||
}
|
||||
|
||||
|
||||
} /* end namespace openfpga */
|
|
@ -0,0 +1,28 @@
|
|||
#ifndef FLOW_MANAGER_H
|
||||
#define FLOW_MANAGER_H
|
||||
|
||||
/********************************************************************
|
||||
* Include header files required by the data structure definition
|
||||
*******************************************************************/
|
||||
/* Begin namespace openfpga */
|
||||
namespace openfpga {
|
||||
|
||||
/********************************************************************
|
||||
* FlowManager aims to resolve the dependency between OpenFPGA functional
|
||||
* code blocks
|
||||
* It can provide flags for downstream modules about if the data structures
|
||||
* they require have already been constructed
|
||||
*
|
||||
*******************************************************************/
|
||||
class FlowManager {
|
||||
public: /* Public accessors */
|
||||
bool compress_routing() const;
|
||||
public: /* Public mutators */
|
||||
void set_compress_routing(const bool& enabled);
|
||||
private: /* Internal Data */
|
||||
bool compress_routing_;
|
||||
};
|
||||
|
||||
} /* End namespace openfpga*/
|
||||
|
||||
#endif
|
|
@ -135,7 +135,7 @@ void add_openfpga_setup_commands(openfpga::Shell<OpenfpgaContext>& shell) {
|
|||
shell.set_command_execute_function(shell_cmd_build_fabric_id, build_fabric);
|
||||
/* The 'build_fabric' command should NOT be executed before 'link_openfpga_arch' */
|
||||
std::vector<ShellCommandId> cmd_dependency_build_fabric;
|
||||
cmd_dependency_lut_truth_table_fixup.push_back(shell_cmd_link_openfpga_arch_id);
|
||||
cmd_dependency_build_fabric.push_back(shell_cmd_link_openfpga_arch_id);
|
||||
shell.set_command_dependency(shell_cmd_build_fabric_id, cmd_dependency_build_fabric);
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
/********************************************************************
|
||||
* This file includes functions to compress the hierachy of routing architecture
|
||||
*******************************************************************/
|
||||
/* Headers from vtrutil library */
|
||||
#include "vtr_time.h"
|
||||
#include "vtr_log.h"
|
||||
|
||||
#include "verilog_api.h"
|
||||
#include "openfpga_verilog.h"
|
||||
|
||||
/* Include global variables of VPR */
|
||||
#include "globals.h"
|
||||
|
||||
/* begin namespace openfpga */
|
||||
namespace openfpga {
|
||||
|
||||
/********************************************************************
|
||||
* A wrapper function to call the fabric_verilog function of FPGA-Verilog
|
||||
*******************************************************************/
|
||||
void write_fabric_verilog(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_include_timing = cmd.option("include_timing");
|
||||
CommandOptionId opt_include_signal_init = cmd.option("include_signal_init");
|
||||
CommandOptionId opt_support_icarus_simulator = cmd.option("support_icarus_simulator");
|
||||
CommandOptionId opt_verbose = cmd.option("verbose");
|
||||
|
||||
/* This is an intermediate data structure which is designed to modularize the FPGA-Verilog
|
||||
* Keep it independent from any other outside data structures
|
||||
*/
|
||||
FabricVerilogOption 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_include_timing(cmd_context.option_enable(cmd, opt_include_timing));
|
||||
options.set_include_signal_init(cmd_context.option_enable(cmd, opt_include_signal_init));
|
||||
options.set_support_icarus_simulator(cmd_context.option_enable(cmd, opt_support_icarus_simulator));
|
||||
options.set_verbose_output(cmd_context.option_enable(cmd, opt_verbose));
|
||||
options.set_compress_routing(openfpga_ctx.flow_manager().compress_routing());
|
||||
|
||||
fpga_fabric_verilog(openfpga_ctx.module_graph(),
|
||||
openfpga_ctx.arch().circuit_lib,
|
||||
openfpga_ctx.mux_lib(),
|
||||
g_vpr_ctx.device().grid,
|
||||
openfpga_ctx.device_rr_gsb(),
|
||||
options);
|
||||
}
|
||||
|
||||
} /* end namespace openfpga */
|
|
@ -0,0 +1,23 @@
|
|||
#ifndef OPENFPGA_VERILOG_H
|
||||
#define OPENFPGA_VERILOG_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 {
|
||||
|
||||
void write_fabric_verilog(OpenfpgaContext& openfpga_ctx,
|
||||
const Command& cmd, const CommandContext& cmd_context);
|
||||
|
||||
} /* end namespace openfpga */
|
||||
|
||||
#endif
|
|
@ -0,0 +1,51 @@
|
|||
/********************************************************************
|
||||
* Add commands to the OpenFPGA shell interface,
|
||||
* in purpose of generate Verilog netlists modeling the full FPGA fabric
|
||||
* This is one of the core engine of openfpga, including:
|
||||
* - generate_fabric_verilog : generate Verilog netlists about FPGA fabric
|
||||
* - generate_fabric_verilog_testbench : TODO: generate Verilog testbenches
|
||||
*******************************************************************/
|
||||
#include "openfpga_verilog.h"
|
||||
#include "openfpga_verilog_command.h"
|
||||
|
||||
/* begin namespace openfpga */
|
||||
namespace openfpga {
|
||||
|
||||
void add_openfpga_verilog_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& shell_cmd_build_fabric_id = shell.command(std::string("build_fabric"));
|
||||
|
||||
/* Add a new class of commands */
|
||||
ShellCommandClassId openfpga_verilog_cmd_class = shell.add_command_class("FPGA-Verilog");
|
||||
|
||||
/********************************
|
||||
* Command 'wirte_fabric_verilog'
|
||||
*/
|
||||
Command shell_cmd_write_fabric_verilog("write_fabric_verilog");
|
||||
/* Add an option '--file' in short '-f'*/
|
||||
CommandOptionId fabric_verilog_output_opt = shell_cmd_write_fabric_verilog.add_option("file", true, "Specify the output directory for Verilog netlists");
|
||||
shell_cmd_write_fabric_verilog.set_option_short_name(fabric_verilog_output_opt, "f");
|
||||
shell_cmd_write_fabric_verilog.set_option_require_value(fabric_verilog_output_opt, openfpga::OPT_STRING);
|
||||
/* Add an option '--explicit_port_mapping' */
|
||||
shell_cmd_write_fabric_verilog.add_option("explicit_port_mapping", false, "Use explicit port mapping in Verilog netlists");
|
||||
/* Add an option '--include_timing' */
|
||||
shell_cmd_write_fabric_verilog.add_option("include_timing", false, "Enable timing annotation in Verilog netlists");
|
||||
/* Add an option '--include_signal_init' */
|
||||
shell_cmd_write_fabric_verilog.add_option("include_signal_init", false, "Initialize all the signals in Verilog netlists");
|
||||
/* Add an option '--support_icarus_simulator' */
|
||||
shell_cmd_write_fabric_verilog.add_option("support_icarus_simulator", false, "Fine-tune Verilog netlists to support icarus simulator");
|
||||
/* Add an option '--verbose' */
|
||||
shell_cmd_write_fabric_verilog.add_option("verbose", false, "Enable verbose output");
|
||||
|
||||
/* Add command 'write_fabric_verilog' to the Shell */
|
||||
ShellCommandId shell_cmd_write_fabric_verilog_id = shell.add_command(shell_cmd_write_fabric_verilog, "generate Verilog netlists modeling full FPGA fabric");
|
||||
shell.set_command_class(shell_cmd_write_fabric_verilog_id, openfpga_verilog_cmd_class);
|
||||
shell.set_command_execute_function(shell_cmd_write_fabric_verilog_id, write_fabric_verilog);
|
||||
|
||||
/* The 'build_fabric' command should NOT be executed before 'link_openfpga_arch' */
|
||||
std::vector<ShellCommandId> cmd_dependency_write_fabric_verilog;
|
||||
cmd_dependency_write_fabric_verilog.push_back(shell_cmd_build_fabric_id);
|
||||
shell.set_command_dependency(shell_cmd_write_fabric_verilog_id, cmd_dependency_write_fabric_verilog);
|
||||
}
|
||||
|
||||
} /* end namespace openfpga */
|
|
@ -0,0 +1,21 @@
|
|||
#ifndef OPENFPGA_VERILOG_COMMAND_H
|
||||
#define OPENFPGA_VERILOG_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_verilog_commands(openfpga::Shell<OpenfpgaContext>& shell);
|
||||
|
||||
} /* end namespace openfpga */
|
||||
|
||||
#endif
|
|
@ -0,0 +1,116 @@
|
|||
/********************************************************************
|
||||
* This file include top-level function of FPGA-Verilog
|
||||
********************************************************************/
|
||||
|
||||
/* Headers from vtrutil library */
|
||||
#include "vtr_log.h"
|
||||
#include "vtr_assert.h"
|
||||
#include "vtr_time.h"
|
||||
|
||||
#include "circuit_library_utils.h"
|
||||
|
||||
/* Headers from openfpgautil library */
|
||||
#include "openfpga_digest.h"
|
||||
|
||||
#include "device_rr_gsb.h"
|
||||
#include "verilog_constants.h"
|
||||
#include "verilog_auxiliary_netlists.h"
|
||||
//#include "verilog_submodules.h"
|
||||
//#include "verilog_routing.h"
|
||||
//#include "verilog_submodules.h"
|
||||
//#include "verilog_grid.h"
|
||||
//#include "verilog_routing.h"
|
||||
//#include "verilog_top_module.h"
|
||||
|
||||
/* Header file for this source file */
|
||||
#include "verilog_api.h"
|
||||
|
||||
/* begin namespace openfpga */
|
||||
namespace openfpga {
|
||||
|
||||
/********************************************************************
|
||||
* Top-level function of FPGA-Verilog
|
||||
* This function will generate
|
||||
* 1. primitive modules required by the full fabric
|
||||
* which are LUTs, routing multiplexer, logic gates, transmission-gates etc.
|
||||
* 2. Routing modules, which are Switch Blocks (SBs) and Connection Blocks (CBs)
|
||||
* 3. Logic block modules, which are Configuration Logic Blocks (CLBs)
|
||||
* 4. FPGA module, which are the full FPGA fabric with configuration protocol
|
||||
* 5. A wrapper module, which encapsulate the FPGA module in a Verilog module which have the same port as the input benchmark
|
||||
* 6. Testbench, where a FPGA module is configured with a bitstream and then driven by input vectors
|
||||
* 7. Pre-configured testbench, which can skip the configuration phase and pre-configure the FPGA module. This testbench is created for quick verification and formal verification purpose.
|
||||
* 8. Verilog netlist including preprocessing flags and all the Verilog netlists that have been generated
|
||||
********************************************************************/
|
||||
void fpga_fabric_verilog(const ModuleManager& module_manager,
|
||||
const CircuitLibrary& circuit_lib,
|
||||
const MuxLibrary& mux_lib,
|
||||
const DeviceGrid& grids,
|
||||
const DeviceRRGSB& device_rr_gsb,
|
||||
const FabricVerilogOption& options) {
|
||||
|
||||
vtr::ScopedStartFinishTimer timer("Write Verilog netlists for FPGA fabric\n");
|
||||
|
||||
std::string src_dir_path = format_dir_path(options.output_directory());
|
||||
|
||||
/* Create directories */
|
||||
create_dir_path(src_dir_path.c_str());
|
||||
|
||||
/* 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_dir_path(submodule_dir_path.c_str());
|
||||
|
||||
/* 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_dir_path(lb_dir_path.c_str());
|
||||
|
||||
/* 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_dir_path(rr_dir_path.c_str());
|
||||
|
||||
/* Print Verilog files containing preprocessing flags */
|
||||
print_verilog_preprocessing_flags_netlist(std::string(src_dir_path),
|
||||
options);
|
||||
|
||||
print_verilog_simulation_preprocessing_flags(std::string(src_dir_path),
|
||||
options);
|
||||
|
||||
/* Generate primitive Verilog modules, which are corner stones of FPGA fabric
|
||||
* Note that this function MUST be called before Verilog generation of
|
||||
* core logic (i.e., logic blocks and routing resources) !!!
|
||||
* This is because that this function will add the primitive Verilog modules to
|
||||
* the module manager.
|
||||
* Without the modules in the module manager, core logic generation is not possible!!!
|
||||
*/
|
||||
//print_verilog_submodules(module_manager, mux_lib, sram_verilog_orgz_info, src_dir_path.c_str(), submodule_dir_path.c_str(),
|
||||
// Arch, vpr_setup.FPGA_SPICE_Opts.SynVerilogOpts);
|
||||
|
||||
/* Generate routing blocks */
|
||||
//if (true == compress_routing) {
|
||||
// print_verilog_unique_routing_modules(module_manager, device_rr_gsb,
|
||||
// src_dir_path, rr_dir_path,
|
||||
// dump_explicit_verilog);
|
||||
//} else {
|
||||
// VTR_ASSERT(false == compress_routing);
|
||||
// print_verilog_flatten_routing_modules(module_manager, device_rr_gsb,
|
||||
// src_dir_path, rr_dir_path,
|
||||
// dump_explicit_verilog);
|
||||
//}
|
||||
|
||||
/* Generate grids */
|
||||
//print_verilog_grids(module_manager,
|
||||
// src_dir_path, lb_dir_path,
|
||||
// dump_explicit_verilog);
|
||||
|
||||
/* Generate FPGA fabric */
|
||||
//print_verilog_top_module(module_manager,
|
||||
// std::string(vpr_setup.FileNameOpts.ArchFile),
|
||||
// src_dir_path,
|
||||
// dump_explicit_verilog);
|
||||
|
||||
/* Given a brief stats on how many Verilog modules have been written to files */
|
||||
VTR_LOGV(options.verbose_output(),
|
||||
"Outputted %lu Verilog modules in total\n",
|
||||
module_manager.num_modules());
|
||||
}
|
||||
|
||||
} /* end namespace openfpga */
|
|
@ -0,0 +1,34 @@
|
|||
#ifndef VERILOG_API_H
|
||||
#define VERILOG_API_H
|
||||
|
||||
/********************************************************************
|
||||
* Include header files that are required by function declaration
|
||||
*******************************************************************/
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "vpr_types.h"
|
||||
#include "mux_library.h"
|
||||
#include "circuit_library.h"
|
||||
#include "device_grid.h"
|
||||
#include "device_rr_gsb.h"
|
||||
#include "module_manager.h"
|
||||
#include "verilog_options.h"
|
||||
|
||||
/********************************************************************
|
||||
* Function declaration
|
||||
*******************************************************************/
|
||||
|
||||
/* begin namespace openfpga */
|
||||
namespace openfpga {
|
||||
|
||||
void fpga_fabric_verilog(const ModuleManager& module_manager,
|
||||
const CircuitLibrary& circuit_lib,
|
||||
const MuxLibrary& mux_lib,
|
||||
const DeviceGrid& grids,
|
||||
const DeviceRRGSB& device_rr_gsb,
|
||||
const FabricVerilogOption& options);
|
||||
|
||||
} /* end namespace openfpga */
|
||||
|
||||
#endif
|
|
@ -0,0 +1,200 @@
|
|||
/********************************************************************
|
||||
* This file includes functions that are used to generate Verilog files
|
||||
* or code blocks, with a focus on
|
||||
* `include user-defined or auto-generated netlists in Verilog format
|
||||
*******************************************************************/
|
||||
#include <fstream>
|
||||
|
||||
/* Headers from vtrutil library */
|
||||
#include "vtr_assert.h"
|
||||
|
||||
/* Headers from openfpgautil library */
|
||||
#include "openfpga_digest.h"
|
||||
|
||||
#include "openfpga_naming.h"
|
||||
#include "circuit_library_utils.h"
|
||||
#include "verilog_constants.h"
|
||||
#include "verilog_writer_utils.h"
|
||||
#include "verilog_auxiliary_netlists.h"
|
||||
|
||||
/* begin namespace openfpga */
|
||||
namespace openfpga {
|
||||
|
||||
/********************************************************************
|
||||
* Local constant variables
|
||||
*******************************************************************/
|
||||
constexpr char* TOP_INCLUDE_NETLIST_FILE_NAME_POSTFIX = "_include_netlists.v";
|
||||
|
||||
/********************************************************************
|
||||
* Print a file that includes all the netlists that have been generated
|
||||
* and user-defined.
|
||||
* Some netlists are open to compile under specific preprocessing flags
|
||||
*******************************************************************/
|
||||
void print_include_netlists(const std::string& src_dir,
|
||||
const std::string& circuit_name,
|
||||
const std::string& reference_benchmark_file,
|
||||
const CircuitLibrary& circuit_lib) {
|
||||
std::string verilog_fname = src_dir + circuit_name + std::string(TOP_INCLUDE_NETLIST_FILE_NAME_POSTFIX);
|
||||
|
||||
/* Create the file stream */
|
||||
std::fstream fp;
|
||||
fp.open(verilog_fname, std::fstream::out | std::fstream::trunc);
|
||||
|
||||
/* Validate the file stream */
|
||||
check_file_stream(verilog_fname.c_str(), fp);
|
||||
|
||||
/* Print the title */
|
||||
print_verilog_file_header(fp, std::string("Netlist Summary"));
|
||||
|
||||
/* Print preprocessing flags */
|
||||
print_verilog_comment(fp, std::string("------ Include defines: preproc flags -----"));
|
||||
print_verilog_include_netlist(fp, std::string(src_dir + std::string(DEFINES_VERILOG_FILE_NAME)));
|
||||
fp << std::endl;
|
||||
|
||||
print_verilog_comment(fp, std::string("------ Include simulation defines -----"));
|
||||
print_verilog_include_netlist(fp, src_dir + std::string(DEFINES_VERILOG_SIMULATION_FILE_NAME));
|
||||
fp << std::endl;
|
||||
|
||||
/* Include all the user-defined netlists */
|
||||
for (const std::string& user_defined_netlist : find_circuit_library_unique_verilog_netlists(circuit_lib)) {
|
||||
print_verilog_include_netlist(fp, user_defined_netlist);
|
||||
}
|
||||
|
||||
/* Include all the primitive modules */
|
||||
print_verilog_include_netlist(fp, src_dir + std::string(DEFAULT_SUBMODULE_DIR_NAME) + std::string(SUBMODULE_VERILOG_FILE_NAME));
|
||||
fp << std::endl;
|
||||
|
||||
/* Include all the CLB, heterogeneous block modules */
|
||||
print_verilog_include_netlist(fp, src_dir + std::string(DEFAULT_LB_DIR_NAME) + std::string(LOGIC_BLOCK_VERILOG_FILE_NAME));
|
||||
fp << std::endl;
|
||||
|
||||
/* Include all the routing architecture modules */
|
||||
print_verilog_include_netlist(fp, src_dir + std::string(DEFAULT_RR_DIR_NAME) + std::string(ROUTING_VERILOG_FILE_NAME));
|
||||
fp << std::endl;
|
||||
|
||||
/* Include FPGA top module */
|
||||
print_verilog_include_netlist(fp, src_dir + generate_fpga_top_netlist_name(std::string(VERILOG_NETLIST_FILE_POSTFIX)));
|
||||
fp << std::endl;
|
||||
|
||||
/* Include reference benchmark netlist only when auto-check flag is enabled */
|
||||
print_verilog_preprocessing_flag(fp, std::string(AUTOCHECKED_SIMULATION_FLAG));
|
||||
fp << "\t";
|
||||
print_verilog_include_netlist(fp, std::string(reference_benchmark_file));
|
||||
print_verilog_endif(fp);
|
||||
fp << std::endl;
|
||||
|
||||
/* Include formal verification netlists only when formal verification flag is enable */
|
||||
print_verilog_preprocessing_flag(fp, std::string(VERILOG_FORMAL_VERIFICATION_PREPROC_FLAG));
|
||||
fp << "\t";
|
||||
print_verilog_include_netlist(fp, src_dir + circuit_name + std::string(FORMAL_VERIFICATION_VERILOG_FILE_POSTFIX));
|
||||
|
||||
/* Include formal verification testbench only when formal simulation flag is enabled */
|
||||
fp << "\t";
|
||||
print_verilog_preprocessing_flag(fp, std::string(FORMAL_SIMULATION_FLAG));
|
||||
fp << "\t\t";
|
||||
print_verilog_include_netlist(fp, src_dir + circuit_name + std::string(RANDOM_TOP_TESTBENCH_VERILOG_FILE_POSTFIX));
|
||||
fp << "\t";
|
||||
print_verilog_endif(fp);
|
||||
|
||||
print_verilog_endif(fp);
|
||||
fp << std::endl;
|
||||
|
||||
/* Include top-level testbench only when auto-check flag is enabled */
|
||||
print_verilog_preprocessing_flag(fp, std::string(AUTOCHECKED_SIMULATION_FLAG));
|
||||
fp << "\t";
|
||||
print_verilog_include_netlist(fp, src_dir + circuit_name + std::string(AUTOCHECK_TOP_TESTBENCH_VERILOG_FILE_POSTFIX));
|
||||
print_verilog_endif(fp);
|
||||
fp << std::endl;
|
||||
|
||||
/* Close the file stream */
|
||||
fp.close();
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
* Print a Verilog file containing preprocessing flags
|
||||
* which are used enable/disable some features in FPGA Verilog modules
|
||||
*******************************************************************/
|
||||
void print_verilog_preprocessing_flags_netlist(const std::string& src_dir,
|
||||
const FabricVerilogOption& fpga_verilog_opts) {
|
||||
|
||||
std::string verilog_fname = src_dir + std::string(DEFINES_VERILOG_FILE_NAME);
|
||||
|
||||
/* Create the file stream */
|
||||
std::fstream fp;
|
||||
fp.open(verilog_fname, std::fstream::out | std::fstream::trunc);
|
||||
|
||||
/* Validate the file stream */
|
||||
check_file_stream(verilog_fname.c_str(), fp);
|
||||
|
||||
/* Print the title */
|
||||
print_verilog_file_header(fp, std::string("Preprocessing flags to enable/disable features in FPGA Verilog modules"));
|
||||
|
||||
/* To enable timing */
|
||||
if (true == fpga_verilog_opts.include_timing()) {
|
||||
print_verilog_define_flag(fp, std::string(VERILOG_TIMING_PREPROC_FLAG), 1);
|
||||
fp << std::endl;
|
||||
}
|
||||
|
||||
/* To enable timing */
|
||||
if (true == fpga_verilog_opts.include_signal_init()) {
|
||||
print_verilog_define_flag(fp, std::string(VERILOG_SIGNAL_INIT_PREPROC_FLAG), 1);
|
||||
fp << std::endl;
|
||||
}
|
||||
|
||||
/* To enable formal verfication flag */
|
||||
if (true == fpga_verilog_opts.print_formal_verification_top_netlist()) {
|
||||
print_verilog_define_flag(fp, std::string(VERILOG_FORMAL_VERIFICATION_PREPROC_FLAG), 1);
|
||||
fp << std::endl;
|
||||
}
|
||||
|
||||
/* To enable functional verfication with Icarus */
|
||||
if (true == fpga_verilog_opts.support_icarus_simulator()) {
|
||||
print_verilog_define_flag(fp, std::string(ICARUS_SIMULATOR_FLAG), 1);
|
||||
fp << std::endl;
|
||||
}
|
||||
|
||||
/* Close the file stream */
|
||||
fp.close();
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
* Print a Verilog file containing simulation-related preprocessing flags
|
||||
*******************************************************************/
|
||||
void print_verilog_simulation_preprocessing_flags(const std::string& src_dir,
|
||||
const FabricVerilogOption& fpga_verilog_opts) {
|
||||
|
||||
std::string verilog_fname = src_dir + std::string(DEFINES_VERILOG_SIMULATION_FILE_NAME);
|
||||
|
||||
/* Create the file stream */
|
||||
std::fstream fp;
|
||||
fp.open(verilog_fname, std::fstream::out | std::fstream::trunc);
|
||||
|
||||
/* Validate the file stream */
|
||||
check_file_stream(verilog_fname.c_str(), fp);
|
||||
|
||||
/* Print the title */
|
||||
print_verilog_file_header(fp, std::string("Preprocessing flags to enable/disable simulation features"));
|
||||
|
||||
/* To enable manualy checked simulation */
|
||||
if (true == fpga_verilog_opts.print_top_testbench()) {
|
||||
print_verilog_define_flag(fp, std::string(INITIAL_SIMULATION_FLAG), 1);
|
||||
fp << std::endl;
|
||||
}
|
||||
|
||||
/* To enable auto-checked simulation */
|
||||
if (true == fpga_verilog_opts.print_autocheck_top_testbench()) {
|
||||
print_verilog_define_flag(fp, std::string(AUTOCHECKED_SIMULATION_FLAG), 1);
|
||||
fp << std::endl;
|
||||
}
|
||||
|
||||
/* To enable pre-configured FPGA simulation */
|
||||
if (true == fpga_verilog_opts.print_formal_verification_top_netlist()) {
|
||||
print_verilog_define_flag(fp, std::string(FORMAL_SIMULATION_FLAG), 1);
|
||||
fp << std::endl;
|
||||
}
|
||||
|
||||
/* Close the file stream */
|
||||
fp.close();
|
||||
}
|
||||
|
||||
} /* end namespace openfpga */
|
|
@ -0,0 +1,31 @@
|
|||
#ifndef VERILOG_AUXILIARY_NETLISTS_H
|
||||
#define VERILOG_AUXILIARY_NETLISTS_H
|
||||
|
||||
/********************************************************************
|
||||
* Include header files that are required by function declaration
|
||||
*******************************************************************/
|
||||
#include <string>
|
||||
#include "circuit_library.h"
|
||||
#include "verilog_options.h"
|
||||
|
||||
/********************************************************************
|
||||
* Function declaration
|
||||
*******************************************************************/
|
||||
|
||||
/* begin namespace openfpga */
|
||||
namespace openfpga {
|
||||
|
||||
void print_include_netlists(const std::string& src_dir,
|
||||
const std::string& circuit_name,
|
||||
const std::string& reference_benchmark_file,
|
||||
const CircuitLibrary& circuit_lib);
|
||||
|
||||
void print_verilog_preprocessing_flags_netlist(const std::string& src_dir,
|
||||
const FabricVerilogOption& fpga_verilog_opts);
|
||||
|
||||
void print_verilog_simulation_preprocessing_flags(const std::string& src_dir,
|
||||
const FabricVerilogOption& fpga_verilog_opts);
|
||||
|
||||
} /* end namespace openfpga */
|
||||
|
||||
#endif
|
|
@ -0,0 +1,44 @@
|
|||
#ifndef VERILOG_CONSTANTS_H
|
||||
#define VERILOG_CONSTANTS_H
|
||||
|
||||
/* global parameters for dumping synthesizable verilog */
|
||||
|
||||
constexpr char* VERILOG_NETLIST_FILE_POSTFIX = ".v";
|
||||
constexpr float VERILOG_SIM_TIMESCALE = 1e-9; // Verilog Simulation time scale (minimum time unit) : 1ns
|
||||
|
||||
constexpr char* VERILOG_TIMING_PREPROC_FLAG = "ENABLE_TIMING"; // the flag to enable timing definition during compilation
|
||||
constexpr char* VERILOG_SIGNAL_INIT_PREPROC_FLAG = "ENABLE_SIGNAL_INITIALIZATION"; // the flag to enable signal initialization during compilation
|
||||
constexpr char* VERILOG_FORMAL_VERIFICATION_PREPROC_FLAG = "ENABLE_FORMAL_VERIFICATION"; // the flag to enable formal verification during compilation
|
||||
constexpr char* INITIAL_SIMULATION_FLAG = "INITIAL_SIMULATION"; // the flag to enable initial functional verification
|
||||
constexpr char* AUTOCHECKED_SIMULATION_FLAG = "AUTOCHECKED_SIMULATION"; // the flag to enable autochecked functional verification
|
||||
constexpr char* FORMAL_SIMULATION_FLAG = "FORMAL_SIMULATION"; // the flag to enable formal functional verification
|
||||
|
||||
constexpr char* DEFAULT_LB_DIR_NAME = "lb/";
|
||||
constexpr char* DEFAULT_RR_DIR_NAME = "routing/";
|
||||
constexpr char* DEFAULT_SUBMODULE_DIR_NAME = "sub_module/";
|
||||
constexpr char* MODELSIM_SIMULATION_TIME_UNIT = "ms";
|
||||
|
||||
// Icarus variables and flag
|
||||
constexpr char* ICARUS_SIMULATOR_FLAG = "ICARUS_SIMULATOR"; // the flag to enable specific Verilog code in testbenches
|
||||
// End of Icarus variables and flag
|
||||
|
||||
constexpr char* VERILOG_TOP_POSTFIX = "_top.v";
|
||||
constexpr char* FORMAL_VERIFICATION_VERILOG_FILE_POSTFIX = "_top_formal_verification.v";
|
||||
constexpr char* TOP_TESTBENCH_VERILOG_FILE_POSTFIX = "_top_tb.v"; /* !!! must be consist with the modelsim_testbench_module_postfix */
|
||||
constexpr char* AUTOCHECK_TOP_TESTBENCH_VERILOG_FILE_POSTFIX = "_autocheck_top_tb.v"; /* !!! must be consist with the modelsim_autocheck_testbench_module_postfix */
|
||||
constexpr char* RANDOM_TOP_TESTBENCH_VERILOG_FILE_POSTFIX = "_formal_random_top_tb.v";
|
||||
constexpr char* DEFINES_VERILOG_FILE_NAME = "fpga_defines.v";
|
||||
constexpr char* DEFINES_VERILOG_SIMULATION_FILE_NAME = "define_simulation.v";
|
||||
constexpr char* SUBMODULE_VERILOG_FILE_NAME = "sub_module.v";
|
||||
constexpr char* LOGIC_BLOCK_VERILOG_FILE_NAME = "logic_blocks.v";
|
||||
constexpr char* LUTS_VERILOG_FILE_NAME = "luts.v";
|
||||
constexpr char* ROUTING_VERILOG_FILE_NAME = "routing.v";
|
||||
constexpr char* MUXES_VERILOG_FILE_NAME = "muxes.v";
|
||||
constexpr char* LOCAL_ENCODER_VERILOG_FILE_NAME = "local_encoder.v";
|
||||
constexpr char* MEMORIES_VERILOG_FILE_NAME = "memories.v";
|
||||
constexpr char* WIRES_VERILOG_FILE_NAME = "wires.v";
|
||||
constexpr char* ESSENTIALS_VERILOG_FILE_NAME = "inv_buf_passgate.v";
|
||||
constexpr char* CONFIG_PERIPHERAL_VERILOG_FILE_NAME = "config_peripherals.v";
|
||||
constexpr char* USER_DEFINED_TEMPLATE_VERILOG_FILE_NAME = "user_defined_templates.v";
|
||||
|
||||
#endif
|
|
@ -0,0 +1,101 @@
|
|||
/******************************************************************************
|
||||
* Memember functions for data structure FabricVerilogOption
|
||||
******************************************************************************/
|
||||
#include "vtr_assert.h"
|
||||
|
||||
#include "verilog_options.h"
|
||||
|
||||
/* begin namespace openfpga */
|
||||
namespace openfpga {
|
||||
|
||||
/**************************************************
|
||||
* Public Accessors
|
||||
*************************************************/
|
||||
std::string FabricVerilogOption::output_directory() const {
|
||||
return output_directory_;
|
||||
}
|
||||
|
||||
bool FabricVerilogOption::support_icarus_simulator() const {
|
||||
return support_icarus_simulator_;
|
||||
}
|
||||
|
||||
bool FabricVerilogOption::include_timing() const {
|
||||
return include_timing_;
|
||||
}
|
||||
|
||||
bool FabricVerilogOption::include_signal_init() const {
|
||||
return include_signal_init_;
|
||||
}
|
||||
|
||||
bool FabricVerilogOption::explicit_port_mapping() const {
|
||||
return explicit_port_mapping_;
|
||||
}
|
||||
|
||||
bool FabricVerilogOption::compress_routing() const {
|
||||
return compress_routing_;
|
||||
}
|
||||
|
||||
bool FabricVerilogOption::print_top_testbench() const {
|
||||
return print_top_testbench_;
|
||||
}
|
||||
|
||||
bool FabricVerilogOption::print_formal_verification_top_netlist() const {
|
||||
return print_formal_verification_top_netlist_;
|
||||
}
|
||||
|
||||
bool FabricVerilogOption::print_autocheck_top_testbench() const {
|
||||
return false == reference_verilog_file_path_.empty();
|
||||
}
|
||||
|
||||
std::string FabricVerilogOption::reference_verilog_file_path() const {
|
||||
return reference_verilog_file_path_;
|
||||
}
|
||||
|
||||
bool FabricVerilogOption::verbose_output() const {
|
||||
return verbose_output_;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Private Mutators
|
||||
******************************************************************************/
|
||||
void FabricVerilogOption::set_output_directory(const std::string& output_dir) {
|
||||
output_directory_ = output_dir;
|
||||
}
|
||||
|
||||
void FabricVerilogOption::set_support_icarus_simulator(const bool& enabled) {
|
||||
support_icarus_simulator_ = enabled;
|
||||
}
|
||||
|
||||
void FabricVerilogOption::set_include_timing(const bool& enabled) {
|
||||
include_timing_ = enabled;
|
||||
}
|
||||
|
||||
void FabricVerilogOption::set_include_signal_init(const bool& enabled) {
|
||||
include_signal_init_ = enabled;
|
||||
}
|
||||
|
||||
void FabricVerilogOption::set_explicit_port_mapping(const bool& enabled) {
|
||||
explicit_port_mapping_ = enabled;
|
||||
}
|
||||
|
||||
void FabricVerilogOption::set_compress_routing(const bool& enabled) {
|
||||
compress_routing_ = enabled;
|
||||
}
|
||||
|
||||
void FabricVerilogOption::set_print_top_testbench(const bool& enabled) {
|
||||
print_top_testbench_ = enabled;
|
||||
}
|
||||
|
||||
void FabricVerilogOption::set_print_formal_verification_top_netlist(const bool& enabled) {
|
||||
print_formal_verification_top_netlist_ = enabled;
|
||||
}
|
||||
|
||||
void FabricVerilogOption::set_print_autocheck_top_testbench(const std::string& reference_verilog_file_path) {
|
||||
reference_verilog_file_path_ = reference_verilog_file_path;
|
||||
}
|
||||
|
||||
void FabricVerilogOption::set_verbose_output(const bool& enabled) {
|
||||
verbose_output_ = enabled;
|
||||
}
|
||||
|
||||
} /* end namespace openfpga */
|
|
@ -0,0 +1,59 @@
|
|||
#ifndef VERILOG_OPTIONS_H
|
||||
#define VERILOG_OPTIONS_H
|
||||
|
||||
/********************************************************************
|
||||
* Include header files required by the data structure definition
|
||||
*******************************************************************/
|
||||
#include <string>
|
||||
|
||||
/* Begin namespace openfpga */
|
||||
namespace openfpga {
|
||||
|
||||
/********************************************************************
|
||||
* FlowManager aims to resolve the dependency between OpenFPGA functional
|
||||
* code blocks
|
||||
* It can provide flags for downstream modules about if the data structures
|
||||
* they require have already been constructed
|
||||
*
|
||||
*******************************************************************/
|
||||
class FabricVerilogOption {
|
||||
public: /* Public accessors */
|
||||
std::string output_directory() const;
|
||||
bool support_icarus_simulator() const;
|
||||
bool include_timing() const;
|
||||
bool include_signal_init() const;
|
||||
bool explicit_port_mapping() const;
|
||||
bool compress_routing() const;
|
||||
bool print_top_testbench() const;
|
||||
bool print_formal_verification_top_netlist() const;
|
||||
bool print_autocheck_top_testbench() const;
|
||||
std::string reference_verilog_file_path() const;
|
||||
bool verbose_output() const;
|
||||
public: /* Public mutators */
|
||||
void set_output_directory(const std::string& output_dir);
|
||||
void set_support_icarus_simulator(const bool& enabled);
|
||||
void set_include_timing(const bool& enabled);
|
||||
void set_include_signal_init(const bool& enabled);
|
||||
void set_explicit_port_mapping(const bool& enabled);
|
||||
void set_compress_routing(const bool& enabled);
|
||||
void set_print_top_testbench(const bool& enabled);
|
||||
void set_print_formal_verification_top_netlist(const bool& enabled);
|
||||
void set_print_autocheck_top_testbench(const std::string& reference_verilog_file_path);
|
||||
void set_verbose_output(const bool& enabled);
|
||||
private: /* Internal Data */
|
||||
std::string output_directory_;
|
||||
bool support_icarus_simulator_;
|
||||
bool include_signal_init_;
|
||||
bool include_timing_;
|
||||
bool explicit_port_mapping_;
|
||||
bool compress_routing_;
|
||||
bool print_top_testbench_;
|
||||
bool print_formal_verification_top_netlist_;
|
||||
/* print_autocheck_top_testbench will be enabled when reference file path is not empty */
|
||||
std::string reference_verilog_file_path_;
|
||||
bool verbose_output_;
|
||||
};
|
||||
|
||||
} /* End namespace openfpga*/
|
||||
|
||||
#endif
|
|
@ -0,0 +1,16 @@
|
|||
#ifndef VERILOG_PORT_TYPES_H
|
||||
#define VERILOG_PORT_TYPES_H
|
||||
|
||||
enum e_dump_verilog_port_type {
|
||||
VERILOG_PORT_INPUT,
|
||||
VERILOG_PORT_OUTPUT,
|
||||
VERILOG_PORT_INOUT,
|
||||
VERILOG_PORT_WIRE,
|
||||
VERILOG_PORT_REG,
|
||||
VERILOG_PORT_CONKT,
|
||||
NUM_VERILOG_PORT_TYPES
|
||||
};
|
||||
constexpr std::array<const char*, NUM_VERILOG_PORT_TYPES> VERILOG_PORT_TYPE_STRING = {{"input", "output", "inout", "wire", "reg", ""}}; /* string version of enum e_verilog_port_type */
|
||||
|
||||
#endif
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,187 @@
|
|||
/************************************************
|
||||
* Header file for verilog_writer_utils.cpp
|
||||
* Include function declaration for most frequently
|
||||
* used Verilog writers
|
||||
***********************************************/
|
||||
#ifndef VERILOG_WRITER_UTILS_H
|
||||
#define VERILOG_WRITER_UTILS_H
|
||||
|
||||
/********************************************************************
|
||||
* Include header files that are required by function declaration
|
||||
*******************************************************************/
|
||||
#include <fstream>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include "openfpga_port.h"
|
||||
#include "verilog_port_types.h"
|
||||
#include "module_manager.h"
|
||||
|
||||
/********************************************************************
|
||||
* Function declaration
|
||||
*******************************************************************/
|
||||
|
||||
/* begin namespace openfpga */
|
||||
namespace openfpga {
|
||||
|
||||
/* Tips: for naming your function in this header/source file
|
||||
* If a function outputs to a file, its name should begin with "print_verilog"
|
||||
* If a function creates a string without outputting to a file, its name should begin with "generate_verilog"
|
||||
* Please show respect to this naming convention, in order to keep a clean header/source file
|
||||
* as well maintain a easy way to identify the functions
|
||||
*/
|
||||
|
||||
void print_verilog_file_header(std::fstream& fp,
|
||||
const std::string& usage);
|
||||
|
||||
void print_verilog_include_netlist(std::fstream& fp,
|
||||
const std::string& netlist_name);
|
||||
|
||||
void print_verilog_define_flag(std::fstream& fp,
|
||||
const std::string& flag_name,
|
||||
const int& flag_value);
|
||||
|
||||
void print_verilog_include_defines_preproc_file(std::fstream& fp,
|
||||
const std::string& verilog_dir);
|
||||
|
||||
void print_verilog_comment(std::fstream& fp,
|
||||
const std::string& comment);
|
||||
|
||||
void print_verilog_preprocessing_flag(std::fstream& fp,
|
||||
const std::string& preproc_flag);
|
||||
|
||||
void print_verilog_endif(std::fstream& fp);
|
||||
|
||||
void print_verilog_module_definition(std::fstream& fp,
|
||||
const ModuleManager& module_manager, const ModuleId& module_id);
|
||||
|
||||
void print_verilog_module_ports(std::fstream& fp,
|
||||
const ModuleManager& module_manager, const ModuleId& module_id);
|
||||
|
||||
void print_verilog_module_declaration(std::fstream& fp,
|
||||
const ModuleManager& module_manager, const ModuleId& module_id);
|
||||
|
||||
void print_verilog_module_instance(std::fstream& fp,
|
||||
const ModuleManager& module_manager,
|
||||
const ModuleId& module_id,
|
||||
const std::string& instance_name,
|
||||
const std::map<std::string, BasicPort>& port2port_name_map,
|
||||
const bool& use_explicit_port_map);
|
||||
|
||||
void print_verilog_module_instance(std::fstream& fp,
|
||||
const ModuleManager& module_manager,
|
||||
const ModuleId& parent_module_id, const ModuleId& child_module_id,
|
||||
const std::map<std::string, BasicPort>& port2port_name_map,
|
||||
const bool& use_explicit_port_map);
|
||||
|
||||
void print_verilog_module_end(std::fstream& fp,
|
||||
const std::string& module_name);
|
||||
|
||||
std::string generate_verilog_port(const enum e_dump_verilog_port_type& dump_port_type,
|
||||
const BasicPort& port_info);
|
||||
|
||||
bool two_verilog_ports_mergeable(const BasicPort& portA,
|
||||
const BasicPort& portB);
|
||||
|
||||
BasicPort merge_two_verilog_ports(const BasicPort& portA,
|
||||
const BasicPort& portB);
|
||||
|
||||
std::vector<BasicPort> combine_verilog_ports(const std::vector<BasicPort>& ports);
|
||||
|
||||
std::string generate_verilog_ports(const std::vector<BasicPort>& merged_ports);
|
||||
|
||||
BasicPort generate_verilog_bus_port(const std::vector<BasicPort>& input_ports,
|
||||
const std::string& bus_port_name);
|
||||
|
||||
std::string generate_verilog_local_wire(const BasicPort& output_port,
|
||||
const std::vector<BasicPort>& input_ports);
|
||||
|
||||
std::string generate_verilog_constant_values(const std::vector<size_t>& const_values);
|
||||
|
||||
std::string generate_verilog_port_constant_values(const BasicPort& output_port,
|
||||
const std::vector<size_t>& const_values);
|
||||
|
||||
void print_verilog_wire_constant_values(std::fstream& fp,
|
||||
const BasicPort& output_port,
|
||||
const std::vector<size_t>& const_values);
|
||||
|
||||
void print_verilog_deposit_wire_constant_values(std::fstream& fp,
|
||||
const BasicPort& output_port,
|
||||
const std::vector<size_t>& const_values);
|
||||
|
||||
void print_verilog_force_wire_constant_values(std::fstream& fp,
|
||||
const BasicPort& output_port,
|
||||
const std::vector<size_t>& const_values);
|
||||
|
||||
void print_verilog_wire_connection(std::fstream& fp,
|
||||
const BasicPort& output_port,
|
||||
const BasicPort& input_port,
|
||||
const bool& inverted);
|
||||
|
||||
void print_verilog_register_connection(std::fstream& fp,
|
||||
const BasicPort& output_port,
|
||||
const BasicPort& input_port,
|
||||
const bool& inverted);
|
||||
|
||||
void print_verilog_buffer_instance(std::fstream& fp,
|
||||
ModuleManager& module_manager,
|
||||
const CircuitLibrary& circuit_lib,
|
||||
const ModuleId& parent_module_id,
|
||||
const CircuitModelId& buffer_model,
|
||||
const BasicPort& instance_input_port,
|
||||
const BasicPort& instance_output_port);
|
||||
|
||||
void print_verilog_local_sram_wires(std::fstream& fp,
|
||||
const CircuitLibrary& circuit_lib,
|
||||
const CircuitModelId& sram_model,
|
||||
const e_config_protocol_type sram_orgz_type,
|
||||
const size_t& port_size);
|
||||
|
||||
void print_verilog_local_config_bus(std::fstream& fp,
|
||||
const std::string& prefix,
|
||||
const e_config_protocol_type& sram_orgz_type,
|
||||
const size_t& instance_id,
|
||||
const size_t& num_conf_bits);
|
||||
|
||||
void print_verilog_mux_config_bus(std::fstream& fp,
|
||||
const CircuitLibrary& circuit_lib,
|
||||
const CircuitModelId& mux_model,
|
||||
const e_config_protocol_type& sram_orgz_type,
|
||||
const size_t& mux_size,
|
||||
const size_t& mux_instance_id,
|
||||
const size_t& num_reserved_conf_bits,
|
||||
const size_t& num_conf_bits);
|
||||
|
||||
void print_verilog_formal_verification_mux_sram_ports_wiring(std::fstream& fp,
|
||||
const CircuitLibrary& circuit_lib,
|
||||
const CircuitModelId& mux_model,
|
||||
const size_t& mux_size,
|
||||
const size_t& mux_instance_id,
|
||||
const size_t& num_conf_bits,
|
||||
const BasicPort& fm_config_bus);
|
||||
|
||||
void print_verilog_pulse_stimuli(std::fstream& fp,
|
||||
const BasicPort& port,
|
||||
const size_t& initial_value,
|
||||
const float& pulse_width,
|
||||
const size_t& flip_value);
|
||||
|
||||
void print_verilog_pulse_stimuli(std::fstream& fp,
|
||||
const BasicPort& port,
|
||||
const size_t& initial_value,
|
||||
const std::vector<float>& pulse_widths,
|
||||
const std::vector<size_t>& flip_values,
|
||||
const std::string& wait_condition);
|
||||
|
||||
void print_verilog_clock_stimuli(std::fstream& fp,
|
||||
const BasicPort& port,
|
||||
const size_t& initial_value,
|
||||
const float& pulse_width,
|
||||
const std::string& wait_condition);
|
||||
|
||||
void print_verilog_netlist_include_header_file(const std::vector<std::string>& netlists_to_be_included,
|
||||
const char* subckt_dir,
|
||||
const char* header_file_name);
|
||||
|
||||
} /* end namespace openfpga */
|
||||
|
||||
#endif
|
|
@ -12,6 +12,7 @@
|
|||
/* Header file from openfpga */
|
||||
#include "vpr_command.h"
|
||||
#include "openfpga_setup_command.h"
|
||||
#include "openfpga_verilog_command.h"
|
||||
#include "basic_command.h"
|
||||
|
||||
#include "openfpga_title.h"
|
||||
|
@ -52,6 +53,9 @@ int main(int argc, char** argv) {
|
|||
/* Add openfpga setup commands */
|
||||
openfpga::add_openfpga_setup_commands(shell);
|
||||
|
||||
/* Add openfpga verilog commands */
|
||||
openfpga::add_openfpga_verilog_commands(shell);
|
||||
|
||||
/* Add basic commands: exit, help, etc.
|
||||
* Note:
|
||||
* This MUST be the last command group to be added!
|
||||
|
|
|
@ -21,5 +21,9 @@ lut_truth_table_fixup #--verbose
|
|||
# - Enable pin duplication on grid modules
|
||||
build_fabric --compress_routing --duplicate_grid_pin --verbose
|
||||
|
||||
# Write the Verilog netlit for FPGA fabric
|
||||
# - Enable the use of explicit port mapping in Verilog netlist
|
||||
write_fabric_verilog --file /var/tmp/xtang/openfpga_test_src --explicit_port_mapping --include_timing --include_signal_init --support_icarus_simulator --verbose
|
||||
|
||||
# Finish and exit OpenFPGA
|
||||
exit
|
||||
|
|
Loading…
Reference in New Issue