add gpio ports to pb_type modules
This commit is contained in:
parent
0f50251b3b
commit
cab4bd6807
|
@ -83,6 +83,34 @@ std::vector<size_t> BasicPort::pins() const {
|
||||||
return pin_indices;
|
return pin_indices;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Check if a port can be merged with this port: their name should be the same */
|
||||||
|
bool BasicPort::mergeable(const BasicPort& portA) const {
|
||||||
|
return (0 == this->get_name().compare(portA.get_name()));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if a port is contained by this port:
|
||||||
|
* this function will check if the (LSB, MSB) of portA
|
||||||
|
* is contained by the (LSB, MSB) of this port
|
||||||
|
*/
|
||||||
|
bool BasicPort::contained(const BasicPort& portA) const {
|
||||||
|
return ( lsb_ <= portA.get_lsb() && portA.get_msb() <= msb_ );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Overloaded operators */
|
||||||
|
/* Two ports are the same only when:
|
||||||
|
* 1. port names are the same
|
||||||
|
* 2. LSBs are the same
|
||||||
|
* 3. MSBs are the same
|
||||||
|
*/
|
||||||
|
bool BasicPort::operator== (const BasicPort& portA) const {
|
||||||
|
if ( (0 == this->get_name().compare(portA.get_name()))
|
||||||
|
&& (this->get_lsb() == portA.get_lsb())
|
||||||
|
&& (this->get_msb() == portA.get_msb()) ) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/* Mutators */
|
/* Mutators */
|
||||||
/* copy */
|
/* copy */
|
||||||
void BasicPort::set(const BasicPort& basic_port) {
|
void BasicPort::set(const BasicPort& basic_port) {
|
||||||
|
@ -218,6 +246,28 @@ void BasicPort::combine(const BasicPort& port) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* A restricted combine function for two ports,
|
||||||
|
* Following conditions will be applied:
|
||||||
|
* 1. the two ports have the same name
|
||||||
|
* Note: you must run mergable() function first
|
||||||
|
* to make sure this assumption is valid
|
||||||
|
* 2. the new MSB will be the maximum MSB of the two ports
|
||||||
|
* 3. the new LSB will be the minimum LSB of the two ports
|
||||||
|
* 4. both ports should be valid!!!
|
||||||
|
*/
|
||||||
|
void BasicPort::merge(const BasicPort& portA) {
|
||||||
|
VTR_ASSERT(true == this->mergeable(portA));
|
||||||
|
VTR_ASSERT(true == this->is_valid() && true == portA.is_valid());
|
||||||
|
/* We skip merging if the portA is already contained by this port */
|
||||||
|
if (true == this->contained(portA)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/* LSB follows the minium LSB of the two ports */
|
||||||
|
lsb_ = std::min((int)lsb_, (int)portA.get_lsb());
|
||||||
|
/* MSB follows the minium MSB of the two ports */
|
||||||
|
msb_ = std::max((int)msb_, (int)portA.get_msb());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* Internal functions */
|
/* Internal functions */
|
||||||
/* Make a port to be invalid: msb < lsb */
|
/* Make a port to be invalid: msb < lsb */
|
||||||
|
|
|
@ -17,6 +17,8 @@ class BasicPort {
|
||||||
BasicPort(const std::string& name, const size_t& lsb, const size_t& msb);
|
BasicPort(const std::string& name, const size_t& lsb, const size_t& msb);
|
||||||
BasicPort(const std::string& name, const size_t& width);
|
BasicPort(const std::string& name, const size_t& width);
|
||||||
BasicPort(const BasicPort& basic_port); /* Copy constructor */
|
BasicPort(const BasicPort& basic_port); /* Copy constructor */
|
||||||
|
public: /* Overloaded operators */
|
||||||
|
bool operator== (const BasicPort& portA) const;
|
||||||
public: /* Accessors */
|
public: /* Accessors */
|
||||||
size_t get_width() const; /* get the port width */
|
size_t get_width() const; /* get the port width */
|
||||||
size_t get_msb() const; /* get the LSB */
|
size_t get_msb() const; /* get the LSB */
|
||||||
|
@ -24,6 +26,8 @@ class BasicPort {
|
||||||
std::string get_name() const; /* get the name */
|
std::string get_name() const; /* get the name */
|
||||||
bool is_valid() const; /* check if port size is valid > 0 */
|
bool is_valid() const; /* check if port size is valid > 0 */
|
||||||
std::vector<size_t> pins() const; /* Make a range of the pin indices */
|
std::vector<size_t> pins() const; /* Make a range of the pin indices */
|
||||||
|
bool mergeable(const BasicPort& portA) const; /* Check if a port can be merged with this port */
|
||||||
|
bool contained(const BasicPort& portA) const; /* Check if a port is contained by this port */
|
||||||
public: /* Mutators */
|
public: /* Mutators */
|
||||||
void set(const BasicPort& basic_port); /* copy */
|
void set(const BasicPort& basic_port); /* copy */
|
||||||
void set_name(const std::string& name); /* set the port LSB and MSB */
|
void set_name(const std::string& name); /* set the port LSB and MSB */
|
||||||
|
@ -37,6 +41,7 @@ class BasicPort {
|
||||||
bool counter_rotate(const size_t& offset); /* counter rotate */
|
bool counter_rotate(const size_t& offset); /* counter rotate */
|
||||||
void reset(); /* Reset to initial port */
|
void reset(); /* Reset to initial port */
|
||||||
void combine(const BasicPort& port); /* Combine two ports */
|
void combine(const BasicPort& port); /* Combine two ports */
|
||||||
|
void merge(const BasicPort& portA);
|
||||||
private: /* internal functions */
|
private: /* internal functions */
|
||||||
void make_invalid(); /* Make a port invalid */
|
void make_invalid(); /* Make a port invalid */
|
||||||
private: /* Internal Data */
|
private: /* Internal Data */
|
||||||
|
|
|
@ -21,6 +21,13 @@ ModuleManager::module_range ModuleManager::modules() const {
|
||||||
return vtr::make_range(ids_.begin(), ids_.end());
|
return vtr::make_range(ids_.begin(), ids_.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Find all the ports belonging to a module */
|
||||||
|
ModuleManager::module_port_range ModuleManager::module_ports(const ModuleId& module) const {
|
||||||
|
/* Validate the module_id */
|
||||||
|
VTR_ASSERT(valid_module_id(module));
|
||||||
|
return vtr::make_range(port_ids_[module].begin(), port_ids_[module].end());
|
||||||
|
}
|
||||||
|
|
||||||
/* Find all the nets belonging to a module */
|
/* Find all the nets belonging to a module */
|
||||||
ModuleManager::module_net_range ModuleManager::module_nets(const ModuleId& module) const {
|
ModuleManager::module_net_range ModuleManager::module_nets(const ModuleId& module) const {
|
||||||
/* Validate the module_id */
|
/* Validate the module_id */
|
||||||
|
@ -94,7 +101,7 @@ std::string ModuleManager::module_name(const ModuleId& module_id) const {
|
||||||
|
|
||||||
/* Get the string of a module port type */
|
/* Get the string of a module port type */
|
||||||
std::string ModuleManager::module_port_type_str(const enum e_module_port_type& port_type) const {
|
std::string ModuleManager::module_port_type_str(const enum e_module_port_type& port_type) const {
|
||||||
std::array<const char*, NUM_MODULE_PORT_TYPES> MODULE_PORT_TYPE_STRING = {{"GLOBAL PORTS", "INOUT PORTS", "INPUT PORTS", "OUTPUT PORTS", "CLOCK PORTS"}};
|
std::array<const char*, NUM_MODULE_PORT_TYPES> MODULE_PORT_TYPE_STRING = {{"GLOBAL PORTS", "GPIO PORTS", "INOUT PORTS", "INPUT PORTS", "OUTPUT PORTS", "CLOCK PORTS"}};
|
||||||
return MODULE_PORT_TYPE_STRING[port_type];
|
return MODULE_PORT_TYPE_STRING[port_type];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,11 +25,12 @@
|
||||||
class ModuleManager {
|
class ModuleManager {
|
||||||
public: /* Private data structures */
|
public: /* Private data structures */
|
||||||
enum e_module_port_type {
|
enum e_module_port_type {
|
||||||
MODULE_GLOBAL_PORT,
|
MODULE_GLOBAL_PORT, /* Global inputs */
|
||||||
MODULE_INOUT_PORT,
|
MODULE_GPIO_PORT, /* General-purpose IOs, which are data IOs of the fabric */
|
||||||
MODULE_INPUT_PORT,
|
MODULE_INOUT_PORT, /* Normal (non-global) inout ports */
|
||||||
MODULE_OUTPUT_PORT,
|
MODULE_INPUT_PORT, /* Normal (non-global) input ports */
|
||||||
MODULE_CLOCK_PORT,
|
MODULE_OUTPUT_PORT, /* Normal (non-global) output ports */
|
||||||
|
MODULE_CLOCK_PORT, /* Nromal (non-global) clock ports*/
|
||||||
NUM_MODULE_PORT_TYPES
|
NUM_MODULE_PORT_TYPES
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -37,11 +38,13 @@ class ModuleManager {
|
||||||
|
|
||||||
public: /* Types and ranges */
|
public: /* Types and ranges */
|
||||||
typedef vtr::vector<ModuleId, ModuleId>::const_iterator module_iterator;
|
typedef vtr::vector<ModuleId, ModuleId>::const_iterator module_iterator;
|
||||||
|
typedef vtr::vector<ModulePortId, ModulePortId>::const_iterator module_port_iterator;
|
||||||
typedef vtr::vector<ModuleNetId, ModuleNetId>::const_iterator module_net_iterator;
|
typedef vtr::vector<ModuleNetId, ModuleNetId>::const_iterator module_net_iterator;
|
||||||
typedef vtr::vector<ModuleNetSrcId, ModuleNetSrcId>::const_iterator module_net_src_iterator;
|
typedef vtr::vector<ModuleNetSrcId, ModuleNetSrcId>::const_iterator module_net_src_iterator;
|
||||||
typedef vtr::vector<ModuleNetSinkId, ModuleNetSinkId>::const_iterator module_net_sink_iterator;
|
typedef vtr::vector<ModuleNetSinkId, ModuleNetSinkId>::const_iterator module_net_sink_iterator;
|
||||||
|
|
||||||
typedef vtr::Range<module_iterator> module_range;
|
typedef vtr::Range<module_iterator> module_range;
|
||||||
|
typedef vtr::Range<module_port_iterator> module_port_range;
|
||||||
typedef vtr::Range<module_net_iterator> module_net_range;
|
typedef vtr::Range<module_net_iterator> module_net_range;
|
||||||
typedef vtr::Range<module_net_src_iterator> module_net_src_range;
|
typedef vtr::Range<module_net_src_iterator> module_net_src_range;
|
||||||
typedef vtr::Range<module_net_sink_iterator> module_net_sink_range;
|
typedef vtr::Range<module_net_sink_iterator> module_net_sink_range;
|
||||||
|
@ -49,6 +52,8 @@ class ModuleManager {
|
||||||
public: /* Public aggregators */
|
public: /* Public aggregators */
|
||||||
/* Find all the modules */
|
/* Find all the modules */
|
||||||
module_range modules() const;
|
module_range modules() const;
|
||||||
|
/* Find all the ports belonging to a module */
|
||||||
|
module_port_range module_ports(const ModuleId& module) const;
|
||||||
/* Find all the nets belonging to a module */
|
/* Find all the nets belonging to a module */
|
||||||
module_net_range module_nets(const ModuleId& module) const;
|
module_net_range module_nets(const ModuleId& module) const;
|
||||||
/* Find all the child modules under a parent module */
|
/* Find all the child modules under a parent module */
|
||||||
|
|
|
@ -840,6 +840,83 @@ size_t find_module_num_config_bits(const ModuleManager& module_manager,
|
||||||
return num_config_bits;
|
return num_config_bits;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/********************************************************************
|
||||||
|
* Add global ports to the module:
|
||||||
|
* In this function, the following tasks are done:
|
||||||
|
* 1. find all the GPIO ports from the child modules and build a list of it,
|
||||||
|
* 2. Merge all the GPIO ports with the same name
|
||||||
|
* 3. add the ports to the pb_module
|
||||||
|
*
|
||||||
|
* Note: This function should be call ONLY after all the sub modules (instances)
|
||||||
|
* have been added to the pb_module!
|
||||||
|
* Otherwise, some GPIO ports of the sub modules may be missed!
|
||||||
|
*******************************************************************/
|
||||||
|
void add_module_gpio_ports_from_child_modules(ModuleManager& module_manager,
|
||||||
|
const ModuleId& module_id) {
|
||||||
|
std::vector<BasicPort> gpio_ports_to_add;
|
||||||
|
|
||||||
|
/* Iterate over the child modules */
|
||||||
|
for (const ModuleId& child : module_manager.child_modules(module_id)) {
|
||||||
|
/* Find all the global ports, whose port type is special */
|
||||||
|
for (BasicPort gpio_port : module_manager.module_ports_by_type(child, ModuleManager::MODULE_GPIO_PORT)) {
|
||||||
|
/* If this port is not mergeable, we update the list */
|
||||||
|
bool is_mergeable = false;
|
||||||
|
for (BasicPort& gpio_port_to_add : gpio_ports_to_add) {
|
||||||
|
if (false == gpio_port_to_add.mergeable(gpio_port)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
is_mergeable = true;
|
||||||
|
/* For mergeable ports, we do a strong merge */
|
||||||
|
gpio_port_to_add.merge(gpio_port);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (false == is_mergeable) {
|
||||||
|
/* Reach here, this is an unique gpio port, update the list */
|
||||||
|
gpio_ports_to_add.push_back(gpio_port);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add the gpio ports for the module */
|
||||||
|
for (const BasicPort& gpio_port_to_add : gpio_ports_to_add) {
|
||||||
|
module_manager.add_port(module_id, gpio_port_to_add, ModuleManager::MODULE_GPIO_PORT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/********************************************************************
|
||||||
|
* Add GPIO ports to the module:
|
||||||
|
* In this function, the following tasks are done:
|
||||||
|
* 1. find all the global ports from the child modules and build a list of it,
|
||||||
|
* 2. add the ports to the pb_module
|
||||||
|
*
|
||||||
|
* Note: This function should be call ONLY after all the sub modules (instances)
|
||||||
|
* have been added to the pb_module!
|
||||||
|
* Otherwise, some global ports of the sub modules may be missed!
|
||||||
|
*******************************************************************/
|
||||||
|
void add_module_global_ports_from_child_modules(ModuleManager& module_manager,
|
||||||
|
const ModuleId& module_id) {
|
||||||
|
std::vector<BasicPort> global_ports_to_add;
|
||||||
|
|
||||||
|
/* Iterate over the child modules */
|
||||||
|
for (const ModuleId& child : module_manager.child_modules(module_id)) {
|
||||||
|
/* Find all the global ports, whose port type is special */
|
||||||
|
for (BasicPort global_port : module_manager.module_ports_by_type(child, ModuleManager::MODULE_GLOBAL_PORT)) {
|
||||||
|
/* Search in the global port list to be added, if this is unique, we update the list */
|
||||||
|
std::vector<BasicPort>::iterator it = std::find(global_ports_to_add.begin(), global_ports_to_add.end(), global_port);
|
||||||
|
if (it != global_ports_to_add.end()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
/* Reach here, this is an unique global port, update the list */
|
||||||
|
global_ports_to_add.push_back(global_port);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add the global ports for the module */
|
||||||
|
for (const BasicPort& global_port_to_add : global_ports_to_add) {
|
||||||
|
module_manager.add_port(module_id, global_port_to_add, ModuleManager::MODULE_GLOBAL_PORT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/********************************************************************
|
/********************************************************************
|
||||||
* TODO:
|
* TODO:
|
||||||
|
|
|
@ -82,4 +82,10 @@ size_t find_module_num_config_bits(const ModuleManager& module_manager,
|
||||||
const CircuitModelId& sram_model,
|
const CircuitModelId& sram_model,
|
||||||
const e_sram_orgz& sram_orgz_type);
|
const e_sram_orgz& sram_orgz_type);
|
||||||
|
|
||||||
|
void add_module_global_ports_from_child_modules(ModuleManager& module_manager,
|
||||||
|
const ModuleId& module_id);
|
||||||
|
|
||||||
|
void add_module_gpio_ports_from_child_modules(ModuleManager& module_manager,
|
||||||
|
const ModuleId& module_id);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
#include "verilog_module_writer.h"
|
#include "verilog_module_writer.h"
|
||||||
#include "verilog_grid.h"
|
#include "verilog_grid.h"
|
||||||
|
|
||||||
|
|
||||||
/********************************************************************
|
/********************************************************************
|
||||||
* Print Verilog modules of a primitive node in the pb_graph_node graph
|
* Print Verilog modules of a primitive node in the pb_graph_node graph
|
||||||
* This generic function can support all the different types of primitive nodes
|
* This generic function can support all the different types of primitive nodes
|
||||||
|
@ -108,7 +109,7 @@ void print_verilog_primitive_block(std::fstream& fp,
|
||||||
std::vector<CircuitPortId> primitive_model_inout_ports = circuit_lib.model_ports_by_type(primitive_model, SPICE_MODEL_PORT_INOUT);
|
std::vector<CircuitPortId> primitive_model_inout_ports = circuit_lib.model_ports_by_type(primitive_model, SPICE_MODEL_PORT_INOUT);
|
||||||
for (auto port : primitive_model_inout_ports) {
|
for (auto port : primitive_model_inout_ports) {
|
||||||
BasicPort module_port(generate_fpga_global_io_port_name(std::string(gio_inout_prefix), circuit_lib, primitive_model), circuit_lib.port_size(port));
|
BasicPort module_port(generate_fpga_global_io_port_name(std::string(gio_inout_prefix), circuit_lib, primitive_model), circuit_lib.port_size(port));
|
||||||
module_manager.add_port(primitive_module, module_port, ModuleManager::MODULE_INOUT_PORT);
|
module_manager.add_port(primitive_module, module_port, ModuleManager::MODULE_GPIO_PORT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Note: to cooperate with the pb_type hierarchy and connections, we add the port of primitive pb_type here.
|
/* Note: to cooperate with the pb_type hierarchy and connections, we add the port of primitive pb_type here.
|
||||||
|
@ -627,7 +628,6 @@ void add_module_pb_graph_interc(ModuleManager& module_manager,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/********************************************************************
|
/********************************************************************
|
||||||
* Print Verilog modules of physical blocks inside a grid (CLB, I/O. etc.)
|
* Print Verilog modules of physical blocks inside a grid (CLB, I/O. etc.)
|
||||||
* This function will traverse the graph of complex logic block (t_pb_graph_node)
|
* This function will traverse the graph of complex logic block (t_pb_graph_node)
|
||||||
|
@ -763,15 +763,17 @@ void print_verilog_physical_blocks_rec(std::fstream& fp,
|
||||||
pb_module_name_prefix,
|
pb_module_name_prefix,
|
||||||
physical_mode_index);
|
physical_mode_index);
|
||||||
|
|
||||||
/* TODO: Add global ports to the pb_module:
|
/* Add global ports to the pb_module:
|
||||||
* This is a much easier job after adding sub modules (instances),
|
* This is a much easier job after adding sub modules (instances),
|
||||||
* we just need to find all the global ports from the child modules and build a list of it
|
* we just need to find all the global ports from the child modules and build a list of it
|
||||||
*/
|
*/
|
||||||
|
add_module_global_ports_from_child_modules(module_manager, pb_module);
|
||||||
|
|
||||||
/* TODO: Count I/O (INOUT) ports from the sub-modules under this Verilog module
|
/* Count GPIO ports from the sub-modules under this Verilog module
|
||||||
* This is a much easier job after adding sub modules (instances),
|
* This is a much easier job after adding sub modules (instances),
|
||||||
* we just need to find all the I/O ports from the child modules and build a list of it
|
* we just need to find all the I/O ports from the child modules and build a list of it
|
||||||
*/
|
*/
|
||||||
|
add_module_gpio_ports_from_child_modules(module_manager, pb_module);
|
||||||
|
|
||||||
/* TODO: Count shared SRAM ports from the sub-modules under this Verilog module
|
/* TODO: Count shared SRAM ports from the sub-modules under this Verilog module
|
||||||
* This is a much easier job after adding sub modules (instances),
|
* This is a much easier job after adding sub modules (instances),
|
||||||
|
@ -785,7 +787,6 @@ void print_verilog_physical_blocks_rec(std::fstream& fp,
|
||||||
|
|
||||||
/* TODO: Add module nets to connect memory cells inside */
|
/* TODO: Add module nets to connect memory cells inside */
|
||||||
|
|
||||||
|
|
||||||
/* Comment lines */
|
/* Comment lines */
|
||||||
print_verilog_comment(fp, std::string("----- BEGIN Physical programmable logic block Verilog module: " + std::string(physical_pb_type->name) + " -----"));
|
print_verilog_comment(fp, std::string("----- BEGIN Physical programmable logic block Verilog module: " + std::string(physical_pb_type->name) + " -----"));
|
||||||
|
|
||||||
|
|
|
@ -7,12 +7,24 @@
|
||||||
* You should NOT modify any content of the module manager
|
* You should NOT modify any content of the module manager
|
||||||
* Please use const keyword to restrict this!
|
* Please use const keyword to restrict this!
|
||||||
*******************************************************************/
|
*******************************************************************/
|
||||||
|
#include <algorithm>
|
||||||
#include "vtr_assert.h"
|
#include "vtr_assert.h"
|
||||||
#include "fpga_x2p_utils.h"
|
#include "fpga_x2p_utils.h"
|
||||||
#include "module_manager_utils.h"
|
#include "module_manager_utils.h"
|
||||||
#include "verilog_writer_utils.h"
|
#include "verilog_writer_utils.h"
|
||||||
#include "verilog_module_writer.h"
|
#include "verilog_module_writer.h"
|
||||||
|
|
||||||
|
/********************************************************************
|
||||||
|
* Generate the name of a local wire for a undriven port inside Verilog
|
||||||
|
* module
|
||||||
|
*******************************************************************/
|
||||||
|
static
|
||||||
|
std::string generate_verilog_undriven_local_wire_name(const ModuleManager& module_manager,
|
||||||
|
const ModuleId& module,
|
||||||
|
const ModulePortId& module_port_id) {
|
||||||
|
return module_manager.module_port(module, module_port_id).get_name();
|
||||||
|
}
|
||||||
|
|
||||||
/********************************************************************
|
/********************************************************************
|
||||||
* Name a net for a local wire for a verilog module
|
* Name a net for a local wire for a verilog module
|
||||||
* 1. If this is a local wire, name it after the <src_module_name>_<instance_id>_<src_port_name>
|
* 1. If this is a local wire, name it after the <src_module_name>_<instance_id>_<src_port_name>
|
||||||
|
@ -113,6 +125,36 @@ std::vector<BasicPort> find_verilog_module_local_wires(const ModuleManager& modu
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Local wires could also happen for undriven ports of child module */
|
||||||
|
for (const ModuleId& child : module_manager.child_modules(module_id)) {
|
||||||
|
for (size_t instance : module_manager.child_module_instances(module_id, child)) {
|
||||||
|
for (const ModulePortId& child_port_id : module_manager.module_ports(child)) {
|
||||||
|
BasicPort child_port = module_manager.module_port(child, child_port_id);
|
||||||
|
std::vector<size_t> undriven_pins;
|
||||||
|
for (size_t child_pin : child_port.pins()) {
|
||||||
|
/* Find the net linked to the pin */
|
||||||
|
ModuleNetId net = module_manager.module_instance_port_net(module_id, child, instance,
|
||||||
|
child_port_id, child_pin);
|
||||||
|
/* We only care undriven ports */
|
||||||
|
if (ModuleNetId::INVALID() == net) {
|
||||||
|
undriven_pins.push_back(child_pin);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (true == undriven_pins.empty()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
/* Reach here, we need a local wire, we will create a port only for the undriven pins of the port! */
|
||||||
|
BasicPort instance_port;
|
||||||
|
instance_port.set_name(generate_verilog_undriven_local_wire_name(module_manager, child, child_port_id));
|
||||||
|
/* We give the same port name as child module, this case happens to global ports */
|
||||||
|
instance_port.set_width(*std::min_element(undriven_pins.begin(), undriven_pins.end()),
|
||||||
|
*std::max_element(undriven_pins.begin(), undriven_pins.end()));
|
||||||
|
|
||||||
|
local_wires.push_back(instance_port);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return local_wires;
|
return local_wires;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -225,6 +267,7 @@ void write_verilog_instance_to_file(std::fstream& fp,
|
||||||
/* port type2type mapping */
|
/* port type2type mapping */
|
||||||
std::map<ModuleManager::e_module_port_type, enum e_dump_verilog_port_type> port_type2type_map;
|
std::map<ModuleManager::e_module_port_type, enum e_dump_verilog_port_type> port_type2type_map;
|
||||||
port_type2type_map[ModuleManager::MODULE_GLOBAL_PORT] = VERILOG_PORT_CONKT;
|
port_type2type_map[ModuleManager::MODULE_GLOBAL_PORT] = VERILOG_PORT_CONKT;
|
||||||
|
port_type2type_map[ModuleManager::MODULE_GPIO_PORT] = VERILOG_PORT_CONKT;
|
||||||
port_type2type_map[ModuleManager::MODULE_INOUT_PORT] = VERILOG_PORT_CONKT;
|
port_type2type_map[ModuleManager::MODULE_INOUT_PORT] = VERILOG_PORT_CONKT;
|
||||||
port_type2type_map[ModuleManager::MODULE_INPUT_PORT] = VERILOG_PORT_CONKT;
|
port_type2type_map[ModuleManager::MODULE_INPUT_PORT] = VERILOG_PORT_CONKT;
|
||||||
port_type2type_map[ModuleManager::MODULE_OUTPUT_PORT] = VERILOG_PORT_CONKT;
|
port_type2type_map[ModuleManager::MODULE_OUTPUT_PORT] = VERILOG_PORT_CONKT;
|
||||||
|
@ -255,7 +298,7 @@ void write_verilog_instance_to_file(std::fstream& fp,
|
||||||
BasicPort instance_port;
|
BasicPort instance_port;
|
||||||
if (ModuleNetId::INVALID() == net) {
|
if (ModuleNetId::INVALID() == net) {
|
||||||
/* We give the same port name as child module, this case happens to global ports */
|
/* We give the same port name as child module, this case happens to global ports */
|
||||||
instance_port.set_name(module_manager.module_port(child_module, child_port_id).get_name());
|
instance_port.set_name(generate_verilog_undriven_local_wire_name(module_manager, child_module, child_port_id));
|
||||||
instance_port.set_width(child_pin, child_pin);
|
instance_port.set_width(child_pin, child_pin);
|
||||||
} else {
|
} else {
|
||||||
/* Find the name for this child port */
|
/* Find the name for this child port */
|
||||||
|
|
|
@ -108,6 +108,7 @@ void print_verilog_module_definition(std::fstream& fp,
|
||||||
/* port type2type mapping */
|
/* port type2type mapping */
|
||||||
std::map<ModuleManager::e_module_port_type, enum e_dump_verilog_port_type> port_type2type_map;
|
std::map<ModuleManager::e_module_port_type, enum e_dump_verilog_port_type> port_type2type_map;
|
||||||
port_type2type_map[ModuleManager::MODULE_GLOBAL_PORT] = VERILOG_PORT_CONKT;
|
port_type2type_map[ModuleManager::MODULE_GLOBAL_PORT] = VERILOG_PORT_CONKT;
|
||||||
|
port_type2type_map[ModuleManager::MODULE_GPIO_PORT] = VERILOG_PORT_CONKT;
|
||||||
port_type2type_map[ModuleManager::MODULE_INOUT_PORT] = VERILOG_PORT_CONKT;
|
port_type2type_map[ModuleManager::MODULE_INOUT_PORT] = VERILOG_PORT_CONKT;
|
||||||
port_type2type_map[ModuleManager::MODULE_INPUT_PORT] = VERILOG_PORT_CONKT;
|
port_type2type_map[ModuleManager::MODULE_INPUT_PORT] = VERILOG_PORT_CONKT;
|
||||||
port_type2type_map[ModuleManager::MODULE_OUTPUT_PORT] = VERILOG_PORT_CONKT;
|
port_type2type_map[ModuleManager::MODULE_OUTPUT_PORT] = VERILOG_PORT_CONKT;
|
||||||
|
@ -166,6 +167,7 @@ void print_verilog_module_ports(std::fstream& fp,
|
||||||
/* port type2type mapping */
|
/* port type2type mapping */
|
||||||
std::map<ModuleManager::e_module_port_type, enum e_dump_verilog_port_type> port_type2type_map;
|
std::map<ModuleManager::e_module_port_type, enum e_dump_verilog_port_type> port_type2type_map;
|
||||||
port_type2type_map[ModuleManager::MODULE_GLOBAL_PORT] = VERILOG_PORT_INPUT;
|
port_type2type_map[ModuleManager::MODULE_GLOBAL_PORT] = VERILOG_PORT_INPUT;
|
||||||
|
port_type2type_map[ModuleManager::MODULE_GPIO_PORT] = VERILOG_PORT_INPUT;
|
||||||
port_type2type_map[ModuleManager::MODULE_INOUT_PORT] = VERILOG_PORT_INOUT;
|
port_type2type_map[ModuleManager::MODULE_INOUT_PORT] = VERILOG_PORT_INOUT;
|
||||||
port_type2type_map[ModuleManager::MODULE_INPUT_PORT] = VERILOG_PORT_INPUT;
|
port_type2type_map[ModuleManager::MODULE_INPUT_PORT] = VERILOG_PORT_INPUT;
|
||||||
port_type2type_map[ModuleManager::MODULE_OUTPUT_PORT] = VERILOG_PORT_OUTPUT;
|
port_type2type_map[ModuleManager::MODULE_OUTPUT_PORT] = VERILOG_PORT_OUTPUT;
|
||||||
|
|
Loading…
Reference in New Issue