From 6f42aac626a1c6ca8687da8f73d066ce99a9df7a Mon Sep 17 00:00:00 2001 From: tangxifan Date: Tue, 8 Oct 2019 20:14:38 -0600 Subject: [PATCH] add wire connection in Verilog module declaration --- .../vpr/SRC/fpga_x2p/base/module_manager.cpp | 18 ++++++++++ .../vpr/SRC/fpga_x2p/base/module_manager.h | 5 +++ .../fpga_x2p/base/module_manager_utils.cpp | 8 +++++ .../vpr/SRC/fpga_x2p/verilog/verilog_lut.cpp | 4 +++ .../fpga_x2p/verilog/verilog_writer_utils.cpp | 33 +++++++++++++++++++ 5 files changed, 68 insertions(+) diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/base/module_manager.cpp b/vpr7_x2p/vpr/SRC/fpga_x2p/base/module_manager.cpp index 2a89a748c..bdcbf174e 100644 --- a/vpr7_x2p/vpr/SRC/fpga_x2p/base/module_manager.cpp +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/base/module_manager.cpp @@ -99,6 +99,13 @@ size_t ModuleManager::num_instance(const ModuleId& parent_module, const ModuleId return 0; } +/* Find if a port is a wire connection */ +bool ModuleManager::port_is_wire(const ModuleId& module, const ModulePortId& port) const { + /* validate both module id and port id*/ + VTR_ASSERT(valid_module_port_id(module, port)); + return port_is_wire_[module][port]; +} + /* Find if a port is register */ bool ModuleManager::port_is_register(const ModuleId& module, const ModulePortId& port) const { /* validate both module id and port id*/ @@ -137,6 +144,7 @@ ModuleId ModuleManager::add_module(const std::string& name) { port_ids_.emplace_back(); ports_.emplace_back(); port_types_.emplace_back(); + port_is_wire_.emplace_back(); port_is_register_.emplace_back(); port_preproc_flags_.emplace_back(); @@ -162,6 +170,7 @@ ModulePortId ModuleManager::add_port(const ModuleId& module, port_ids_[module].push_back(port); ports_[module].push_back(port_info); port_types_[module].push_back(port_type); + port_is_wire_[module].push_back(false); port_is_register_[module].push_back(false); port_preproc_flags_[module].emplace_back(); /* Create an empty string for the pre-processing flags */ @@ -178,6 +187,15 @@ void ModuleManager::set_module_name(const ModuleId& module, const std::string& n names_[module] = name; } +/* Set a port to be a wire */ +void ModuleManager::set_port_is_wire(const ModuleId& module, const std::string& port_name, const bool& is_wire) { + /* Find the port */ + ModulePortId port = find_module_port(module, port_name); + /* Must find something, otherwise drop an error */ + VTR_ASSERT(ModulePortId::INVALID() != port); + port_is_wire_[module][port] = is_wire; +} + /* Set a port to be a register */ void ModuleManager::set_port_is_register(const ModuleId& module, const std::string& port_name, const bool& is_register) { /* Find the port */ diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/base/module_manager.h b/vpr7_x2p/vpr/SRC/fpga_x2p/base/module_manager.h index 297046059..c99d3ffa1 100644 --- a/vpr7_x2p/vpr/SRC/fpga_x2p/base/module_manager.h +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/base/module_manager.h @@ -46,6 +46,8 @@ class ModuleManager { ModuleId find_module(const std::string& name) const; /* Find the number of instances of a child module in the parent module */ size_t num_instance(const ModuleId& parent_module, const ModuleId& child_module) const; + /* Find if a port is a wire connection */ + bool port_is_wire(const ModuleId& module, const ModulePortId& port) const; /* Find if a port is register */ bool port_is_register(const ModuleId& module, const ModulePortId& port) const; /* Return the pre-processing flag of a port */ @@ -58,6 +60,8 @@ class ModuleManager { const BasicPort& port_info, const enum e_module_port_type& port_type); /* Set a name for a module */ void set_module_name(const ModuleId& module, const std::string& name); + /* Set a port to be a wire */ + void set_port_is_wire(const ModuleId& module, const std::string& port_name, const bool& is_wire); /* Set a port to be a register */ void set_port_is_register(const ModuleId& module, const std::string& port_name, const bool& is_register); /* Set the preprocessing flag for a port */ @@ -80,6 +84,7 @@ class ModuleManager { vtr::vector> port_ids_; /* List of ports for each Module */ vtr::vector> ports_; /* List of ports for each Module */ vtr::vector> port_types_; /* Type of ports */ + vtr::vector> port_is_wire_; /* If the port is a wire, use for Verilog port definition. If enabled: reg */ vtr::vector> port_is_register_; /* If the port is a register, use for Verilog port definition. If enabled: reg */ vtr::vector> port_preproc_flags_; /* If a port is available only when a pre-processing flag is enabled. This is to record the pre-processing flags */ diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/base/module_manager_utils.cpp b/vpr7_x2p/vpr/SRC/fpga_x2p/base/module_manager_utils.cpp index 120ed3958..9f744bd24 100644 --- a/vpr7_x2p/vpr/SRC/fpga_x2p/base/module_manager_utils.cpp +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/base/module_manager_utils.cpp @@ -228,6 +228,8 @@ void add_pb_type_ports_to_module_manager(ModuleManager& module_manager, for (auto port : pb_type_inout_ports) { BasicPort module_port(generate_pb_type_port_name(port), port->num_pins); module_manager.add_port(module_id, module_port, ModuleManager::MODULE_INOUT_PORT); + /* Set the port to be wire-connection */ + module_manager.set_port_is_wire(module_id, module_port.get_name(), true); } /* Find the input ports required by the primitive pb_type, and add them to the module */ @@ -235,6 +237,8 @@ void add_pb_type_ports_to_module_manager(ModuleManager& module_manager, for (auto port : pb_type_input_ports) { BasicPort module_port(generate_pb_type_port_name(port), port->num_pins); module_manager.add_port(module_id, module_port, ModuleManager::MODULE_INPUT_PORT); + /* Set the port to be wire-connection */ + module_manager.set_port_is_wire(module_id, module_port.get_name(), true); } /* Find the output ports required by the primitive pb_type, and add them to the module */ @@ -242,6 +246,8 @@ void add_pb_type_ports_to_module_manager(ModuleManager& module_manager, for (auto port : pb_type_output_ports) { BasicPort module_port(generate_pb_type_port_name(port), port->num_pins); module_manager.add_port(module_id, module_port, ModuleManager::MODULE_OUTPUT_PORT); + /* Set the port to be wire-connection */ + module_manager.set_port_is_wire(module_id, module_port.get_name(), true); } /* Find the clock ports required by the primitive pb_type, and add them to the module */ @@ -249,6 +255,8 @@ void add_pb_type_ports_to_module_manager(ModuleManager& module_manager, for (auto port : pb_type_clock_ports) { BasicPort module_port(generate_pb_type_port_name(port), port->num_pins); module_manager.add_port(module_id, module_port, ModuleManager::MODULE_CLOCK_PORT); + /* Set the port to be wire-connection */ + module_manager.set_port_is_wire(module_id, module_port.get_name(), true); } } diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_lut.cpp b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_lut.cpp index 5c7e27449..50f924c32 100644 --- a/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_lut.cpp +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_lut.cpp @@ -104,11 +104,15 @@ void print_verilog_submodule_lut(ModuleManager& module_manager, for (const auto& port : lut_input_ports) { BasicPort input_port(circuit_lib.port_lib_name(port), circuit_lib.port_size(port)); module_manager.add_port(module_id, input_port, ModuleManager::MODULE_INPUT_PORT); + /* Set the port to be wire-connection */ + module_manager.set_port_is_wire(module_id, input_port.get_name(), true); } /* Add each output port */ for (const auto& port : lut_output_ports) { BasicPort output_port(circuit_lib.port_lib_name(port), circuit_lib.port_size(port)); module_manager.add_port(module_id, output_port, ModuleManager::MODULE_OUTPUT_PORT); + /* Set the port to be wire-connection */ + module_manager.set_port_is_wire(module_id, output_port.get_name(), true); } /* Add each regular (not mode select) SRAM port */ for (const auto& port : lut_regular_sram_ports) { diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_writer_utils.cpp b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_writer_utils.cpp index 2a4025cf3..141a2c367 100644 --- a/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_writer_utils.cpp +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_writer_utils.cpp @@ -194,6 +194,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; + } + + /* 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; + + 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; + /* Output any port that is registered */ fp << std::endl;