diff --git a/openfpga/src/fpga_verilog/verilog_wire.cpp b/openfpga/src/fpga_verilog/verilog_wire.cpp new file mode 100644 index 000000000..2ac9e7ffa --- /dev/null +++ b/openfpga/src/fpga_verilog/verilog_wire.cpp @@ -0,0 +1,136 @@ +/*********************************************** + * This file includes functions to generate + * Verilog submodules for wires. + **********************************************/ +#include +#include + +/* Headers from vtrutil library */ +#include "vtr_assert.h" +#include "vtr_log.h" + +/* Headers from openfpgautil library */ +#include "openfpga_digest.h" + +#include "module_manager.h" +#include "module_manager_utils.h" + +#include "openfpga_naming.h" + +#include "verilog_constants.h" +#include "verilog_submodule_utils.h" +#include "verilog_writer_utils.h" +#include "verilog_wire.h" + +/* begin namespace openfpga */ +namespace openfpga { + +/******************************************************************** + * Print a Verilog module of a regular wire segment + * Regular wire, which is 1-input and 1-output + * This type of wires are used in the local routing architecture + * +------+ + * input --->| wire |---> output + * +------+ + * + *******************************************************************/ +static +void print_verilog_wire_module(ModuleManager& module_manager, + const CircuitLibrary& circuit_lib, + std::fstream& fp, + const CircuitModelId& wire_model) { + /* Ensure a valid file handler*/ + VTR_ASSERT(true == valid_file_stream(fp)); + + /* Find the input port, output port*/ + std::vector input_ports = circuit_lib.model_ports_by_type(wire_model, CIRCUIT_MODEL_PORT_INPUT, true); + std::vector output_ports = circuit_lib.model_ports_by_type(wire_model, CIRCUIT_MODEL_PORT_OUTPUT, true); + std::vector global_ports = circuit_lib.model_global_ports_by_type(wire_model, CIRCUIT_MODEL_PORT_INPUT, true, true); + + /* Makre sure the port size is what we want */ + VTR_ASSERT (1 == input_ports.size()); + VTR_ASSERT (1 == output_ports.size()); + VTR_ASSERT (1 == circuit_lib.port_size(input_ports[0])); + VTR_ASSERT (1 == circuit_lib.port_size(output_ports[0])); + + /* Create a Verilog Module based on the circuit model, and add to module manager */ + ModuleId wire_module = module_manager.find_module(circuit_lib.model_name(wire_model)); + VTR_ASSERT(true == module_manager.valid_module_id(wire_module)); + + /* dump module definition + ports */ + print_verilog_module_declaration(fp, module_manager, wire_module); + /* Finish dumping ports */ + + /* Print the internal logic of Verilog module */ + /* Find the input port of the module */ + ModulePortId module_input_port_id = module_manager.find_module_port(wire_module, circuit_lib.port_lib_name(input_ports[0])); + VTR_ASSERT(ModulePortId::INVALID() != module_input_port_id); + BasicPort module_input_port = module_manager.module_port(wire_module, module_input_port_id); + + /* Find the output port of the module */ + ModulePortId module_output_port_id = module_manager.find_module_port(wire_module, circuit_lib.port_lib_name(output_ports[0])); + VTR_ASSERT(ModulePortId::INVALID() != module_output_port_id); + BasicPort module_output_port = module_manager.module_port(wire_module, module_output_port_id); + + /* Print wire declaration for the inputs and outputs */ + fp << generate_verilog_port(VERILOG_PORT_WIRE, module_input_port) << ";" << std::endl; + fp << generate_verilog_port(VERILOG_PORT_WIRE, module_output_port) << ";" << std::endl; + + /* Direct shortcut */ + print_verilog_wire_connection(fp, module_output_port, module_input_port, false); + + /* Print timing info */ + print_verilog_submodule_timing(fp, circuit_lib, wire_model); + + /* Put an end to the Verilog module */ + print_verilog_module_end(fp, circuit_lib.model_name(wire_model)); + + /* Add an empty line as a splitter */ + fp << std::endl; +} + +/******************************************************************** + * Top-level function to print wire modules + *******************************************************************/ +void print_verilog_submodule_wires(ModuleManager& module_manager, + std::vector& netlist_names, + const CircuitLibrary& circuit_lib, + const std::string& verilog_dir, + const std::string& submodule_dir) { + std::string verilog_fname(submodule_dir + std::string(WIRES_VERILOG_FILE_NAME)); + + /* Create the file stream */ + std::fstream fp; + fp.open(verilog_fname, std::fstream::out | std::fstream::trunc); + + 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 wires '%s'...", + verilog_fname.c_str()); + + print_verilog_file_header(fp, "Wires"); + + print_verilog_include_defines_preproc_file(fp, verilog_dir); + + /* Print Verilog models for regular wires*/ + print_verilog_comment(fp, std::string("----- BEGIN Verilog modules for regular wires -----")); + for (const auto& model : circuit_lib.models_by_type(CIRCUIT_MODEL_WIRE)) { + /* Bypass user-defined circuit models */ + if (!circuit_lib.model_verilog_netlist(model).empty()) { + continue; + } + print_verilog_wire_module(module_manager, circuit_lib, fp, model); + } + print_verilog_comment(fp, std::string("----- END Verilog modules for regular wires -----")); + + /* Close the file stream */ + fp.close(); + + /* Add fname to the netlist name list */ + netlist_names.push_back(verilog_fname); + + VTR_LOG("Done\n"); +} + +} /* end namespace openfpga */ diff --git a/openfpga/src/fpga_verilog/verilog_wire.h b/openfpga/src/fpga_verilog/verilog_wire.h new file mode 100644 index 000000000..7d22ae4c8 --- /dev/null +++ b/openfpga/src/fpga_verilog/verilog_wire.h @@ -0,0 +1,28 @@ +#ifndef VERILOG_WIRE_H +#define VERILOG_WIRE_H + +/******************************************************************** + * Include header files that are required by function declaration + *******************************************************************/ +#include +#include + +#include "circuit_library.h" +#include "module_manager.h" + +/******************************************************************** + * Function declaration + *******************************************************************/ + +/* begin namespace openfpga */ +namespace openfpga { + +void print_verilog_submodule_wires(ModuleManager& module_manager, + std::vector& netlist_names, + const CircuitLibrary& circuit_lib, + const std::string& verilog_dir, + const std::string& submodule_dir); + +} /* end namespace openfpga */ + +#endif