adapt all the Verilog submodule writers and bring it onlien

This commit is contained in:
tangxifan 2020-02-16 13:35:18 -07:00
parent 99c3712b6f
commit c6c3ef71f3
13 changed files with 198 additions and 11 deletions

View File

@ -135,7 +135,7 @@ bool create_dir_path(const char* dir_path) {
return true;
case -1:
if (EEXIST == errno) {
VTR_LOG_ERROR("Directory '%s' already exists. Will overwrite contents\n",
VTR_LOG_WARN("Directory '%s' already exists. Will overwrite contents\n",
dir_path);
return true;
}

View File

@ -25,6 +25,10 @@ void write_fabric_verilog(OpenfpgaContext& openfpga_ctx,
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_print_user_defined_template = cmd.option("print_user_defined_template");
CommandOptionId opt_print_top_testbench = cmd.option("print_top_testbench");
CommandOptionId opt_print_formal_verification_top_netlist = cmd.option("print_formal_verification_top_netlist");
CommandOptionId opt_print_autocheck_top_testbench = cmd.option("print_autocheck_top_testbench");
CommandOptionId opt_verbose = cmd.option("verbose");
/* This is an intermediate data structure which is designed to modularize the FPGA-Verilog
@ -36,10 +40,14 @@ void write_fabric_verilog(OpenfpgaContext& openfpga_ctx,
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_print_user_defined_template(cmd_context.option_enable(cmd, opt_print_user_defined_template));
options.set_print_top_testbench(cmd_context.option_enable(cmd, opt_print_top_testbench));
options.set_print_formal_verification_top_netlist(cmd_context.option_enable(cmd, opt_print_formal_verification_top_netlist));
options.set_print_autocheck_top_testbench(cmd_context.option_value(cmd, opt_print_autocheck_top_testbench));
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(),
fpga_fabric_verilog(openfpga_ctx.mutable_module_graph(),
openfpga_ctx.arch().circuit_lib,
openfpga_ctx.mux_lib(),
g_vpr_ctx.device().grid,

View File

@ -34,6 +34,15 @@ void add_openfpga_verilog_commands(openfpga::Shell<OpenfpgaContext>& shell) {
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 '--print_user_defined_template' */
shell_cmd_write_fabric_verilog.add_option("print_user_defined_template", false, "Generate a template Verilog files for user-defined circuit models");
/* Add an option '--print_top_testbench' */
shell_cmd_write_fabric_verilog.add_option("print_top_testbench", false, "Generate a testbench for top-level fabric module");
/* Add an option '--print_formal_verification_top_netlist' */
shell_cmd_write_fabric_verilog.add_option("print_formal_verification_top_netlist", false, "Generate a top-level module which can be used in formal verification");
/* Add an option '--print_autocheck_top_testbench' */
CommandOptionId fabric_verilog_autocheck_tb_opt = shell_cmd_write_fabric_verilog.add_option("print_autocheck_top_testbench", false, "Generate a testbench for top-level fabric module with autocheck capability");
shell_cmd_write_fabric_verilog.set_option_require_value(fabric_verilog_autocheck_tb_opt, openfpga::OPT_STRING);
/* Add an option '--verbose' */
shell_cmd_write_fabric_verilog.add_option("verbose", false, "Enable verbose output");

View File

@ -15,11 +15,9 @@
#include "device_rr_gsb.h"
#include "verilog_constants.h"
#include "verilog_auxiliary_netlists.h"
//#include "verilog_submodules.h"
#include "verilog_submodule.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 */
@ -40,8 +38,13 @@ namespace openfpga {
* 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
*
* TODO: We should use module manager as a constant here.
* All the modification should be done before this writer!
* The only exception now is the user-defined modules.
* We should think clearly about how to handle them for both Verilog and SPICE generators!
********************************************************************/
void fpga_fabric_verilog(const ModuleManager& module_manager,
void fpga_fabric_verilog(ModuleManager& module_manager,
const CircuitLibrary& circuit_lib,
const MuxLibrary& mux_lib,
const DeviceGrid& grids,
@ -81,8 +84,9 @@ void fpga_fabric_verilog(const ModuleManager& module_manager,
* 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);
print_verilog_submodule(module_manager, mux_lib, circuit_lib,
src_dir_path, submodule_dir_path,
options);
/* Generate routing blocks */
//if (true == compress_routing) {

View File

@ -22,7 +22,7 @@
/* begin namespace openfpga */
namespace openfpga {
void fpga_fabric_verilog(const ModuleManager& module_manager,
void fpga_fabric_verilog(ModuleManager& module_manager,
const CircuitLibrary& circuit_lib,
const MuxLibrary& mux_lib,
const DeviceGrid& grids,

View File

@ -1240,7 +1240,7 @@ void print_verilog_submodule_muxes(ModuleManager& module_manager,
check_file_stream(verilog_fname.c_str(), fp);
/* Print out debugging information for if the file is not opened/created properly */
VTR_LOG("Writing Verilog netlist for Multiplexers '%s' ...\n",
VTR_LOG("Writing Verilog netlist for Multiplexers '%s' ...",
verilog_fname.c_str());
print_verilog_file_header(fp, "Multiplexers");

View File

@ -8,6 +8,23 @@
/* begin namespace openfpga */
namespace openfpga {
/**************************************************
* Public Constructors
*************************************************/
FabricVerilogOption::FabricVerilogOption() {
output_directory_.clear();
support_icarus_simulator_ = false;
include_signal_init_ = false;
include_timing_ = false;
explicit_port_mapping_ = false;
compress_routing_ = false;
print_top_testbench_ = false;
print_formal_verification_top_netlist_ = false;
reference_verilog_file_path_.clear();
print_user_defined_template_ = false;
verbose_output_ = false;
}
/**************************************************
* Public Accessors
*************************************************/
@ -51,6 +68,10 @@ std::string FabricVerilogOption::reference_verilog_file_path() const {
return reference_verilog_file_path_;
}
bool FabricVerilogOption::print_user_defined_template() const {
return print_user_defined_template_;
}
bool FabricVerilogOption::verbose_output() const {
return verbose_output_;
}
@ -94,6 +115,10 @@ void FabricVerilogOption::set_print_autocheck_top_testbench(const std::string& r
reference_verilog_file_path_ = reference_verilog_file_path;
}
void FabricVerilogOption::set_print_user_defined_template(const bool& enabled) {
print_user_defined_template_ = enabled;
}
void FabricVerilogOption::set_verbose_output(const bool& enabled) {
verbose_output_ = enabled;
}

View File

@ -17,6 +17,9 @@ namespace openfpga {
*
*******************************************************************/
class FabricVerilogOption {
public: /* Public constructor */
/* Set default options */
FabricVerilogOption();
public: /* Public accessors */
std::string output_directory() const;
bool support_icarus_simulator() const;
@ -28,6 +31,7 @@ class FabricVerilogOption {
bool print_formal_verification_top_netlist() const;
bool print_autocheck_top_testbench() const;
std::string reference_verilog_file_path() const;
bool print_user_defined_template() const;
bool verbose_output() const;
public: /* Public mutators */
void set_output_directory(const std::string& output_dir);
@ -39,6 +43,7 @@ class FabricVerilogOption {
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_print_user_defined_template(const bool& enabled);
void set_verbose_output(const bool& enabled);
private: /* Internal Data */
std::string output_directory_;
@ -51,6 +56,7 @@ class FabricVerilogOption {
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 print_user_defined_template_;
bool verbose_output_;
};

View File

@ -0,0 +1,96 @@
/*********************************************************************
* This file includes top-level function to generate Verilog primitive modules
* and print them to files
********************************************************************/
/* Headers from vtrutil library */
#include "vtr_assert.h"
#include "vtr_log.h"
#include "verilog_submodule_utils.h"
#include "verilog_essential_gates.h"
#include "verilog_decoders.h"
#include "verilog_mux.h"
#include "verilog_lut.h"
#include "verilog_wire.h"
#include "verilog_memory.h"
#include "verilog_writer_utils.h"
#include "verilog_constants.h"
#include "verilog_submodule.h"
/* begin namespace openfpga */
namespace openfpga {
/*********************************************************************
* Top-level function to generate primitive modules:
* 1. Logic gates: AND/OR, inverter, buffer and transmission-gate/pass-transistor
* 2. Routing multiplexers
* 3. Local encoders for routing multiplexers
* 4. Wires
* 5. Configuration memory blocks
* 6. Verilog template
********************************************************************/
void print_verilog_submodule(ModuleManager& module_manager,
const MuxLibrary& mux_lib,
const CircuitLibrary& circuit_lib,
const std::string& verilog_dir,
const std::string& submodule_dir,
const FabricVerilogOption& fpga_verilog_opts) {
/* Register all the user-defined modules in the module manager
* This should be done prior to other steps in this function,
* because they will be instanciated by other primitive modules
*/
add_user_defined_verilog_modules(module_manager, circuit_lib);
/* Create a vector to contain all the Verilog netlist names that have been generated in this function */
std::vector<std::string> netlist_names;
print_verilog_submodule_essentials(module_manager,
netlist_names,
verilog_dir,
submodule_dir,
circuit_lib);
/* Routing multiplexers */
/* NOTE: local decoders generation must go before the MUX generation!!!
* because local decoders modules will be instanciated in the MUX modules
*/
print_verilog_submodule_mux_local_decoders(module_manager, netlist_names,
mux_lib, circuit_lib,
verilog_dir, submodule_dir);
print_verilog_submodule_muxes(module_manager, netlist_names, mux_lib, circuit_lib,
verilog_dir, submodule_dir,
fpga_verilog_opts.explicit_port_mapping());
/* LUTes */
print_verilog_submodule_luts(module_manager, netlist_names, circuit_lib,
verilog_dir, submodule_dir,
fpga_verilog_opts.explicit_port_mapping());
/* Hard wires */
print_verilog_submodule_wires(module_manager, netlist_names, circuit_lib,
verilog_dir, submodule_dir);
/* 4. Memories */
print_verilog_submodule_memories(module_manager, netlist_names,
mux_lib, circuit_lib,
verilog_dir, submodule_dir,
fpga_verilog_opts.explicit_port_mapping());
/* 5. Dump template for all the modules */
if (true == fpga_verilog_opts.print_user_defined_template()) {
print_verilog_submodule_templates(module_manager, circuit_lib,
verilog_dir, submodule_dir);
}
/* Create a header file to include all the subckts */
print_verilog_netlist_include_header_file(netlist_names,
submodule_dir.c_str(),
SUBMODULE_VERILOG_FILE_NAME);
}
} /* end namespace openfpga */

View File

@ -0,0 +1,27 @@
#ifndef VERILOG_SUBMODULE_H
#define VERILOG_SUBMODULE_H
/********************************************************************
* Include header files that are required by function declaration
*******************************************************************/
#include "module_manager.h"
#include "mux_library.h"
#include "verilog_options.h"
/********************************************************************
* Function declaration
*******************************************************************/
/* begin namespace openfpga */
namespace openfpga {
void print_verilog_submodule(ModuleManager& module_manager,
const MuxLibrary& mux_lib,
const CircuitLibrary& circuit_lib,
const std::string& verilog_dir,
const std::string& submodule_dir,
const FabricVerilogOption& fpga_verilog_opts);
} /* end namespace openfpga */
#endif

View File

@ -132,6 +132,8 @@ void print_verilog_submodule_signal_init(std::fstream& fp,
********************************************************************/
void add_user_defined_verilog_modules(ModuleManager& module_manager,
const CircuitLibrary& circuit_lib) {
VTR_LOG("Registering user-defined modules...");
/* Iterate over Verilog modules */
for (const auto& model : circuit_lib.models()) {
/* We only care about user-defined models */
@ -149,8 +151,12 @@ void add_user_defined_verilog_modules(ModuleManager& module_manager,
ModuleId module_id = module_manager.find_module(circuit_lib.model_name(model));
if (ModuleId::INVALID() == module_id) {
add_circuit_model_to_module_manager(module_manager, circuit_lib, model);
VTR_LOG("Registered user-defined circuit model '%s'\n",
circuit_lib.model_name(model).c_str());
}
}
VTR_LOG("Done\n");
}
/*********************************************************************

View File

@ -1374,8 +1374,12 @@ void print_verilog_clock_stimuli(std::fstream& fp,
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) {
std::string verilog_fname(std::string(subckt_dir) + std::string(header_file_name));
VTR_LOG("Writing header file for primitive modules '%s' ...",
verilog_fname.c_str());
/* Create the file stream */
std::fstream fp;
fp.open(verilog_fname, std::fstream::out | std::fstream::trunc);
@ -1392,6 +1396,8 @@ void print_verilog_netlist_include_header_file(const std::vector<std::string>& n
/* close file stream */
fp.close();
VTR_LOG("Done\n");
}
} /* end namespace openfpga */

View File

@ -23,7 +23,7 @@ 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
write_fabric_verilog --file /var/tmp/xtang/openfpga_test_src --explicit_port_mapping --include_timing --include_signal_init --support_icarus_simulator --print_user_defined_template --verbose
# Finish and exit OpenFPGA
exit