diff --git a/openfpga/src/base/openfpga_verilog.cpp b/openfpga/src/base/openfpga_verilog.cpp index 99075aa19..ad92228f1 100644 --- a/openfpga/src/base/openfpga_verilog.cpp +++ b/openfpga/src/base/openfpga_verilog.cpp @@ -30,6 +30,7 @@ int write_fabric_verilog(OpenfpgaContext& openfpga_ctx, CommandOptionId opt_explicit_port_mapping = cmd.option("explicit_port_mapping"); CommandOptionId opt_include_timing = cmd.option("include_timing"); CommandOptionId opt_print_user_defined_template = cmd.option("print_user_defined_template"); + CommandOptionId opt_default_net_type = cmd.option("default_net_type"); CommandOptionId opt_verbose = cmd.option("verbose"); /* This is an intermediate data structure which is designed to modularize the FPGA-Verilog @@ -40,6 +41,9 @@ int write_fabric_verilog(OpenfpgaContext& openfpga_ctx, 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_print_user_defined_template(cmd_context.option_enable(cmd, opt_print_user_defined_template)); + if (true == cmd_context.option_enable(cmd, opt_default_net_type)) { + options.set_default_net_type(cmd_context.option_value(cmd, opt_default_net_type)); + } options.set_verbose_output(cmd_context.option_enable(cmd, opt_verbose)); options.set_compress_routing(openfpga_ctx.flow_manager().compress_routing()); diff --git a/openfpga/src/base/openfpga_verilog_command.cpp b/openfpga/src/base/openfpga_verilog_command.cpp index aa4da293d..946f0e2bf 100644 --- a/openfpga/src/base/openfpga_verilog_command.cpp +++ b/openfpga/src/base/openfpga_verilog_command.cpp @@ -36,6 +36,10 @@ ShellCommandId add_openfpga_write_fabric_verilog_command(openfpga::Shell +#include "verilog_port_types.h" /* Begin namespace openfpga */ namespace openfpga { @@ -21,6 +22,7 @@ class FabricVerilogOption { bool include_timing() const; bool explicit_port_mapping() const; bool compress_routing() const; + e_verilog_default_net_type default_net_type() const; bool print_user_defined_template() const; bool verbose_output() const; public: /* Public mutators */ @@ -29,6 +31,7 @@ class FabricVerilogOption { void set_explicit_port_mapping(const bool& enabled); void set_compress_routing(const bool& enabled); void set_print_user_defined_template(const bool& enabled); + void set_default_net_type(const std::string& default_net_type); void set_verbose_output(const bool& enabled); private: /* Internal Data */ std::string output_directory_; @@ -36,6 +39,7 @@ class FabricVerilogOption { bool explicit_port_mapping_; bool compress_routing_; bool print_user_defined_template_; + e_verilog_default_net_type default_net_type_; bool verbose_output_; }; diff --git a/openfpga/src/fpga_verilog/verilog_api.cpp b/openfpga/src/fpga_verilog/verilog_api.cpp index 23abbc3ea..424f85c42 100644 --- a/openfpga/src/fpga_verilog/verilog_api.cpp +++ b/openfpga/src/fpga_verilog/verilog_api.cpp @@ -88,12 +88,12 @@ void fpga_fabric_verilog(ModuleManager &module_manager, 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!!! - */ + * 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_submodule(module_manager, netlist_manager, mux_lib, decoder_lib, circuit_lib, submodule_dir_path, @@ -105,14 +105,14 @@ void fpga_fabric_verilog(ModuleManager &module_manager, const_cast(module_manager), device_rr_gsb, rr_dir_path, - options.explicit_port_mapping()); + options); } else { VTR_ASSERT(false == options.compress_routing()); print_verilog_flatten_routing_modules(netlist_manager, const_cast(module_manager), device_rr_gsb, rr_dir_path, - options.explicit_port_mapping()); + options); } /* Generate grids */ @@ -120,14 +120,14 @@ void fpga_fabric_verilog(ModuleManager &module_manager, const_cast(module_manager), device_ctx, device_annotation, lb_dir_path, - options.explicit_port_mapping(), + options, options.verbose_output()); /* Generate FPGA fabric */ print_verilog_top_module(netlist_manager, const_cast(module_manager), src_dir_path, - options.explicit_port_mapping()); + options); /* Generate an netlist including all the fabric-related netlists */ print_verilog_fabric_include_netlist(const_cast(netlist_manager), diff --git a/openfpga/src/fpga_verilog/verilog_decoders.cpp b/openfpga/src/fpga_verilog/verilog_decoders.cpp index 5804a918e..6960ba19e 100644 --- a/openfpga/src/fpga_verilog/verilog_decoders.cpp +++ b/openfpga/src/fpga_verilog/verilog_decoders.cpp @@ -46,7 +46,8 @@ static void print_verilog_mux_local_decoder_module(std::fstream& fp, const ModuleManager& module_manager, const DecoderLibrary& decoder_lib, - const DecoderId& decoder) { + const DecoderId& decoder, + const e_verilog_default_net_type& default_net_type) { /* Get the number of inputs */ size_t addr_size = decoder_lib.addr_size(decoder); size_t data_size = decoder_lib.data_size(decoder); @@ -73,7 +74,7 @@ void print_verilog_mux_local_decoder_module(std::fstream& fp, VTR_ASSERT(true == decoder_lib.use_data_inv_port(decoder)); /* dump module definition + ports */ - print_verilog_module_declaration(fp, module_manager, module_id); + print_verilog_module_declaration(fp, module_manager, module_id, default_net_type); /* Finish dumping ports */ print_verilog_comment(fp, std::string("----- BEGIN Verilog codes for Decoder convert " + std::to_string(addr_size) + "-bit addr to " + std::to_string(data_size) + "-bit data -----")); @@ -164,7 +165,8 @@ void print_verilog_submodule_mux_local_decoders(const ModuleManager& module_mana NetlistManager& netlist_manager, const MuxLibrary& mux_lib, const CircuitLibrary& circuit_lib, - const std::string& submodule_dir) { + const std::string& submodule_dir, + const e_verilog_default_net_type& default_net_type) { std::string verilog_fname(submodule_dir + std::string(LOCAL_ENCODER_VERILOG_FILE_NAME)); /* Create the file stream */ @@ -212,7 +214,7 @@ void print_verilog_submodule_mux_local_decoders(const ModuleManager& module_mana /* Generate Verilog modules for the found unique local encoders */ for (const auto& decoder : decoder_lib.decoders()) { - print_verilog_mux_local_decoder_module(fp, module_manager, decoder_lib, decoder); + print_verilog_mux_local_decoder_module(fp, module_manager, decoder_lib, decoder, default_net_type); } /* Close the file stream */ @@ -253,7 +255,8 @@ static void print_verilog_arch_decoder_module(std::fstream& fp, const ModuleManager& module_manager, const DecoderLibrary& decoder_lib, - const DecoderId& decoder) { + const DecoderId& decoder, + const e_verilog_default_net_type& default_net_type) { /* Get the number of inputs */ size_t addr_size = decoder_lib.addr_size(decoder); size_t data_size = decoder_lib.data_size(decoder); @@ -287,7 +290,7 @@ void print_verilog_arch_decoder_module(std::fstream& fp, } /* dump module definition + ports */ - print_verilog_module_declaration(fp, module_manager, module_id); + print_verilog_module_declaration(fp, module_manager, module_id, default_net_type); /* Finish dumping ports */ print_verilog_comment(fp, std::string("----- BEGIN Verilog codes for Decoder convert " + std::to_string(addr_size) + "-bit addr to " + std::to_string(data_size) + "-bit data -----")); @@ -406,7 +409,8 @@ static void print_verilog_arch_decoder_with_data_in_module(std::fstream& fp, const ModuleManager& module_manager, const DecoderLibrary& decoder_lib, - const DecoderId& decoder) { + const DecoderId& decoder, + const e_verilog_default_net_type& default_net_type) { /* Get the number of inputs */ size_t addr_size = decoder_lib.addr_size(decoder); size_t data_size = decoder_lib.data_size(decoder); @@ -444,7 +448,7 @@ void print_verilog_arch_decoder_with_data_in_module(std::fstream& fp, } /* dump module definition + ports */ - print_verilog_module_declaration(fp, module_manager, module_id); + print_verilog_module_declaration(fp, module_manager, module_id, default_net_type); /* Finish dumping ports */ print_verilog_comment(fp, std::string("----- BEGIN Verilog codes for Decoder convert " + std::to_string(addr_size) + "-bit addr to " + std::to_string(data_size) + "-bit data -----")); @@ -548,7 +552,8 @@ void print_verilog_arch_decoder_with_data_in_module(std::fstream& fp, void print_verilog_submodule_arch_decoders(const ModuleManager& module_manager, NetlistManager& netlist_manager, const DecoderLibrary& decoder_lib, - const std::string& submodule_dir) { + const std::string& submodule_dir, + const e_verilog_default_net_type& default_net_type) { std::string verilog_fname(submodule_dir + std::string(ARCH_ENCODER_VERILOG_FILE_NAME)); /* Create the file stream */ @@ -566,9 +571,9 @@ void print_verilog_submodule_arch_decoders(const ModuleManager& module_manager, /* Generate Verilog modules for the found unique local encoders */ for (const auto& decoder : decoder_lib.decoders()) { if (true == decoder_lib.use_data_in(decoder)) { - print_verilog_arch_decoder_with_data_in_module(fp, module_manager, decoder_lib, decoder); + print_verilog_arch_decoder_with_data_in_module(fp, module_manager, decoder_lib, decoder, default_net_type); } else { - print_verilog_arch_decoder_module(fp, module_manager, decoder_lib, decoder); + print_verilog_arch_decoder_module(fp, module_manager, decoder_lib, decoder, default_net_type); } } @@ -583,5 +588,4 @@ void print_verilog_submodule_arch_decoders(const ModuleManager& module_manager, VTR_LOG("Done\n"); } - } /* end namespace openfpga */ diff --git a/openfpga/src/fpga_verilog/verilog_decoders.h b/openfpga/src/fpga_verilog/verilog_decoders.h index e15d5299a..999b1c1bb 100644 --- a/openfpga/src/fpga_verilog/verilog_decoders.h +++ b/openfpga/src/fpga_verilog/verilog_decoders.h @@ -14,6 +14,7 @@ #include "decoder_library.h" #include "module_manager.h" #include "netlist_manager.h" +#include "verilog_port_types.h" /******************************************************************** * Function declaration @@ -26,12 +27,14 @@ void print_verilog_submodule_mux_local_decoders(const ModuleManager& module_mana NetlistManager& netlist_manager, const MuxLibrary& mux_lib, const CircuitLibrary& circuit_lib, - const std::string& submodule_dir); + const std::string& submodule_dir, + const e_verilog_default_net_type& default_net_type); void print_verilog_submodule_arch_decoders(const ModuleManager& module_manager, NetlistManager& netlist_manager, const DecoderLibrary& decoder_lib, - const std::string& submodule_dir); + const std::string& submodule_dir, + const e_verilog_default_net_type& default_net_type); } /* end namespace openfpga */ diff --git a/openfpga/src/fpga_verilog/verilog_essential_gates.cpp b/openfpga/src/fpga_verilog/verilog_essential_gates.cpp index 9b4a356f4..f382a5308 100644 --- a/openfpga/src/fpga_verilog/verilog_essential_gates.cpp +++ b/openfpga/src/fpga_verilog/verilog_essential_gates.cpp @@ -150,7 +150,8 @@ static void print_verilog_invbuf_module(const ModuleManager& module_manager, std::fstream& fp, const CircuitLibrary& circuit_lib, - const CircuitModelId& circuit_model) { + const CircuitModelId& circuit_model, + const e_verilog_default_net_type& default_net_type) { /* Ensure a valid file handler*/ VTR_ASSERT(true == valid_file_stream(fp)); @@ -171,7 +172,7 @@ void print_verilog_invbuf_module(const ModuleManager& module_manager, VTR_ASSERT(true == module_manager.valid_module_id(module_id)); /* dump module definition + ports */ - print_verilog_module_declaration(fp, module_manager, module_id); + print_verilog_module_declaration(fp, module_manager, module_id, default_net_type); /* Finish dumping ports */ /* Assign logics : depending on topology */ @@ -207,7 +208,8 @@ static void print_verilog_passgate_module(const ModuleManager& module_manager, std::fstream& fp, const CircuitLibrary& circuit_lib, - const CircuitModelId& circuit_model) { + const CircuitModelId& circuit_model, + const e_verilog_default_net_type& default_net_type) { /* Ensure a valid file handler*/ VTR_ASSERT(true == valid_file_stream(fp)); @@ -255,7 +257,7 @@ void print_verilog_passgate_module(const ModuleManager& module_manager, VTR_ASSERT(true == module_manager.valid_module_id(module_id)); /* dump module definition + ports */ - print_verilog_module_declaration(fp, module_manager, module_id); + print_verilog_module_declaration(fp, module_manager, module_id, default_net_type); /* Finish dumping ports */ /* Dump logics: we propagate input to the output when the gate is '1' @@ -416,7 +418,8 @@ static void print_verilog_gate_module(const ModuleManager& module_manager, std::fstream& fp, const CircuitLibrary& circuit_lib, - const CircuitModelId& circuit_model) { + const CircuitModelId& circuit_model, + const e_verilog_default_net_type& default_net_type) { /* Ensure a valid file handler*/ VTR_ASSERT(true == valid_file_stream(fp)); @@ -436,7 +439,7 @@ void print_verilog_gate_module(const ModuleManager& module_manager, VTR_ASSERT(true == module_manager.valid_module_id(module_id)); /* dump module definition + ports */ - print_verilog_module_declaration(fp, module_manager, module_id); + print_verilog_module_declaration(fp, module_manager, module_id, default_net_type); /* Finish dumping ports */ /* Dump logics */ @@ -469,7 +472,8 @@ void print_verilog_gate_module(const ModuleManager& module_manager, static void print_verilog_constant_generator_module(const ModuleManager& module_manager, std::fstream& fp, - const size_t& const_value) { + const size_t& const_value, + const e_verilog_default_net_type& default_net_type) { /* Find the module in module manager */ std::string module_name = generate_const_value_module_name(const_value); ModuleId const_val_module = module_manager.find_module(module_name); @@ -479,7 +483,7 @@ void print_verilog_constant_generator_module(const ModuleManager& module_manager VTR_ASSERT(true == valid_file_stream(fp)); /* dump module definition + ports */ - print_verilog_module_declaration(fp, module_manager, const_val_module); + print_verilog_module_declaration(fp, module_manager, const_val_module, default_net_type); /* Finish dumping ports */ /* Find the only output*/ @@ -500,7 +504,8 @@ void print_verilog_constant_generator_module(const ModuleManager& module_manager void print_verilog_submodule_essentials(const ModuleManager& module_manager, NetlistManager& netlist_manager, const std::string& submodule_dir, - const CircuitLibrary& circuit_lib) { + const CircuitLibrary& circuit_lib, + const e_verilog_default_net_type& default_net_type) { /* TODO: remove .bak when this part is completed and tested */ std::string verilog_fname = submodule_dir + std::string(ESSENTIALS_VERILOG_FILE_NAME); @@ -515,13 +520,13 @@ void print_verilog_submodule_essentials(const ModuleManager& module_manager, VTR_LOG("Generating Verilog netlist '%s' for essential gates...", verilog_fname.c_str()); - print_verilog_file_header(fp, "Essential gates"); + print_verilog_file_header(fp, "Essential gates"); /* Print constant generators */ /* VDD */ - print_verilog_constant_generator_module(module_manager, fp, 0); + print_verilog_constant_generator_module(module_manager, fp, 0, default_net_type); /* GND */ - print_verilog_constant_generator_module(module_manager, fp, 1); + print_verilog_constant_generator_module(module_manager, fp, 1, default_net_type); for (const auto& circuit_model : circuit_lib.models()) { /* By pass user-defined modules */ @@ -529,19 +534,19 @@ void print_verilog_submodule_essentials(const ModuleManager& module_manager, continue; } if (CIRCUIT_MODEL_INVBUF == circuit_lib.model_type(circuit_model)) { - print_verilog_invbuf_module(module_manager, fp, circuit_lib, circuit_model); + print_verilog_invbuf_module(module_manager, fp, circuit_lib, circuit_model, default_net_type); continue; } if (CIRCUIT_MODEL_PASSGATE == circuit_lib.model_type(circuit_model)) { - print_verilog_passgate_module(module_manager, fp, circuit_lib, circuit_model); + print_verilog_passgate_module(module_manager, fp, circuit_lib, circuit_model, default_net_type); continue; } if (CIRCUIT_MODEL_GATE == circuit_lib.model_type(circuit_model)) { - print_verilog_gate_module(module_manager, fp, circuit_lib, circuit_model); + print_verilog_gate_module(module_manager, fp, circuit_lib, circuit_model, default_net_type); continue; } } - + /* Close file handler*/ fp.close(); diff --git a/openfpga/src/fpga_verilog/verilog_essential_gates.h b/openfpga/src/fpga_verilog/verilog_essential_gates.h index 2510e6d3d..3828a9f7e 100644 --- a/openfpga/src/fpga_verilog/verilog_essential_gates.h +++ b/openfpga/src/fpga_verilog/verilog_essential_gates.h @@ -8,6 +8,7 @@ #include "circuit_library.h" #include "module_manager.h" #include "netlist_manager.h" +#include "verilog_port_types.h" /******************************************************************** * Function declaration @@ -19,7 +20,8 @@ namespace openfpga { void print_verilog_submodule_essentials(const ModuleManager& module_manager, NetlistManager& netlist_manager, const std::string& submodule_dir, - const CircuitLibrary& circuit_lib); + const CircuitLibrary& circuit_lib, + const e_verilog_default_net_type& default_net_type); } /* end namespace openfpga */ diff --git a/openfpga/src/fpga_verilog/verilog_grid.cpp b/openfpga/src/fpga_verilog/verilog_grid.cpp index ff7f7433e..06af5aac0 100644 --- a/openfpga/src/fpga_verilog/verilog_grid.cpp +++ b/openfpga/src/fpga_verilog/verilog_grid.cpp @@ -61,13 +61,16 @@ namespace openfpga { * | | * +---------------------------------------+ * + * Note that the primitive may be mapped to a standard cell, we force to use + * explict port mapping. This aims to avoid any port sequence issues!!! + * *******************************************************************/ static void print_verilog_primitive_block(NetlistManager& netlist_manager, const ModuleManager& module_manager, const std::string& subckt_dir, t_pb_graph_node* primitive_pb_graph_node, - const bool& use_explicit_mapping, + const FabricVerilogOption& options, const bool& verbose) { /* Ensure a valid pb_graph_node */ if (nullptr == primitive_pb_graph_node) { @@ -107,7 +110,11 @@ void print_verilog_primitive_block(NetlistManager& netlist_manager, module_manager.module_name(primitive_module).c_str()); /* Write the verilog module */ - write_verilog_module_to_file(fp, module_manager, primitive_module, use_explicit_mapping); + write_verilog_module_to_file(fp, + module_manager, + primitive_module, + true, + options.default_net_type()); /* Close file handler */ fp.close(); @@ -141,7 +148,7 @@ void rec_print_verilog_logical_tile(NetlistManager& netlist_manager, const VprDeviceAnnotation& device_annotation, const std::string& subckt_dir, t_pb_graph_node* physical_pb_graph_node, - const bool& use_explicit_mapping, + const FabricVerilogOption& options, const bool& verbose) { /* Check cur_pb_graph_node*/ @@ -167,21 +174,18 @@ void rec_print_verilog_logical_tile(NetlistManager& netlist_manager, module_manager, device_annotation, subckt_dir, &(physical_pb_graph_node->child_pb_graph_nodes[physical_mode->index][ipb][0]), - use_explicit_mapping, + options, verbose); } } - /* For leaf node, a primitive Verilog module will be generated. - * Note that the primitive may be mapped to a standard cell, we force to use - * explict port mapping. This aims to avoid any port sequence issues!!! - */ + /* For leaf node, a primitive Verilog module will be generated. */ if (true == is_primitive_pb_type(physical_pb_type)) { print_verilog_primitive_block(netlist_manager, module_manager, subckt_dir, physical_pb_graph_node, - true, + options, verbose); /* Finish for primitive node, return */ return; @@ -220,7 +224,11 @@ void rec_print_verilog_logical_tile(NetlistManager& netlist_manager, print_verilog_comment(fp, std::string("----- BEGIN Physical programmable logic block Verilog module: " + std::string(physical_pb_type->name) + " -----")); /* Write the verilog module */ - write_verilog_module_to_file(fp, module_manager, pb_module, use_explicit_mapping); + write_verilog_module_to_file(fp, + module_manager, + pb_module, + options.explicit_port_mapping(), + options.default_net_type()); print_verilog_comment(fp, std::string("----- END Physical programmable logic block Verilog module: " + std::string(physical_pb_type->name) + " -----")); @@ -245,7 +253,7 @@ void print_verilog_logical_tile_netlist(NetlistManager& netlist_manager, const VprDeviceAnnotation& device_annotation, const std::string& subckt_dir, t_pb_graph_node* pb_graph_head, - const bool& use_explicit_mapping, + const FabricVerilogOption& options, const bool& verbose) { VTR_LOG("Writing Verilog netlists for logic tile '%s' ...", @@ -264,7 +272,7 @@ void print_verilog_logical_tile_netlist(NetlistManager& netlist_manager, device_annotation, subckt_dir, pb_graph_head, - use_explicit_mapping, + options, verbose); VTR_LOG("Done\n"); @@ -285,7 +293,7 @@ void print_verilog_physical_tile_netlist(NetlistManager& netlist_manager, const std::string& subckt_dir, t_physical_tile_type_ptr phy_block_type, const e_side& border_side, - const bool& use_explicit_mapping) { + const FabricVerilogOption& options) { /* Give a name to the Verilog netlist */ /* Create the file name for Verilog */ std::string verilog_fname(subckt_dir @@ -321,7 +329,11 @@ void print_verilog_physical_tile_netlist(NetlistManager& netlist_manager, /* Write the verilog module */ print_verilog_comment(fp, std::string("----- BEGIN Grid Verilog module: " + module_manager.module_name(grid_module) + " -----")); - write_verilog_module_to_file(fp, module_manager, grid_module, use_explicit_mapping); + write_verilog_module_to_file(fp, + module_manager, + grid_module, + options.explicit_port_mapping(), + options.default_net_type()); print_verilog_comment(fp, std::string("----- END Grid Verilog module: " + module_manager.module_name(grid_module) + " -----")); @@ -350,7 +362,7 @@ void print_verilog_grids(NetlistManager& netlist_manager, const DeviceContext& device_ctx, const VprDeviceAnnotation& device_annotation, const std::string& subckt_dir, - const bool& use_explicit_mapping, + const FabricVerilogOption& options, const bool& verbose) { /* Create a vector to contain all the Verilog netlist names that have been generated in this function */ std::vector netlist_names; @@ -374,7 +386,7 @@ void print_verilog_grids(NetlistManager& netlist_manager, device_annotation, subckt_dir, logical_tile.pb_graph_head, - use_explicit_mapping, + options, verbose); } VTR_LOG("Writing logical tiles..."); @@ -408,7 +420,7 @@ void print_verilog_grids(NetlistManager& netlist_manager, subckt_dir, &physical_tile, io_type_side, - use_explicit_mapping); + options); } continue; } else { @@ -418,7 +430,7 @@ void print_verilog_grids(NetlistManager& netlist_manager, subckt_dir, &physical_tile, NUM_SIDES, - use_explicit_mapping); + options); } } VTR_LOG("Building physical tiles..."); diff --git a/openfpga/src/fpga_verilog/verilog_grid.h b/openfpga/src/fpga_verilog/verilog_grid.h index 7603bd298..0449aec31 100644 --- a/openfpga/src/fpga_verilog/verilog_grid.h +++ b/openfpga/src/fpga_verilog/verilog_grid.h @@ -9,6 +9,7 @@ #include "module_manager.h" #include "netlist_manager.h" #include "vpr_device_annotation.h" +#include "fabric_verilog_options.h" /******************************************************************** * Function declaration @@ -22,7 +23,7 @@ void print_verilog_grids(NetlistManager& netlist_manager, const DeviceContext& device_ctx, const VprDeviceAnnotation& device_annotation, const std::string& subckt_dir, - const bool& use_explicit_mapping, + const FabricVerilogOption& options, const bool& verbose); diff --git a/openfpga/src/fpga_verilog/verilog_lut.cpp b/openfpga/src/fpga_verilog/verilog_lut.cpp index 34767aff7..806376cde 100644 --- a/openfpga/src/fpga_verilog/verilog_lut.cpp +++ b/openfpga/src/fpga_verilog/verilog_lut.cpp @@ -33,7 +33,7 @@ void print_verilog_submodule_luts(const ModuleManager& module_manager, NetlistManager& netlist_manager, const CircuitLibrary& circuit_lib, const std::string& submodule_dir, - const bool& use_explicit_port_map) { + const FabricVerilogOption& options) { std::string verilog_fname = submodule_dir + std::string(LUTS_VERILOG_FILE_NAME); std::fstream fp; @@ -60,7 +60,8 @@ void print_verilog_submodule_luts(const ModuleManager& module_manager, ModuleId lut_module = module_manager.find_module(circuit_lib.model_name(lut_model)); VTR_ASSERT(true == module_manager.valid_module_id(lut_module)); write_verilog_module_to_file(fp, module_manager, lut_module, - use_explicit_port_map || circuit_lib.dump_explicit_port_map(lut_model)); + options.explicit_port_mapping() || circuit_lib.dump_explicit_port_map(lut_model), + options.default_net_type()); } /* Close the file handler */ diff --git a/openfpga/src/fpga_verilog/verilog_lut.h b/openfpga/src/fpga_verilog/verilog_lut.h index a102e6df0..4347ef78f 100644 --- a/openfpga/src/fpga_verilog/verilog_lut.h +++ b/openfpga/src/fpga_verilog/verilog_lut.h @@ -10,6 +10,7 @@ #include "circuit_library.h" #include "module_manager.h" #include "netlist_manager.h" +#include "fabric_verilog_options.h" /******************************************************************** * Function declaration @@ -22,7 +23,7 @@ void print_verilog_submodule_luts(const ModuleManager& module_manager, NetlistManager& netlist_manager, const CircuitLibrary& circuit_lib, const std::string& submodule_dir, - const bool& use_explicit_port_map); + const FabricVerilogOption& options); } /* end namespace openfpga */ diff --git a/openfpga/src/fpga_verilog/verilog_memory.cpp b/openfpga/src/fpga_verilog/verilog_memory.cpp index ad30eb337..dfb9f487a 100644 --- a/openfpga/src/fpga_verilog/verilog_memory.cpp +++ b/openfpga/src/fpga_verilog/verilog_memory.cpp @@ -47,7 +47,7 @@ void print_verilog_mux_memory_module(const ModuleManager& module_manager, std::fstream& fp, const CircuitModelId& mux_model, const MuxGraph& mux_graph, - const bool& use_explicit_port_map) { + const FabricVerilogOption& options) { /* Multiplexers built with different technology is in different organization */ switch (circuit_lib.design_tech_type(mux_model)) { case CIRCUIT_MODEL_DESIGN_CMOS: { @@ -59,7 +59,8 @@ void print_verilog_mux_memory_module(const ModuleManager& module_manager, VTR_ASSERT(true == module_manager.valid_module_id(mem_module)); /* Write the module content in Verilog format */ write_verilog_module_to_file(fp, module_manager, mem_module, - use_explicit_port_map || circuit_lib.dump_explicit_port_map(mux_model)); + options.explicit_port_mapping() || circuit_lib.dump_explicit_port_map(mux_model), + options.default_net_type()); /* Add an empty line as a splitter */ fp << std::endl; @@ -101,7 +102,7 @@ void print_verilog_submodule_memories(const ModuleManager& module_manager, const MuxLibrary& mux_lib, const CircuitLibrary& circuit_lib, const std::string& submodule_dir, - const bool& use_explicit_port_map) { + const FabricVerilogOption& options) { /* Plug in with the mux subckt */ std::string verilog_fname(submodule_dir + std::string(MEMORIES_VERILOG_FILE_NAME)); @@ -129,7 +130,12 @@ void print_verilog_submodule_memories(const ModuleManager& module_manager, continue; } /* Create a Verilog module for the memories used by the multiplexer */ - print_verilog_mux_memory_module(module_manager, circuit_lib, fp, mux_model, mux_graph, use_explicit_port_map); + print_verilog_mux_memory_module(module_manager, + circuit_lib, + fp, + mux_model, + mux_graph, + options); } /* Create the memory circuits for non-MUX circuit models. @@ -174,7 +180,8 @@ void print_verilog_submodule_memories(const ModuleManager& module_manager, VTR_ASSERT(true == module_manager.valid_module_id(mem_module)); /* Write the module content in Verilog format */ write_verilog_module_to_file(fp, module_manager, mem_module, - use_explicit_port_map || circuit_lib.dump_explicit_port_map(model)); + options.explicit_port_mapping() || circuit_lib.dump_explicit_port_map(model), + options.default_net_type()); /* Add an empty line as a splitter */ fp << std::endl; diff --git a/openfpga/src/fpga_verilog/verilog_memory.h b/openfpga/src/fpga_verilog/verilog_memory.h index f489df2ad..2a5136005 100644 --- a/openfpga/src/fpga_verilog/verilog_memory.h +++ b/openfpga/src/fpga_verilog/verilog_memory.h @@ -11,6 +11,7 @@ #include "mux_library.h" #include "module_manager.h" #include "netlist_manager.h" +#include "fabric_verilog_options.h" /******************************************************************** * Function declaration @@ -24,7 +25,7 @@ void print_verilog_submodule_memories(const ModuleManager& module_manager, const MuxLibrary& mux_lib, const CircuitLibrary& circuit_lib, const std::string& submodule_dir, - const bool& use_explicit_port_map); + const FabricVerilogOption& options); } /* end namespace openfpga */ diff --git a/openfpga/src/fpga_verilog/verilog_module_writer.cpp b/openfpga/src/fpga_verilog/verilog_module_writer.cpp index 08e1b3adb..78d89c69e 100644 --- a/openfpga/src/fpga_verilog/verilog_module_writer.cpp +++ b/openfpga/src/fpga_verilog/verilog_module_writer.cpp @@ -464,7 +464,8 @@ void write_verilog_instance_to_file(std::fstream& fp, void write_verilog_module_to_file(std::fstream& fp, const ModuleManager& module_manager, const ModuleId& module_id, - const bool& use_explicit_port_map) { + const bool& use_explicit_port_map, + const e_verilog_default_net_type& default_net_type) { VTR_ASSERT(true == valid_file_stream(fp)); @@ -472,16 +473,18 @@ void write_verilog_module_to_file(std::fstream& fp, VTR_ASSERT(module_manager.valid_module_id(module_id)); /* Print module declaration */ - print_verilog_module_declaration(fp, module_manager, module_id); + print_verilog_module_declaration(fp, module_manager, module_id, default_net_type); /* Print an empty line as splitter */ fp << std::endl; - /* Print internal wires */ - std::map> local_wires = find_verilog_module_local_wires(module_manager, module_id); - for (std::pair> port_group : local_wires) { - for (const BasicPort& local_wire : port_group.second) { - fp << generate_verilog_port(VERILOG_PORT_WIRE, local_wire) << ";" << std::endl; + /* Print internal wires only when default net type is NOT wire */ + if (VERILOG_DEFAULT_NET_TYPE_WIRE != default_net_type) { + std::map> local_wires = find_verilog_module_local_wires(module_manager, module_id); + for (std::pair> port_group : local_wires) { + for (const BasicPort& local_wire : port_group.second) { + fp << generate_verilog_port(VERILOG_PORT_WIRE, local_wire) << ";" << std::endl; + } } } @@ -515,6 +518,9 @@ void write_verilog_module_to_file(std::fstream& fp, /* Print an empty line as splitter */ fp << std::endl; + + /* Print an empty line as splitter */ + fp << std::endl; } } /* end namespace openfpga */ diff --git a/openfpga/src/fpga_verilog/verilog_module_writer.h b/openfpga/src/fpga_verilog/verilog_module_writer.h index 1c0391492..322538b29 100644 --- a/openfpga/src/fpga_verilog/verilog_module_writer.h +++ b/openfpga/src/fpga_verilog/verilog_module_writer.h @@ -6,6 +6,7 @@ *******************************************************************/ #include #include "module_manager.h" +#include "verilog_port_types.h" /******************************************************************** * Function declaration @@ -17,7 +18,8 @@ namespace openfpga { void write_verilog_module_to_file(std::fstream& fp, const ModuleManager& module_manager, const ModuleId& module_id, - const bool& use_explicit_port_map); + const bool& use_explicit_port_map, + const e_verilog_default_net_type& default_net_type); } /* end namespace openfpga */ diff --git a/openfpga/src/fpga_verilog/verilog_mux.cpp b/openfpga/src/fpga_verilog/verilog_mux.cpp index a0fd896e2..3f114c48b 100644 --- a/openfpga/src/fpga_verilog/verilog_mux.cpp +++ b/openfpga/src/fpga_verilog/verilog_mux.cpp @@ -121,7 +121,8 @@ void print_verilog_cmos_mux_branch_module_behavioral(ModuleManager& module_manag std::fstream& fp, const CircuitModelId& mux_model, const std::string& module_name, - const MuxGraph& mux_graph) { + const MuxGraph& mux_graph, + const e_verilog_default_net_type& default_net_type) { /* Get the tgate model */ CircuitModelId tgate_model = circuit_lib.pass_gate_logic_model(mux_model); @@ -160,7 +161,7 @@ void print_verilog_cmos_mux_branch_module_behavioral(ModuleManager& module_manag BasicPort mem_port("mem", num_mems); /* dump module definition + ports */ - print_verilog_module_declaration(fp, module_manager, mux_module); + print_verilog_module_declaration(fp, module_manager, mux_module, default_net_type); /* Print the internal logic in behavioral Verilog codes */ /* Get the default value of SRAM ports */ @@ -509,6 +510,7 @@ void generate_verilog_rram_mux_branch_module(ModuleManager& module_manager, const CircuitModelId& circuit_model, const std::string& module_name, const MuxGraph& mux_graph, + const e_verilog_default_net_type& default_net_type, const bool& use_structural_verilog) { /* Make sure we have a valid file handler*/ VTR_ASSERT(true == valid_file_stream(fp)); @@ -559,7 +561,7 @@ void generate_verilog_rram_mux_branch_module(ModuleManager& module_manager, BasicPort wl_port(circuit_lib.port_prefix(mux_wl_ports[0]), num_mems + 1); /* dump module definition + ports */ - print_verilog_module_declaration(fp, module_manager, module_id); + print_verilog_module_declaration(fp, module_manager, module_id, default_net_type); /* Print the internal logic in either structural or behavioral Verilog codes */ if (true == use_structural_verilog) { @@ -583,6 +585,7 @@ void generate_verilog_mux_branch_module(ModuleManager& module_manager, const CircuitModelId& mux_model, const MuxGraph& mux_graph, const bool& use_explicit_port_map, + const e_verilog_default_net_type& default_net_type, std::map& branch_mux_module_is_outputted) { std::string module_name = generate_mux_branch_subckt_name(circuit_lib, mux_model, mux_graph.num_inputs(), mux_graph.num_memory_bits(), VERILOG_MUX_BASIS_POSTFIX); @@ -608,16 +611,29 @@ void generate_verilog_mux_branch_module(ModuleManager& module_manager, ModuleId mux_module = module_manager.find_module(module_name); VTR_ASSERT(true == module_manager.valid_module_id(mux_module)); write_verilog_module_to_file(fp, module_manager, mux_module, - use_explicit_port_map || circuit_lib.dump_explicit_port_map(mux_model)); + use_explicit_port_map || circuit_lib.dump_explicit_port_map(mux_model), + default_net_type); /* Add an empty line as a splitter */ fp << std::endl; } else { /* Behavioral verilog requires customized generation */ - print_verilog_cmos_mux_branch_module_behavioral(module_manager, circuit_lib, fp, mux_model, module_name, mux_graph); + print_verilog_cmos_mux_branch_module_behavioral(module_manager, + circuit_lib, + fp, + mux_model, + module_name, + mux_graph, + default_net_type); } break; case CIRCUIT_MODEL_DESIGN_RRAM: - generate_verilog_rram_mux_branch_module(module_manager, circuit_lib, fp, mux_model, module_name, mux_graph, + generate_verilog_rram_mux_branch_module(module_manager, + circuit_lib, + fp, + mux_model, + module_name, + mux_graph, + default_net_type, circuit_lib.dump_structural_verilog(mux_model)); break; default: @@ -1084,7 +1100,8 @@ void generate_verilog_rram_mux_module(ModuleManager& module_manager, std::fstream& fp, const CircuitModelId& circuit_model, const std::string& module_name, - const MuxGraph& mux_graph) { + const MuxGraph& mux_graph, + const e_verilog_default_net_type& default_net_type) { /* Error out for the conditions where we are not yet supported! */ if (CIRCUIT_MODEL_LUT == circuit_lib.model_type(circuit_model)) { /* RRAM LUT is not supported now... */ @@ -1169,7 +1186,7 @@ void generate_verilog_rram_mux_module(ModuleManager& module_manager, } /* dump module definition + ports */ - print_verilog_module_declaration(fp, module_manager, module_id); + print_verilog_module_declaration(fp, module_manager, module_id, default_net_type); /* TODO: Print the internal logic in Verilog codes */ generate_verilog_rram_mux_module_multiplexing_structure(module_manager, circuit_lib, fp, module_id, circuit_model, mux_graph); @@ -1194,7 +1211,8 @@ void generate_verilog_mux_module(ModuleManager& module_manager, std::fstream& fp, const CircuitModelId& mux_model, const MuxGraph& mux_graph, - const bool& use_explicit_port_map) { + const bool& use_explicit_port_map, + const e_verilog_default_net_type& default_net_type) { std::string module_name = generate_mux_subckt_name(circuit_lib, mux_model, find_mux_num_datapath_inputs(circuit_lib, mux_model, mux_graph.num_inputs()), std::string("")); @@ -1208,15 +1226,21 @@ void generate_verilog_mux_module(ModuleManager& module_manager, write_verilog_module_to_file(fp, module_manager, mux_module, ( use_explicit_port_map || circuit_lib.dump_explicit_port_map(mux_model) - || circuit_lib.dump_explicit_port_map(circuit_lib.pass_gate_logic_model(mux_model)) ) - ); + || circuit_lib.dump_explicit_port_map(circuit_lib.pass_gate_logic_model(mux_model)) ), + default_net_type); /* Add an empty line as a splitter */ fp << std::endl; break; } case CIRCUIT_MODEL_DESIGN_RRAM: /* TODO: RRAM-based Multiplexer Verilog module generation */ - generate_verilog_rram_mux_module(module_manager, circuit_lib, fp, mux_model, module_name, mux_graph); + generate_verilog_rram_mux_module(module_manager, + circuit_lib, + fp, + mux_model, + module_name, + mux_graph, + default_net_type); break; default: VTR_LOGF_ERROR(__FILE__, __LINE__, @@ -1236,7 +1260,7 @@ void print_verilog_submodule_mux_primitives(ModuleManager& module_manager, const MuxLibrary& mux_lib, const CircuitLibrary& circuit_lib, const std::string& submodule_dir, - const bool& use_explicit_port_map) { + const FabricVerilogOption& options) { /* Output primitive cells for MUX modules */ std::string verilog_fname(submodule_dir + std::string(MUX_PRIMITIVES_VERILOG_FILE_NAME)); @@ -1266,7 +1290,9 @@ void print_verilog_submodule_mux_primitives(ModuleManager& module_manager, /* Create branch circuits, which are N:1 one-level or 2:1 tree-like MUXes */ for (auto branch_mux_graph : branch_mux_graphs) { generate_verilog_mux_branch_module(module_manager, circuit_lib, fp, mux_circuit_model, - branch_mux_graph, use_explicit_port_map, + branch_mux_graph, + options.explicit_port_mapping(), + options.default_net_type(), branch_mux_module_is_outputted); } } @@ -1292,7 +1318,7 @@ void print_verilog_submodule_mux_top_modules(ModuleManager& module_manager, const MuxLibrary& mux_lib, const CircuitLibrary& circuit_lib, const std::string& submodule_dir, - const bool& use_explicit_port_map) { + const FabricVerilogOption& options) { /* Output top-level MUX modules */ std::string verilog_fname(submodule_dir + std::string(MUXES_VERILOG_FILE_NAME)); @@ -1308,13 +1334,18 @@ void print_verilog_submodule_mux_top_modules(ModuleManager& module_manager, print_verilog_file_header(fp, "Multiplexers"); - /* Generate unique Verilog modules for the multiplexers */ for (auto mux : mux_lib.muxes()) { const MuxGraph& mux_graph = mux_lib.mux_graph(mux); CircuitModelId mux_circuit_model = mux_lib.mux_circuit_model(mux); /* Create MUX circuits */ - generate_verilog_mux_module(module_manager, circuit_lib, fp, mux_circuit_model, mux_graph, use_explicit_port_map); + generate_verilog_mux_module(module_manager, + circuit_lib, + fp, + mux_circuit_model, + mux_graph, + options.explicit_port_mapping(), + options.default_net_type()); } /* Close the file stream */ @@ -1342,20 +1373,20 @@ void print_verilog_submodule_muxes(ModuleManager& module_manager, const MuxLibrary& mux_lib, const CircuitLibrary& circuit_lib, const std::string& submodule_dir, - const bool& use_explicit_port_map) { + const FabricVerilogOption& options) { print_verilog_submodule_mux_primitives(module_manager, netlist_manager, mux_lib, circuit_lib, submodule_dir, - use_explicit_port_map); + options); print_verilog_submodule_mux_top_modules(module_manager, netlist_manager, mux_lib, circuit_lib, submodule_dir, - use_explicit_port_map); + options); } } /* end namespace openfpga */ diff --git a/openfpga/src/fpga_verilog/verilog_mux.h b/openfpga/src/fpga_verilog/verilog_mux.h index 361c394dc..290a63759 100644 --- a/openfpga/src/fpga_verilog/verilog_mux.h +++ b/openfpga/src/fpga_verilog/verilog_mux.h @@ -12,6 +12,7 @@ #include "mux_library.h" #include "module_manager.h" #include "netlist_manager.h" +#include "fabric_verilog_options.h" /******************************************************************** * Function declaration @@ -25,7 +26,7 @@ void print_verilog_submodule_muxes(ModuleManager& module_manager, const MuxLibrary& mux_lib, const CircuitLibrary& circuit_lib, const std::string& submodule_dir, - const bool& use_explicit_port_map); + const FabricVerilogOption& options); } /* end namespace openfpga */ diff --git a/openfpga/src/fpga_verilog/verilog_port_types.h b/openfpga/src/fpga_verilog/verilog_port_types.h index 2100ba272..11e70622a 100644 --- a/openfpga/src/fpga_verilog/verilog_port_types.h +++ b/openfpga/src/fpga_verilog/verilog_port_types.h @@ -1,6 +1,22 @@ #ifndef VERILOG_PORT_TYPES_H #define VERILOG_PORT_TYPES_H +/******************************************************************** + * Include header files required by the data structure definition + *******************************************************************/ +#include +#include + +/* Begin namespace openfpga */ +namespace openfpga { + +enum e_verilog_default_net_type { + VERILOG_DEFAULT_NET_TYPE_NONE, + VERILOG_DEFAULT_NET_TYPE_WIRE, + NUM_VERILOG_DEFAULT_NET_TYPES, +}; +constexpr std::array VERILOG_DEFAULT_NET_TYPE_STRING = {{"none", "wire"}}; //String versions of default net types + enum e_dump_verilog_port_type { VERILOG_PORT_INPUT, VERILOG_PORT_OUTPUT, @@ -12,5 +28,7 @@ enum e_dump_verilog_port_type { }; constexpr std::array VERILOG_PORT_TYPE_STRING = {{"input", "output", "inout", "wire", "reg", ""}}; /* string version of enum e_verilog_port_type */ +} /* End namespace openfpga*/ + #endif diff --git a/openfpga/src/fpga_verilog/verilog_routing.cpp b/openfpga/src/fpga_verilog/verilog_routing.cpp index e6df8e858..5669fc567 100644 --- a/openfpga/src/fpga_verilog/verilog_routing.cpp +++ b/openfpga/src/fpga_verilog/verilog_routing.cpp @@ -80,7 +80,7 @@ void print_verilog_routing_connection_box_unique_module(NetlistManager& netlist_ const std::string& subckt_dir, const RRGSB& rr_gsb, const t_rr_type& cb_type, - const bool& use_explicit_port_map) { + const FabricVerilogOption& options) { /* Create the netlist */ vtr::Point gsb_coordinate(rr_gsb.get_cb_x(cb_type), rr_gsb.get_cb_y(cb_type)); std::string verilog_fname(subckt_dir + generate_connection_block_netlist_name(cb_type, gsb_coordinate, std::string(VERILOG_NETLIST_FILE_POSTFIX))); @@ -98,7 +98,10 @@ void print_verilog_routing_connection_box_unique_module(NetlistManager& netlist_ VTR_ASSERT(true == module_manager.valid_module_id(cb_module)); /* Write the verilog module */ - write_verilog_module_to_file(fp, module_manager, cb_module, use_explicit_port_map); + write_verilog_module_to_file(fp, + module_manager, cb_module, + options.explicit_port_mapping(), + options.default_net_type()); /* Add an empty line as a splitter */ fp << std::endl; @@ -180,7 +183,7 @@ void print_verilog_routing_switch_box_unique_module(NetlistManager& netlist_mana const ModuleManager& module_manager, const std::string& subckt_dir, const RRGSB& rr_gsb, - const bool& use_explicit_port_map) { + const FabricVerilogOption& options) { /* Create the netlist */ vtr::Point gsb_coordinate(rr_gsb.get_sb_x(), rr_gsb.get_sb_y()); std::string verilog_fname(subckt_dir + generate_routing_block_netlist_name(SB_VERILOG_FILE_NAME_PREFIX, gsb_coordinate, std::string(VERILOG_NETLIST_FILE_POSTFIX))); @@ -198,7 +201,11 @@ void print_verilog_routing_switch_box_unique_module(NetlistManager& netlist_mana VTR_ASSERT(true == module_manager.valid_module_id(sb_module)); /* Write the verilog module */ - write_verilog_module_to_file(fp, module_manager, sb_module, use_explicit_port_map); + write_verilog_module_to_file(fp, + module_manager, + sb_module, + options.explicit_port_mapping(), + options.default_net_type()); /* Close file handler */ fp.close(); @@ -219,7 +226,7 @@ void print_verilog_flatten_connection_block_modules(NetlistManager& netlist_mana const DeviceRRGSB& device_rr_gsb, const std::string& subckt_dir, const t_rr_type& cb_type, - const bool& use_explicit_port_map) { + const FabricVerilogOption& options) { /* Build unique X-direction connection block modules */ vtr::Point cb_range = device_rr_gsb.get_gsb_range(); @@ -237,7 +244,7 @@ void print_verilog_flatten_connection_block_modules(NetlistManager& netlist_mana module_manager, subckt_dir, rr_gsb, cb_type, - use_explicit_port_map); + options); } } } @@ -255,7 +262,7 @@ void print_verilog_flatten_routing_modules(NetlistManager& netlist_manager, const ModuleManager& module_manager, const DeviceRRGSB& device_rr_gsb, const std::string& subckt_dir, - const bool& use_explicit_port_map) { + const FabricVerilogOption& options) { /* Create a vector to contain all the Verilog netlist names that have been generated in this function */ std::vector netlist_names; @@ -272,13 +279,23 @@ void print_verilog_flatten_routing_modules(NetlistManager& netlist_manager, module_manager, subckt_dir, rr_gsb, - use_explicit_port_map); + options); } } - print_verilog_flatten_connection_block_modules(netlist_manager, module_manager, device_rr_gsb, subckt_dir, CHANX, use_explicit_port_map); + print_verilog_flatten_connection_block_modules(netlist_manager, + module_manager, + device_rr_gsb, + subckt_dir, + CHANX, + options); - print_verilog_flatten_connection_block_modules(netlist_manager, module_manager, device_rr_gsb, subckt_dir, CHANY, use_explicit_port_map); + print_verilog_flatten_connection_block_modules(netlist_manager, + module_manager, + device_rr_gsb, + subckt_dir, + CHANY, + options); /* VTR_LOG("Writing header file for routing submodules '%s'...", @@ -306,7 +323,7 @@ void print_verilog_unique_routing_modules(NetlistManager& netlist_manager, const ModuleManager& module_manager, const DeviceRRGSB& device_rr_gsb, const std::string& subckt_dir, - const bool& use_explicit_port_map) { + const FabricVerilogOption& options) { /* Create a vector to contain all the Verilog netlist names that have been generated in this function */ std::vector netlist_names; @@ -317,7 +334,7 @@ void print_verilog_unique_routing_modules(NetlistManager& netlist_manager, module_manager, subckt_dir, unique_mirror, - use_explicit_port_map); + options); } /* Build unique X-direction connection block modules */ @@ -328,7 +345,7 @@ void print_verilog_unique_routing_modules(NetlistManager& netlist_manager, module_manager, subckt_dir, unique_mirror, CHANX, - use_explicit_port_map); + options); } /* Build unique X-direction connection block modules */ @@ -339,7 +356,7 @@ void print_verilog_unique_routing_modules(NetlistManager& netlist_manager, module_manager, subckt_dir, unique_mirror, CHANY, - use_explicit_port_map); + options); } /* diff --git a/openfpga/src/fpga_verilog/verilog_routing.h b/openfpga/src/fpga_verilog/verilog_routing.h index 9d439053a..6f9eeb7bc 100644 --- a/openfpga/src/fpga_verilog/verilog_routing.h +++ b/openfpga/src/fpga_verilog/verilog_routing.h @@ -9,6 +9,7 @@ #include "module_manager.h" #include "netlist_manager.h" #include "device_rr_gsb.h" +#include "fabric_verilog_options.h" /******************************************************************** * Function declaration @@ -21,13 +22,13 @@ void print_verilog_flatten_routing_modules(NetlistManager& netlist_manager, const ModuleManager& module_manager, const DeviceRRGSB& device_rr_gsb, const std::string& subckt_dir, - const bool& use_explicit_port_map); + const FabricVerilogOption& options); void print_verilog_unique_routing_modules(NetlistManager& netlist_manager, const ModuleManager& module_manager, const DeviceRRGSB& device_rr_gsb, const std::string& subckt_dir, - const bool& use_explicit_port_map); + const FabricVerilogOption& options); } /* end namespace openfpga */ diff --git a/openfpga/src/fpga_verilog/verilog_submodule.cpp b/openfpga/src/fpga_verilog/verilog_submodule.cpp index 6756824ab..d2bca2aa9 100644 --- a/openfpga/src/fpga_verilog/verilog_submodule.cpp +++ b/openfpga/src/fpga_verilog/verilog_submodule.cpp @@ -48,13 +48,15 @@ void print_verilog_submodule(ModuleManager& module_manager, print_verilog_submodule_essentials(const_cast(module_manager), netlist_manager, submodule_dir, - circuit_lib); + circuit_lib, + fpga_verilog_opts.default_net_type()); /* Decoders for architecture */ print_verilog_submodule_arch_decoders(const_cast(module_manager), netlist_manager, decoder_lib, - submodule_dir); + submodule_dir, + fpga_verilog_opts.default_net_type()); /* Routing multiplexers */ /* NOTE: local decoders generation must go before the MUX generation!!! @@ -63,35 +65,38 @@ void print_verilog_submodule(ModuleManager& module_manager, print_verilog_submodule_mux_local_decoders(const_cast(module_manager), netlist_manager, mux_lib, circuit_lib, - submodule_dir); + submodule_dir, + fpga_verilog_opts.default_net_type()); print_verilog_submodule_muxes(module_manager, netlist_manager, mux_lib, circuit_lib, submodule_dir, - fpga_verilog_opts.explicit_port_mapping()); + fpga_verilog_opts); /* LUTes */ print_verilog_submodule_luts(const_cast(module_manager), netlist_manager, circuit_lib, submodule_dir, - fpga_verilog_opts.explicit_port_mapping()); + fpga_verilog_opts); /* Hard wires */ print_verilog_submodule_wires(const_cast(module_manager), netlist_manager, circuit_lib, - submodule_dir); + submodule_dir, + fpga_verilog_opts.default_net_type()); /* 4. Memories */ print_verilog_submodule_memories(const_cast(module_manager), netlist_manager, mux_lib, circuit_lib, submodule_dir, - fpga_verilog_opts.explicit_port_mapping()); + fpga_verilog_opts); /* 5. Dump template for all the modules */ if (true == fpga_verilog_opts.print_user_defined_template()) { print_verilog_submodule_templates(const_cast(module_manager), circuit_lib, - submodule_dir); + submodule_dir, + fpga_verilog_opts.default_net_type()); } /* Create a header file to include all the subckts */ diff --git a/openfpga/src/fpga_verilog/verilog_submodule_utils.cpp b/openfpga/src/fpga_verilog/verilog_submodule_utils.cpp index 37009c930..1163474d0 100644 --- a/openfpga/src/fpga_verilog/verilog_submodule_utils.cpp +++ b/openfpga/src/fpga_verilog/verilog_submodule_utils.cpp @@ -132,7 +132,8 @@ void add_user_defined_verilog_modules(ModuleManager& module_manager, static void print_one_verilog_template_module(const ModuleManager& module_manager, std::fstream& fp, - const std::string& module_name) { + const std::string& module_name, + const e_verilog_default_net_type& default_net_type) { /* Ensure a valid file handler*/ VTR_ASSERT(true == valid_file_stream(fp)); @@ -144,7 +145,7 @@ void print_one_verilog_template_module(const ModuleManager& module_manager, VTR_ASSERT(ModuleId::INVALID() != template_module); /* dump module definition + ports */ - print_verilog_module_declaration(fp, module_manager, template_module); + print_verilog_module_declaration(fp, module_manager, template_module, default_net_type); /* Finish dumping ports */ print_verilog_comment(fp, std::string("----- Internal logic should start here -----")); @@ -170,7 +171,8 @@ void print_one_verilog_template_module(const ModuleManager& module_manager, ********************************************************************/ void print_verilog_submodule_templates(const ModuleManager& module_manager, const CircuitLibrary& circuit_lib, - const std::string& submodule_dir) { + const std::string& submodule_dir, + const e_verilog_default_net_type& default_net_type) { std::string verilog_fname(submodule_dir + USER_DEFINED_TEMPLATE_VERILOG_FILE_NAME); /* Create the file stream */ @@ -196,7 +198,10 @@ void print_verilog_submodule_templates(const ModuleManager& module_manager, continue; } /* Print a Verilog template for the circuit model */ - print_one_verilog_template_module(module_manager, fp, circuit_lib.model_name(model)); + print_one_verilog_template_module(module_manager, + fp, + circuit_lib.model_name(model), + default_net_type); } /* close file stream */ diff --git a/openfpga/src/fpga_verilog/verilog_submodule_utils.h b/openfpga/src/fpga_verilog/verilog_submodule_utils.h index 51347de35..ad91e42f8 100644 --- a/openfpga/src/fpga_verilog/verilog_submodule_utils.h +++ b/openfpga/src/fpga_verilog/verilog_submodule_utils.h @@ -8,6 +8,7 @@ #include #include "module_manager.h" #include "circuit_library.h" +#include "verilog_port_types.h" /******************************************************************** * Function declaration @@ -25,7 +26,8 @@ void add_user_defined_verilog_modules(ModuleManager& module_manager, void print_verilog_submodule_templates(const ModuleManager& module_manager, const CircuitLibrary& circuit_lib, - const std::string& submodule_dir); + const std::string& submodule_dir, + const e_verilog_default_net_type& default_net_type); } /* end namespace openfpga */ diff --git a/openfpga/src/fpga_verilog/verilog_top_module.cpp b/openfpga/src/fpga_verilog/verilog_top_module.cpp index 79c6ebebe..340232535 100644 --- a/openfpga/src/fpga_verilog/verilog_top_module.cpp +++ b/openfpga/src/fpga_verilog/verilog_top_module.cpp @@ -37,7 +37,7 @@ namespace openfpga { void print_verilog_top_module(NetlistManager& netlist_manager, const ModuleManager& module_manager, const std::string& verilog_dir, - const bool& use_explicit_mapping) { + const FabricVerilogOption& options) { /* Create a module as the top-level fabric, and add it to the module manager */ std::string top_module_name = generate_fpga_top_module_name(); ModuleId top_module = module_manager.find_module(top_module_name); @@ -59,7 +59,11 @@ void print_verilog_top_module(NetlistManager& netlist_manager, print_verilog_file_header(fp, std::string("Top-level Verilog module for FPGA")); /* Write the module content in Verilog format */ - write_verilog_module_to_file(fp, module_manager, top_module, use_explicit_mapping); + write_verilog_module_to_file(fp, + module_manager, + top_module, + options.explicit_port_mapping(), + options.default_net_type()); /* Add an empty line as a splitter */ fp << std::endl; diff --git a/openfpga/src/fpga_verilog/verilog_top_module.h b/openfpga/src/fpga_verilog/verilog_top_module.h index 95f73e815..33180729f 100644 --- a/openfpga/src/fpga_verilog/verilog_top_module.h +++ b/openfpga/src/fpga_verilog/verilog_top_module.h @@ -7,6 +7,7 @@ #include #include "module_manager.h" #include "netlist_manager.h" +#include "fabric_verilog_options.h" /******************************************************************** * Function declaration @@ -18,7 +19,7 @@ namespace openfpga { void print_verilog_top_module(NetlistManager& netlist_manager, const ModuleManager& module_manager, const std::string& verilog_dir, - const bool& use_explicit_mapping); + const FabricVerilogOption& options); } /* end namespace openfpga */ diff --git a/openfpga/src/fpga_verilog/verilog_wire.cpp b/openfpga/src/fpga_verilog/verilog_wire.cpp index bb8419edd..c6e2e36b5 100644 --- a/openfpga/src/fpga_verilog/verilog_wire.cpp +++ b/openfpga/src/fpga_verilog/verilog_wire.cpp @@ -38,7 +38,8 @@ static void print_verilog_wire_module(const ModuleManager& module_manager, const CircuitLibrary& circuit_lib, std::fstream& fp, - const CircuitModelId& wire_model) { + const CircuitModelId& wire_model, + const e_verilog_default_net_type& default_net_type) { /* Ensure a valid file handler*/ VTR_ASSERT(true == valid_file_stream(fp)); @@ -58,7 +59,7 @@ void print_verilog_wire_module(const ModuleManager& module_manager, VTR_ASSERT(true == module_manager.valid_module_id(wire_module)); /* dump module definition + ports */ - print_verilog_module_declaration(fp, module_manager, wire_module); + print_verilog_module_declaration(fp, module_manager, wire_module, default_net_type); /* Finish dumping ports */ /* Print the internal logic of Verilog module */ @@ -95,7 +96,8 @@ void print_verilog_wire_module(const ModuleManager& module_manager, void print_verilog_submodule_wires(const ModuleManager& module_manager, NetlistManager& netlist_manager, const CircuitLibrary& circuit_lib, - const std::string& submodule_dir) { + const std::string& submodule_dir, + const e_verilog_default_net_type& default_net_type) { std::string verilog_fname(submodule_dir + std::string(WIRES_VERILOG_FILE_NAME)); /* Create the file stream */ @@ -117,7 +119,7 @@ void print_verilog_submodule_wires(const ModuleManager& module_manager, if (!circuit_lib.model_verilog_netlist(model).empty()) { continue; } - print_verilog_wire_module(module_manager, circuit_lib, fp, model); + print_verilog_wire_module(module_manager, circuit_lib, fp, model, default_net_type); } print_verilog_comment(fp, std::string("----- END Verilog modules for regular wires -----")); diff --git a/openfpga/src/fpga_verilog/verilog_wire.h b/openfpga/src/fpga_verilog/verilog_wire.h index d9996fbcf..82ee5a9bd 100644 --- a/openfpga/src/fpga_verilog/verilog_wire.h +++ b/openfpga/src/fpga_verilog/verilog_wire.h @@ -10,6 +10,7 @@ #include "circuit_library.h" #include "module_manager.h" #include "netlist_manager.h" +#include "verilog_port_types.h" /******************************************************************** * Function declaration @@ -21,7 +22,8 @@ namespace openfpga { void print_verilog_submodule_wires(const ModuleManager& module_manager, NetlistManager& netlist_manager, const CircuitLibrary& circuit_lib, - const std::string& submodule_dir); + const std::string& submodule_dir, + const e_verilog_default_net_type& default_net_type); } /* end namespace openfpga */ diff --git a/openfpga/src/fpga_verilog/verilog_writer_utils.cpp b/openfpga/src/fpga_verilog/verilog_writer_utils.cpp index bc41f1cab..15f801f7e 100644 --- a/openfpga/src/fpga_verilog/verilog_writer_utils.cpp +++ b/openfpga/src/fpga_verilog/verilog_writer_utils.cpp @@ -26,6 +26,18 @@ /* begin namespace openfpga */ namespace openfpga { +/************************************************ + * Generate the declaration for default net type + ***********************************************/ +void print_verilog_default_net_type_declaration(std::fstream& fp, + const e_verilog_default_net_type& default_net_type) { + VTR_ASSERT(true == valid_file_stream(fp)); + + fp << "//----- Default net type -----" << std::endl; + fp << "`default_nettype " << VERILOG_DEFAULT_NET_TYPE_STRING[default_net_type] << std::endl; + fp << std::endl; +} + /************************************************ * Generate header comments for a Verilog netlist * include the description @@ -184,7 +196,9 @@ void print_verilog_module_definition(std::fstream& fp, * Print a Verilog module ports based on the module id ***********************************************/ void print_verilog_module_ports(std::fstream& fp, - const ModuleManager& module_manager, const ModuleId& module_id) { + const ModuleManager& module_manager, + const ModuleId& module_id, + const e_verilog_default_net_type& default_net_type) { VTR_ASSERT(true == valid_file_stream(fp)); /* port type2type mapping */ @@ -222,38 +236,39 @@ void print_verilog_module_ports(std::fstream& fp, } } - /* Output any port that is also wire connection */ - fp << std::endl; - fp << "//----- BEGIN wire-connection ports -----" << std::endl; - for (const auto& kv : port_type2type_map) { - for (const auto& port : module_manager.module_ports_by_type(module_id, kv.first)) { - /* Skip the ports that are not registered */ - ModulePortId port_id = module_manager.find_module_port(module_id, port.get_name()); - VTR_ASSERT(ModulePortId::INVALID() != port_id); - if (false == module_manager.port_is_wire(module_id, port_id)) { - continue; - } + /* Output any port that is also wire connection when default net type is not wire! */ + if (VERILOG_DEFAULT_NET_TYPE_WIRE != default_net_type) { + fp << std::endl; + fp << "//----- BEGIN wire-connection ports -----" << std::endl; + for (const auto& kv : port_type2type_map) { + for (const auto& port : module_manager.module_ports_by_type(module_id, kv.first)) { + /* Skip the ports that are not registered */ + ModulePortId port_id = module_manager.find_module_port(module_id, port.get_name()); + VTR_ASSERT(ModulePortId::INVALID() != port_id); + if (false == module_manager.port_is_wire(module_id, port_id)) { + continue; + } - /* Print pre-processing flag for a port, if defined */ - std::string preproc_flag = module_manager.port_preproc_flag(module_id, port_id); - if (false == preproc_flag.empty()) { - /* Print an ifdef Verilog syntax */ - print_verilog_preprocessing_flag(fp, preproc_flag); - } + /* Print pre-processing flag for a port, if defined */ + std::string preproc_flag = module_manager.port_preproc_flag(module_id, port_id); + if (false == preproc_flag.empty()) { + /* Print an ifdef Verilog syntax */ + print_verilog_preprocessing_flag(fp, preproc_flag); + } - /* Print port */ - fp << generate_verilog_port(VERILOG_PORT_WIRE, port); - fp << ";" << std::endl; + /* Print port */ + fp << generate_verilog_port(VERILOG_PORT_WIRE, port); + fp << ";" << std::endl; - if (false == preproc_flag.empty()) { - /* Print an endif to pair the ifdef */ - print_verilog_endif(fp); + if (false == preproc_flag.empty()) { + /* Print an endif to pair the ifdef */ + print_verilog_endif(fp); + } } } + fp << "//----- END wire-connection ports -----" << std::endl; + fp << std::endl; } - fp << "//----- END wire-connection ports -----" << std::endl; - fp << std::endl; - /* Output any port that is registered */ fp << std::endl; @@ -295,12 +310,18 @@ void print_verilog_module_ports(std::fstream& fp, * ***********************************************/ void print_verilog_module_declaration(std::fstream& fp, - const ModuleManager& module_manager, const ModuleId& module_id) { + const ModuleManager& module_manager, + const ModuleId& module_id, + const e_verilog_default_net_type& default_net_type) { VTR_ASSERT(true == valid_file_stream(fp)); + /* Apply default net type from user's option */ + print_verilog_default_net_type_declaration(fp, + default_net_type); + print_verilog_module_definition(fp, module_manager, module_id); - print_verilog_module_ports(fp, module_manager, module_id); + print_verilog_module_ports(fp, module_manager, module_id, default_net_type); } @@ -429,6 +450,10 @@ void print_verilog_module_end(std::fstream& fp, fp << "endmodule" << std::endl; print_verilog_comment(fp, std::string("----- END Verilog module for " + module_name + " -----")); fp << std::endl; + + /* Reset default net type to be none */ + print_verilog_default_net_type_declaration(fp, + VERILOG_DEFAULT_NET_TYPE_NONE); } /************************************************ diff --git a/openfpga/src/fpga_verilog/verilog_writer_utils.h b/openfpga/src/fpga_verilog/verilog_writer_utils.h index fd1c9b1a5..59c05aea9 100644 --- a/openfpga/src/fpga_verilog/verilog_writer_utils.h +++ b/openfpga/src/fpga_verilog/verilog_writer_utils.h @@ -31,6 +31,9 @@ namespace openfpga { * as well maintain a easy way to identify the functions */ +void print_verilog_default_net_type_declaration(std::fstream& fp, + const e_verilog_default_net_type& default_net_type); + void print_verilog_file_header(std::fstream& fp, const std::string& usage); @@ -56,10 +59,14 @@ 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); + const ModuleManager& module_manager, + const ModuleId& module_id, + const e_verilog_default_net_type& default_net_type); void print_verilog_module_declaration(std::fstream& fp, - const ModuleManager& module_manager, const ModuleId& module_id); + const ModuleManager& module_manager, + const ModuleId& module_id, + const e_verilog_default_net_type& default_net_type); void print_verilog_module_instance(std::fstream& fp, const ModuleManager& module_manager,