start supporting global output ports in module manager
This commit is contained in:
parent
32c74ad811
commit
836f722f20
|
@ -120,7 +120,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", "GPIO PORTS", "INOUT PORTS", "INPUT PORTS", "OUTPUT PORTS", "CLOCK PORTS"}};
|
std::array<const char*, NUM_MODULE_PORT_TYPES> MODULE_PORT_TYPE_STRING = {{"GLOBAL PORTS", "SPY 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];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,6 +28,7 @@ class ModuleManager {
|
||||||
public: /* Private data structures */
|
public: /* Private data structures */
|
||||||
enum e_module_port_type {
|
enum e_module_port_type {
|
||||||
MODULE_GLOBAL_PORT, /* Global inputs */
|
MODULE_GLOBAL_PORT, /* Global inputs */
|
||||||
|
MODULE_SPY_PORT, /* Global outputs, which is designed for spypads */
|
||||||
MODULE_GPIO_PORT, /* General-purpose IOs, which are data IOs of the fabric */
|
MODULE_GPIO_PORT, /* General-purpose IOs, which are data IOs of the fabric */
|
||||||
MODULE_INOUT_PORT, /* Normal (non-global) inout ports */
|
MODULE_INOUT_PORT, /* Normal (non-global) inout ports */
|
||||||
MODULE_INPUT_PORT, /* Normal (non-global) input ports */
|
MODULE_INPUT_PORT, /* Normal (non-global) input ports */
|
||||||
|
|
|
@ -129,6 +129,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_SPY_PORT] = VERILOG_PORT_CONKT;
|
||||||
port_type2type_map[ModuleManager::MODULE_GPIO_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;
|
||||||
|
@ -188,6 +189,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_SPY_PORT] = VERILOG_PORT_OUTPUT;
|
||||||
port_type2type_map[ModuleManager::MODULE_GPIO_PORT] = VERILOG_PORT_INOUT;
|
port_type2type_map[ModuleManager::MODULE_GPIO_PORT] = VERILOG_PORT_INOUT;
|
||||||
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;
|
||||||
|
@ -344,6 +346,7 @@ void print_verilog_module_instance(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_SPY_PORT] = VERILOG_PORT_CONKT;
|
||||||
port_type2type_map[ModuleManager::MODULE_GPIO_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;
|
||||||
|
|
|
@ -36,10 +36,20 @@ ModuleId add_circuit_model_to_module_manager(ModuleManager& module_manager,
|
||||||
VTR_ASSERT(ModuleId::INVALID() != module);
|
VTR_ASSERT(ModuleId::INVALID() != module);
|
||||||
|
|
||||||
/* Add ports */
|
/* Add ports */
|
||||||
/* Find global ports and add one by one */
|
/* Find global ports and add one by one
|
||||||
|
* Global input ports will be considered as global port in the context of module manager
|
||||||
|
* Global output ports will be considered as spy port in the context of module manager
|
||||||
|
*/
|
||||||
for (const auto& port : circuit_lib.model_global_ports(circuit_model, false)) {
|
for (const auto& port : circuit_lib.model_global_ports(circuit_model, false)) {
|
||||||
BasicPort port_info(circuit_lib.port_prefix(port), circuit_lib.port_size(port));
|
BasicPort port_info(circuit_lib.port_prefix(port), circuit_lib.port_size(port));
|
||||||
|
if (CIRCUIT_MODEL_PORT_INPUT == circuit_lib.port_type(port)) {
|
||||||
module_manager.add_port(module, port_info, ModuleManager::MODULE_GLOBAL_PORT);
|
module_manager.add_port(module, port_info, ModuleManager::MODULE_GLOBAL_PORT);
|
||||||
|
} else if (CIRCUIT_MODEL_PORT_CLOCK == circuit_lib.port_type(port)) {
|
||||||
|
module_manager.add_port(module, port_info, ModuleManager::MODULE_GLOBAL_PORT);
|
||||||
|
} else {
|
||||||
|
VTR_ASSERT(CIRCUIT_MODEL_PORT_OUTPUT == circuit_lib.port_type(port));
|
||||||
|
module_manager.add_port(module, port_info, ModuleManager::MODULE_SPY_PORT);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Find other ports and add one by one */
|
/* Find other ports and add one by one */
|
||||||
|
@ -1011,17 +1021,29 @@ void add_module_gpio_ports_from_child_modules(ModuleManager& module_manager,
|
||||||
}
|
}
|
||||||
|
|
||||||
/********************************************************************
|
/********************************************************************
|
||||||
* Add global ports to the module:
|
* Add global input ports to the module:
|
||||||
* In this function, the following tasks are done:
|
* In this function, the following tasks are done:
|
||||||
* 1. find all the global ports from the child modules and build a list of it,
|
* 1. find all the global input ports from the child modules and build a list of it,
|
||||||
* 2. add the ports to the pb_module
|
* 2. add the input ports to the pb_module
|
||||||
* 3. add the module nets to connect the pb_module global ports to those of child modules
|
* 3. add the module nets to connect the pb_module global ports to those of child modules
|
||||||
*
|
*
|
||||||
|
* Module
|
||||||
|
* +--------------------------
|
||||||
|
* | child[0]
|
||||||
|
* input_portA[0] ----+-+---->+----------
|
||||||
|
* | | |
|
||||||
|
* | | +----------
|
||||||
|
* | |
|
||||||
|
* | | child[1]
|
||||||
|
* | +---->+----------
|
||||||
|
* | |
|
||||||
|
* | +----------
|
||||||
|
*
|
||||||
* Note: This function should be call ONLY after all the sub modules (instances)
|
* Note: This function should be call ONLY after all the sub modules (instances)
|
||||||
* have been added to the pb_module!
|
* have been added to the pb_module!
|
||||||
* Otherwise, some global ports of the sub modules may be missed!
|
* Otherwise, some global ports of the sub modules may be missed!
|
||||||
*******************************************************************/
|
*******************************************************************/
|
||||||
void add_module_global_ports_from_child_modules(ModuleManager& module_manager,
|
void add_module_global_input_ports_from_child_modules(ModuleManager& module_manager,
|
||||||
const ModuleId& module_id) {
|
const ModuleId& module_id) {
|
||||||
std::vector<BasicPort> global_ports_to_add;
|
std::vector<BasicPort> global_ports_to_add;
|
||||||
|
|
||||||
|
@ -1078,6 +1100,136 @@ void add_module_global_ports_from_child_modules(ModuleManager& module_manager,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/********************************************************************
|
||||||
|
* Add global output ports to the module:
|
||||||
|
* In this function, the following tasks are done:
|
||||||
|
* 1. find all the global output ports from the child modules and build a list of it,
|
||||||
|
* 2. add the output ports to the pb_module
|
||||||
|
* 3. add the module nets to connect the pb_module global ports to those of child modules
|
||||||
|
*
|
||||||
|
* Module
|
||||||
|
* ----------------------+
|
||||||
|
* |
|
||||||
|
* child[0] |
|
||||||
|
* -----------+ |
|
||||||
|
* |----------+----> outputA[0]
|
||||||
|
* -----------+ |
|
||||||
|
* |
|
||||||
|
* child[1] |
|
||||||
|
* -----------+ |
|
||||||
|
* |----------+----> outputA[1]
|
||||||
|
* -----------+ |
|
||||||
|
*
|
||||||
|
* 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_output_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)) {
|
||||||
|
/* Iterate over the child instances */
|
||||||
|
for (size_t i = 0; i < module_manager.num_instance(module_id, child); ++i) {
|
||||||
|
/* Find all the global ports, whose port type is special */
|
||||||
|
for (BasicPort global_port : module_manager.module_ports_by_type(child, ModuleManager::MODULE_SPY_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()) {
|
||||||
|
/* Found in the global port with the same name, increase the port size */
|
||||||
|
it->expand(global_port.get_width());
|
||||||
|
continue; /* Finish for the port already in the list */
|
||||||
|
}
|
||||||
|
/* Reach here, this is an unique global port, update the list */
|
||||||
|
global_ports_to_add.push_back(global_port);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Record the port id for each type of global port */
|
||||||
|
std::vector<ModulePortId> global_port_ids;
|
||||||
|
/* Add the global ports for the module */
|
||||||
|
for (const BasicPort& global_port_to_add : global_ports_to_add) {
|
||||||
|
ModulePortId port_id = module_manager.add_port(module_id, global_port_to_add, ModuleManager::MODULE_SPY_PORT);
|
||||||
|
global_port_ids.push_back(port_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add module nets to connect the global ports of the module to the global ports of the sub module */
|
||||||
|
/* Create a counter for each global port to record the current LSB */
|
||||||
|
std::vector<size_t> global_port_lsbs(global_port_ids.size(), 0);
|
||||||
|
|
||||||
|
/* Iterate over the child modules */
|
||||||
|
for (const ModuleId& child : module_manager.child_modules(module_id)) {
|
||||||
|
/* Iterate over the child instances */
|
||||||
|
for (const size_t& child_instance : module_manager.child_module_instances(module_id, child)) {
|
||||||
|
/* Find all the global ports, whose port type is special */
|
||||||
|
for (ModulePortId child_global_port_id : module_manager.module_port_ids_by_type(child, ModuleManager::MODULE_SPY_PORT)) {
|
||||||
|
/* Find the global port from the child module */
|
||||||
|
BasicPort child_global_port = module_manager.module_port(child, child_global_port_id);
|
||||||
|
/* Search in the global port list to be added, find the port id */
|
||||||
|
std::vector<BasicPort>::iterator it = std::find(global_ports_to_add.begin(), global_ports_to_add.end(), child_global_port);
|
||||||
|
VTR_ASSERT(it != global_ports_to_add.end());
|
||||||
|
|
||||||
|
/* Find the global port from the parent module */
|
||||||
|
size_t module_global_port_offset = it - global_ports_to_add.begin();
|
||||||
|
ModulePortId module_global_port_id = global_port_ids[module_global_port_offset];
|
||||||
|
BasicPort module_global_port = module_manager.module_port(module_id, module_global_port_id);
|
||||||
|
/* Current LSB should be in range */
|
||||||
|
VTR_ASSERT(module_global_port.get_width() > global_port_lsbs[module_global_port_offset]);
|
||||||
|
/* Set the global port from the parent module as the LSB recorded */
|
||||||
|
module_global_port.set_width(global_port_lsbs[module_global_port_offset], global_port_lsbs[module_global_port_offset]);
|
||||||
|
/* Update the LSB */
|
||||||
|
global_port_lsbs[module_global_port_offset]++;
|
||||||
|
|
||||||
|
/* The global ports should match in size */
|
||||||
|
VTR_ASSERT(module_global_port.get_width() == child_global_port.get_width());
|
||||||
|
/* For each pin of the child port, create a net and do wiring */
|
||||||
|
for (size_t pin_id = 0; pin_id < child_global_port.pins().size(); ++pin_id) {
|
||||||
|
/* Reach here, it means this is the port we want, create a net and configure its source and sink */
|
||||||
|
ModuleNetId net = module_manager.create_module_net(module_id);
|
||||||
|
module_manager.add_module_net_source(module_id, net, child, child_instance, child_global_port_id, child_global_port.pins()[pin_id]);
|
||||||
|
module_manager.add_module_net_sink(module_id, net, module_id, 0, module_global_port_id, module_global_port.pins()[pin_id]);
|
||||||
|
/* We finish for this child gpio port */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Find check: all the LSBs of global ports should match the MSB */
|
||||||
|
for (size_t iport = 0; iport < global_port_ids.size(); ++iport) {
|
||||||
|
BasicPort module_global_port = module_manager.module_port(module_id, global_port_ids[iport]);
|
||||||
|
VTR_ASSERT(module_global_port.get_width() == global_port_lsbs[iport]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/********************************************************************
|
||||||
|
* Add global ports to the module:
|
||||||
|
* In this function, we will add global input ports and global output ports
|
||||||
|
* which are collected from the child modules
|
||||||
|
*
|
||||||
|
* - Input ports: the input ports will be uniquified by names
|
||||||
|
* Ports with the same name will be merged to the same pin
|
||||||
|
* See details inside the function
|
||||||
|
*
|
||||||
|
* - Output ports: the output ports will be uniquified by names
|
||||||
|
* Different from the input ports, output ports
|
||||||
|
* with the same name will be merged but will have indepedent pins
|
||||||
|
* See details inside the function
|
||||||
|
*
|
||||||
|
* 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) {
|
||||||
|
/* Input ports */
|
||||||
|
add_module_global_input_ports_from_child_modules(module_manager, module_id);
|
||||||
|
|
||||||
|
/* Output ports */
|
||||||
|
add_module_global_output_ports_from_child_modules(module_manager, module_id);
|
||||||
|
}
|
||||||
|
|
||||||
/********************************************************************
|
/********************************************************************
|
||||||
* Find the number of shared configuration bits for a module
|
* Find the number of shared configuration bits for a module
|
||||||
* by selected the maximum number of shared configuration bits of child modules
|
* by selected the maximum number of shared configuration bits of child modules
|
||||||
|
|
|
@ -108,6 +108,12 @@ size_t find_module_num_config_bits(const ModuleManager& module_manager,
|
||||||
const CircuitModelId& sram_model,
|
const CircuitModelId& sram_model,
|
||||||
const e_config_protocol_type& sram_orgz_type);
|
const e_config_protocol_type& sram_orgz_type);
|
||||||
|
|
||||||
|
void add_module_global_input_ports_from_child_modules(ModuleManager& module_manager,
|
||||||
|
const ModuleId& module_id);
|
||||||
|
|
||||||
|
void add_module_global_output_ports_from_child_modules(ModuleManager& module_manager,
|
||||||
|
const ModuleId& module_id);
|
||||||
|
|
||||||
void add_module_global_ports_from_child_modules(ModuleManager& module_manager,
|
void add_module_global_ports_from_child_modules(ModuleManager& module_manager,
|
||||||
const ModuleId& module_id);
|
const ModuleId& module_id);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue