start transplanting fpga_verilog
This commit is contained in:
parent
85627dc128
commit
622c7826d1
|
@ -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
|
||||
|
|
|
@ -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 */
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
||||
|
Loading…
Reference in New Issue