start transplanting fpga_verilog

This commit is contained in:
tangxifan 2020-02-15 15:03:00 -07:00
parent 85627dc128
commit 622c7826d1
6 changed files with 331 additions and 0 deletions

View File

@ -2,6 +2,9 @@
* This file includes functions that handles the file outputting * This file includes functions that handles the file outputting
* in OpenFPGA framework * in OpenFPGA framework
*******************************************************************/ *******************************************************************/
#include <sys/stat.h>
#include <algorithm>
/* Headers from vtrutil library */ /* Headers from vtrutil library */
#include "vtr_log.h" #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 */ } /* namespace openfpga ends */

View File

@ -17,6 +17,14 @@ bool valid_file_stream(std::fstream& fp);
void check_file_stream(const char* fname, void check_file_stream(const char* fname,
std::fstream& fp); 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 */ } /* namespace openfpga ends */
#endif #endif

View File

@ -0,0 +1,118 @@
/********************************************************************
* 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_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 fabric_verilog(ModuleManager& module_manager,
const CircuitLibrary& circuit_lib,
const MuxLibrary& mux_lib,
const DeviceGrid& grids,
const DeviceRRGSB& device_rr_gsb,
const std::string& output_directory,
const bool& compress_routing,
const bool& dump_explict_verilog,
const bool& verbose) {
vtr::ScopedStartFinishTimer timer("Generate Verilog netlists for FPGA fabric\n");
std::string src_dir_path = format_dir_path(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),
// vpr_setup.FPGA_SPICE_Opts.SynVerilogOpts);
//print_verilog_simulation_preprocessing_flags(std::string(src_dir_path),
// vpr_setup.FPGA_SPICE_Opts.SynVerilogOpts);
/* 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(verbose,
"Outputted %lu Verilog modules in total\n",
module_manager.num_modules());
}
} /* end namespace openfpga */

View File

@ -0,0 +1,36 @@
#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"
/********************************************************************
* Function declaration
*******************************************************************/
/* begin namespace openfpga */
namespace openfpga {
void fabric_verilog(ModuleManager& module_manager,
const CircuitLibrary& circuit_lib,
const MuxLibrary& mux_lib,
const DeviceGrid& grids,
const DeviceRRGSB& device_rr_gsb,
const std::string& output_directory,
const bool& compress_routing,
const bool& dump_explict_verilog,
const bool& verbose);
} /* end namespace openfpga */
#endif

View File

@ -0,0 +1,40 @@
#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_VERIFICATGION_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_SIMULATION_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* 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

View File

@ -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