[core] move new functions to a separated source file
This commit is contained in:
parent
d3aa4c53d0
commit
433391eec4
|
@ -22,6 +22,7 @@
|
|||
#include "build_top_module_memory_bank.h"
|
||||
#include "build_top_module_utils.h"
|
||||
#include "command_exit_codes.h"
|
||||
#include "module_manager_memory_utils.h"
|
||||
#include "module_manager_utils.h"
|
||||
#include "openfpga_device_grid_utils.h"
|
||||
#include "openfpga_naming.h"
|
||||
|
|
|
@ -0,0 +1,563 @@
|
|||
/******************************************************************************
|
||||
* This files includes most utilized functions
|
||||
* for data structures for module management.
|
||||
******************************************************************************/
|
||||
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <map>
|
||||
|
||||
/* Headers from vtrutil library */
|
||||
#include "command_exit_codes.h"
|
||||
#include "vtr_assert.h"
|
||||
#include "vtr_log.h"
|
||||
|
||||
/* Headers from openfpgautil library */
|
||||
#include "build_decoder_modules.h"
|
||||
#include "circuit_library_utils.h"
|
||||
#include "decoder_library_utils.h"
|
||||
#include "memory_utils.h"
|
||||
#include "module_manager_memory_utils.h"
|
||||
#include "module_manager_utils.h"
|
||||
#include "openfpga_naming.h"
|
||||
#include "openfpga_port.h"
|
||||
#include "openfpga_reserved_words.h"
|
||||
#include "pb_type_utils.h"
|
||||
|
||||
/* begin namespace openfpga */
|
||||
namespace openfpga {
|
||||
|
||||
/********************************************************************
|
||||
* Compare the configurable children list with a given list of fabric sub-keys
|
||||
* Return true if exact naming-matches are found
|
||||
* When searching for matching, we consider
|
||||
* - alias is treated as No. 1 reference
|
||||
* - the <name, value> pair as No. 2 reference
|
||||
*******************************************************************/
|
||||
static bool submodule_memory_modules_match_fabric_key(
|
||||
ModuleManager& module_manager, const ModuleId& module_id,
|
||||
const FabricKey& fabric_key, const FabricKeyModuleId& key_module_id) {
|
||||
/* If the length does not match, conclusion is easy to be made */
|
||||
size_t len_module_memory =
|
||||
module_manager.configurable_children(module_id).size();
|
||||
size_t len_fabric_sub_key = fabric_key.sub_keys(key_module_id).size();
|
||||
if (len_module_memory != len_fabric_sub_key) {
|
||||
return false;
|
||||
}
|
||||
/* Now walk through the child one by one */
|
||||
for (size_t ikey = 0; ikey < len_module_memory; ++ikey) {
|
||||
FabricSubKeyId key_id = fabric_key.sub_keys(key_module_id)[ikey];
|
||||
std::pair<ModuleId, size_t> inst_info(ModuleId::INVALID(), 0);
|
||||
/* Try to match the alias */
|
||||
if (!fabric_key.sub_key_alias(key_id).empty()) {
|
||||
if (!fabric_key.sub_key_name(key_id).empty()) {
|
||||
inst_info.first =
|
||||
module_manager.find_module(fabric_key.sub_key_name(key_id));
|
||||
inst_info.second = module_manager.instance_id(
|
||||
module_id, inst_info.first, fabric_key.sub_key_alias(key_id));
|
||||
} else {
|
||||
inst_info = find_module_manager_instance_module_info(
|
||||
module_manager, module_id, fabric_key.sub_key_alias(key_id));
|
||||
}
|
||||
} else {
|
||||
inst_info.first =
|
||||
module_manager.find_module(fabric_key.sub_key_name(key_id));
|
||||
inst_info.second = fabric_key.sub_key_value(key_id);
|
||||
}
|
||||
if (inst_info.first !=
|
||||
module_manager.configurable_children(module_id)[ikey] ||
|
||||
inst_info.second !=
|
||||
module_manager.configurable_child_instances(module_id)[ikey]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
* Update the configurable children list based on fabric key definitions
|
||||
*******************************************************************/
|
||||
static bool update_submodule_memory_modules_from_fabric_key(
|
||||
ModuleManager& module_manager, const ModuleId& module_id,
|
||||
const CircuitLibrary& circuit_lib, const ConfigProtocol& config_protocol,
|
||||
const FabricKey& fabric_key, const FabricKeyModuleId& key_module_id) {
|
||||
/* Reset the configurable children */
|
||||
module_manager.clear_configurable_children(module_id);
|
||||
|
||||
for (FabricSubKeyId key_id : fabric_key.sub_keys(key_module_id)) {
|
||||
std::pair<ModuleId, size_t> inst_info(ModuleId::INVALID(), 0);
|
||||
/* Try to match the alias */
|
||||
if (!fabric_key.sub_key_alias(key_id).empty()) {
|
||||
if (!fabric_key.sub_key_name(key_id).empty()) {
|
||||
inst_info.first =
|
||||
module_manager.find_module(fabric_key.sub_key_name(key_id));
|
||||
inst_info.second = module_manager.instance_id(
|
||||
module_id, inst_info.first, fabric_key.sub_key_alias(key_id));
|
||||
} else {
|
||||
inst_info = find_module_manager_instance_module_info(
|
||||
module_manager, module_id, fabric_key.sub_key_alias(key_id));
|
||||
}
|
||||
} else {
|
||||
inst_info.first =
|
||||
module_manager.find_module(fabric_key.sub_key_name(key_id));
|
||||
inst_info.second = fabric_key.sub_key_value(key_id);
|
||||
}
|
||||
if (false == module_manager.valid_module_id(inst_info.first)) {
|
||||
if (!fabric_key.sub_key_alias(key_id).empty()) {
|
||||
VTR_LOG_ERROR("Invalid key alias '%s'!\n",
|
||||
fabric_key.sub_key_alias(key_id).c_str());
|
||||
} else {
|
||||
VTR_LOG_ERROR("Invalid key name '%s'!\n",
|
||||
fabric_key.sub_key_name(key_id).c_str());
|
||||
}
|
||||
return CMD_EXEC_FATAL_ERROR;
|
||||
}
|
||||
|
||||
if (false == module_manager.valid_module_instance_id(
|
||||
module_id, inst_info.first, inst_info.second)) {
|
||||
if (!fabric_key.sub_key_alias(key_id).empty()) {
|
||||
VTR_LOG_ERROR("Invalid key alias '%s'!\n",
|
||||
fabric_key.sub_key_alias(key_id).c_str());
|
||||
} else {
|
||||
VTR_LOG_ERROR("Invalid key value '%ld'!\n", inst_info.second);
|
||||
}
|
||||
return CMD_EXEC_FATAL_ERROR;
|
||||
}
|
||||
|
||||
/* If the the child has not configuration bits, error out */
|
||||
if (0 == find_module_num_config_bits(
|
||||
module_manager, inst_info.first, circuit_lib,
|
||||
config_protocol.memory_model(), config_protocol.type())) {
|
||||
if (!fabric_key.sub_key_alias(key_id).empty()) {
|
||||
VTR_LOG_ERROR(
|
||||
"Invalid key alias '%s' which has zero configuration bits!\n",
|
||||
fabric_key.sub_key_alias(key_id).c_str());
|
||||
} else {
|
||||
VTR_LOG_ERROR(
|
||||
"Invalid key name '%s' which has zero configuration bits!\n",
|
||||
fabric_key.sub_key_name(key_id).c_str());
|
||||
}
|
||||
return CMD_EXEC_FATAL_ERROR;
|
||||
}
|
||||
|
||||
/* Now we can add the child to configurable children of the top module */
|
||||
module_manager.add_configurable_child(module_id, inst_info.first,
|
||||
inst_info.second, vtr::Point<int>());
|
||||
}
|
||||
return CMD_EXEC_SUCCESS;
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
* Remove the nets around the configuration chain (ccff_head and ccff_tails)
|
||||
*******************************************************************/
|
||||
static int remove_submodule_nets_cmos_memory_chain_config_bus(
|
||||
ModuleManager& module_manager, const ModuleId& parent_module,
|
||||
const e_config_protocol_type& sram_orgz_type) {
|
||||
for (size_t mem_index = 0;
|
||||
mem_index < module_manager.configurable_children(parent_module).size();
|
||||
++mem_index) {
|
||||
ModuleId net_src_module_id;
|
||||
size_t net_src_instance_id;
|
||||
ModulePortId net_src_port_id;
|
||||
|
||||
if (0 == mem_index) {
|
||||
/* Find the port name of configuration chain head */
|
||||
std::string src_port_name =
|
||||
generate_sram_port_name(sram_orgz_type, CIRCUIT_MODEL_PORT_INPUT);
|
||||
net_src_module_id = parent_module;
|
||||
net_src_instance_id = 0;
|
||||
net_src_port_id =
|
||||
module_manager.find_module_port(net_src_module_id, src_port_name);
|
||||
} else {
|
||||
/* Find the port name of previous memory module */
|
||||
std::string src_port_name = generate_configuration_chain_tail_name();
|
||||
net_src_module_id =
|
||||
module_manager.configurable_children(parent_module)[mem_index - 1];
|
||||
net_src_instance_id = module_manager.configurable_child_instances(
|
||||
parent_module)[mem_index - 1];
|
||||
net_src_port_id =
|
||||
module_manager.find_module_port(net_src_module_id, src_port_name);
|
||||
}
|
||||
|
||||
/* Get the pin id for source port */
|
||||
BasicPort net_src_port =
|
||||
module_manager.module_port(net_src_module_id, net_src_port_id);
|
||||
|
||||
/* Create a net for each pin */
|
||||
for (size_t pin_id = 0; pin_id < net_src_port.pins().size(); ++pin_id) {
|
||||
/* Find the net from which the source node is driving */
|
||||
ModuleNetId net = module_manager.module_instance_port_net(
|
||||
parent_module, net_src_module_id, net_src_instance_id, net_src_port_id,
|
||||
net_src_port.pins()[pin_id]);
|
||||
/* Remove the net including sources and sinks */
|
||||
module_manager.clear_module_net_sinks(parent_module, net);
|
||||
}
|
||||
}
|
||||
|
||||
/* For the last memory module:
|
||||
* net source is the configuration chain tail of the previous memory module
|
||||
* net sink is the configuration chain tail of the primitive module
|
||||
*/
|
||||
/* Find the port name of previous memory module */
|
||||
std::string src_port_name = generate_configuration_chain_tail_name();
|
||||
ModuleId net_src_module_id =
|
||||
module_manager.configurable_children(parent_module).back();
|
||||
size_t net_src_instance_id =
|
||||
module_manager.configurable_child_instances(parent_module).back();
|
||||
ModulePortId net_src_port_id =
|
||||
module_manager.find_module_port(net_src_module_id, src_port_name);
|
||||
|
||||
/* Get the pin id for source port */
|
||||
BasicPort net_src_port =
|
||||
module_manager.module_port(net_src_module_id, net_src_port_id);
|
||||
|
||||
/* Create a net for each pin */
|
||||
for (size_t pin_id = 0; pin_id < net_src_port.pins().size(); ++pin_id) {
|
||||
/* Find the net from which the source node is driving */
|
||||
ModuleNetId net = module_manager.module_instance_port_net(
|
||||
parent_module, net_src_module_id, net_src_instance_id, net_src_port_id,
|
||||
net_src_port.pins()[pin_id]);
|
||||
/* Remove the net including sources and sinks */
|
||||
module_manager.clear_module_net_sinks(parent_module, net);
|
||||
}
|
||||
return CMD_EXEC_SUCCESS;
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
* Remove the nets around the configurable children for a given module which
|
||||
*should be in CMOS type
|
||||
*******************************************************************/
|
||||
static int remove_submodule_nets_cmos_memory_config_bus(
|
||||
ModuleManager& module_manager, const ModuleId& module_id,
|
||||
const e_config_protocol_type& sram_orgz_type) {
|
||||
switch (sram_orgz_type) {
|
||||
case CONFIG_MEM_SCAN_CHAIN: {
|
||||
return remove_submodule_nets_cmos_memory_chain_config_bus(
|
||||
module_manager, module_id, sram_orgz_type);
|
||||
break;
|
||||
}
|
||||
case CONFIG_MEM_STANDALONE:
|
||||
case CONFIG_MEM_QL_MEMORY_BANK:
|
||||
/* TODO:
|
||||
add_module_nets_cmos_memory_bank_bl_config_bus(
|
||||
module_manager, parent_module, sram_orgz_type, CIRCUIT_MODEL_PORT_BL);
|
||||
add_module_nets_cmos_memory_bank_wl_config_bus(
|
||||
module_manager, parent_module, sram_orgz_type, CIRCUIT_MODEL_PORT_WL);
|
||||
add_module_nets_cmos_memory_bank_wl_config_bus(
|
||||
module_manager, parent_module, sram_orgz_type, CIRCUIT_MODEL_PORT_WLR);
|
||||
*/
|
||||
break;
|
||||
case CONFIG_MEM_MEMORY_BANK:
|
||||
/* TODO:
|
||||
add_module_nets_cmos_flatten_memory_config_bus(
|
||||
module_manager, parent_module, sram_orgz_type, CIRCUIT_MODEL_PORT_BL);
|
||||
add_module_nets_cmos_flatten_memory_config_bus(
|
||||
module_manager, parent_module, sram_orgz_type, CIRCUIT_MODEL_PORT_WL);
|
||||
*/
|
||||
break;
|
||||
case CONFIG_MEM_FRAME_BASED:
|
||||
/* TODO:
|
||||
add_module_nets_cmos_memory_frame_config_bus(module_manager, decoder_lib,
|
||||
parent_module);
|
||||
*/
|
||||
break;
|
||||
default:
|
||||
VTR_LOGF_ERROR(__FILE__, __LINE__,
|
||||
"Invalid type of SRAM organization!\n");
|
||||
return CMD_EXEC_FATAL_ERROR;
|
||||
}
|
||||
return CMD_EXEC_FATAL_ERROR;
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
* Remove the nets around the configurable children for a given module
|
||||
*******************************************************************/
|
||||
static int remove_submodule_configurable_children_nets(
|
||||
ModuleManager& module_manager, const ModuleId& module_id,
|
||||
const CircuitLibrary& circuit_lib, const ConfigProtocol& config_protocol) {
|
||||
switch (circuit_lib.design_tech_type(config_protocol.memory_model())) {
|
||||
case CIRCUIT_MODEL_DESIGN_CMOS:
|
||||
return remove_submodule_nets_cmos_memory_config_bus(
|
||||
module_manager, module_id, config_protocol.type());
|
||||
break;
|
||||
case CIRCUIT_MODEL_DESIGN_RRAM:
|
||||
/* TODO: */
|
||||
break;
|
||||
default:
|
||||
VTR_LOGF_ERROR(__FILE__, __LINE__,
|
||||
"Invalid type of memory design technology!\n");
|
||||
return CMD_EXEC_FATAL_ERROR;
|
||||
}
|
||||
return CMD_EXEC_FATAL_ERROR;
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
* Rebuild the nets(only sinks) around the configuration chain (ccff_head and
|
||||
*ccff_tails)
|
||||
*******************************************************************/
|
||||
static int rebuild_submodule_nets_cmos_memory_chain_config_bus(
|
||||
ModuleManager& module_manager, const ModuleId& parent_module,
|
||||
const e_config_protocol_type& sram_orgz_type) {
|
||||
for (size_t mem_index = 0;
|
||||
mem_index < module_manager.configurable_children(parent_module).size();
|
||||
++mem_index) {
|
||||
ModuleId net_src_module_id;
|
||||
size_t net_src_instance_id;
|
||||
ModulePortId net_src_port_id;
|
||||
|
||||
ModuleId net_sink_module_id;
|
||||
size_t net_sink_instance_id;
|
||||
ModulePortId net_sink_port_id;
|
||||
|
||||
if (0 == mem_index) {
|
||||
/* Find the port name of configuration chain head */
|
||||
std::string src_port_name =
|
||||
generate_sram_port_name(sram_orgz_type, CIRCUIT_MODEL_PORT_INPUT);
|
||||
net_src_module_id = parent_module;
|
||||
net_src_instance_id = 0;
|
||||
net_src_port_id =
|
||||
module_manager.find_module_port(net_src_module_id, src_port_name);
|
||||
|
||||
/* Find the port name of next memory module */
|
||||
std::string sink_port_name = generate_configuration_chain_head_name();
|
||||
net_sink_module_id =
|
||||
module_manager.configurable_children(parent_module)[mem_index];
|
||||
net_sink_instance_id =
|
||||
module_manager.configurable_child_instances(parent_module)[mem_index];
|
||||
net_sink_port_id =
|
||||
module_manager.find_module_port(net_sink_module_id, sink_port_name);
|
||||
} else {
|
||||
/* Find the port name of previous memory module */
|
||||
std::string src_port_name = generate_configuration_chain_tail_name();
|
||||
net_src_module_id =
|
||||
module_manager.configurable_children(parent_module)[mem_index - 1];
|
||||
net_src_instance_id = module_manager.configurable_child_instances(
|
||||
parent_module)[mem_index - 1];
|
||||
net_src_port_id =
|
||||
module_manager.find_module_port(net_src_module_id, src_port_name);
|
||||
|
||||
/* Find the port name of next memory module */
|
||||
std::string sink_port_name = generate_configuration_chain_head_name();
|
||||
net_sink_module_id =
|
||||
module_manager.configurable_children(parent_module)[mem_index];
|
||||
net_sink_instance_id =
|
||||
module_manager.configurable_child_instances(parent_module)[mem_index];
|
||||
net_sink_port_id =
|
||||
module_manager.find_module_port(net_sink_module_id, sink_port_name);
|
||||
}
|
||||
|
||||
/* Get the pin id for source port */
|
||||
BasicPort net_src_port =
|
||||
module_manager.module_port(net_src_module_id, net_src_port_id);
|
||||
/* Get the pin id for sink port */
|
||||
BasicPort net_sink_port =
|
||||
module_manager.module_port(net_sink_module_id, net_sink_port_id);
|
||||
/* Port sizes of source and sink should match */
|
||||
VTR_ASSERT(net_src_port.get_width() == net_sink_port.get_width());
|
||||
|
||||
/* Create a net for each pin */
|
||||
for (size_t pin_id = 0; pin_id < net_src_port.pins().size(); ++pin_id) {
|
||||
/* Create a net and add source and sink to it */
|
||||
ModuleNetId net = create_module_source_pin_net(
|
||||
module_manager, parent_module, net_src_module_id, net_src_instance_id,
|
||||
net_src_port_id, net_src_port.pins()[pin_id]);
|
||||
/* Add net sink */
|
||||
module_manager.add_module_net_sink(parent_module, net, net_sink_module_id,
|
||||
net_sink_instance_id, net_sink_port_id,
|
||||
net_sink_port.pins()[pin_id]);
|
||||
}
|
||||
}
|
||||
|
||||
/* For the last memory module:
|
||||
* net source is the configuration chain tail of the previous memory module
|
||||
* net sink is the configuration chain tail of the primitive module
|
||||
*/
|
||||
/* Find the port name of previous memory module */
|
||||
std::string src_port_name = generate_configuration_chain_tail_name();
|
||||
ModuleId net_src_module_id =
|
||||
module_manager.configurable_children(parent_module).back();
|
||||
size_t net_src_instance_id =
|
||||
module_manager.configurable_child_instances(parent_module).back();
|
||||
ModulePortId net_src_port_id =
|
||||
module_manager.find_module_port(net_src_module_id, src_port_name);
|
||||
|
||||
/* Find the port name of next memory module */
|
||||
std::string sink_port_name =
|
||||
generate_sram_port_name(sram_orgz_type, CIRCUIT_MODEL_PORT_OUTPUT);
|
||||
ModuleId net_sink_module_id = parent_module;
|
||||
size_t net_sink_instance_id = 0;
|
||||
ModulePortId net_sink_port_id =
|
||||
module_manager.find_module_port(net_sink_module_id, sink_port_name);
|
||||
|
||||
/* Get the pin id for source port */
|
||||
BasicPort net_src_port =
|
||||
module_manager.module_port(net_src_module_id, net_src_port_id);
|
||||
/* Get the pin id for sink port */
|
||||
BasicPort net_sink_port =
|
||||
module_manager.module_port(net_sink_module_id, net_sink_port_id);
|
||||
/* Port sizes of source and sink should match */
|
||||
VTR_ASSERT(net_src_port.get_width() == net_sink_port.get_width());
|
||||
|
||||
/* Create a net for each pin */
|
||||
for (size_t pin_id = 0; pin_id < net_src_port.pins().size(); ++pin_id) {
|
||||
/* Create a net and add source and sink to it */
|
||||
ModuleNetId net = create_module_source_pin_net(
|
||||
module_manager, parent_module, net_src_module_id, net_src_instance_id,
|
||||
net_src_port_id, net_src_port.pins()[pin_id]);
|
||||
/* Add net sink */
|
||||
module_manager.add_module_net_sink(parent_module, net, net_sink_module_id,
|
||||
net_sink_instance_id, net_sink_port_id,
|
||||
net_sink_port.pins()[pin_id]);
|
||||
}
|
||||
return CMD_EXEC_SUCCESS;
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
* Rebuild the nets around the configurable children for a given module which
|
||||
*should be in CMOS type
|
||||
*******************************************************************/
|
||||
static int rebuild_submodule_nets_cmos_memory_config_bus(
|
||||
ModuleManager& module_manager, const ModuleId& module_id,
|
||||
const e_config_protocol_type& sram_orgz_type) {
|
||||
switch (sram_orgz_type) {
|
||||
case CONFIG_MEM_SCAN_CHAIN: {
|
||||
return rebuild_submodule_nets_cmos_memory_chain_config_bus(
|
||||
module_manager, module_id, sram_orgz_type);
|
||||
break;
|
||||
}
|
||||
case CONFIG_MEM_STANDALONE:
|
||||
case CONFIG_MEM_QL_MEMORY_BANK:
|
||||
/* TODO:
|
||||
add_module_nets_cmos_memory_bank_bl_config_bus(
|
||||
module_manager, parent_module, sram_orgz_type, CIRCUIT_MODEL_PORT_BL);
|
||||
add_module_nets_cmos_memory_bank_wl_config_bus(
|
||||
module_manager, parent_module, sram_orgz_type, CIRCUIT_MODEL_PORT_WL);
|
||||
add_module_nets_cmos_memory_bank_wl_config_bus(
|
||||
module_manager, parent_module, sram_orgz_type, CIRCUIT_MODEL_PORT_WLR);
|
||||
*/
|
||||
break;
|
||||
case CONFIG_MEM_MEMORY_BANK:
|
||||
/* TODO:
|
||||
add_module_nets_cmos_flatten_memory_config_bus(
|
||||
module_manager, parent_module, sram_orgz_type, CIRCUIT_MODEL_PORT_BL);
|
||||
add_module_nets_cmos_flatten_memory_config_bus(
|
||||
module_manager, parent_module, sram_orgz_type, CIRCUIT_MODEL_PORT_WL);
|
||||
*/
|
||||
break;
|
||||
case CONFIG_MEM_FRAME_BASED:
|
||||
/* TODO:
|
||||
add_module_nets_cmos_memory_frame_config_bus(module_manager, decoder_lib,
|
||||
parent_module);
|
||||
*/
|
||||
break;
|
||||
default:
|
||||
VTR_LOGF_ERROR(__FILE__, __LINE__,
|
||||
"Invalid type of SRAM organization!\n");
|
||||
return CMD_EXEC_FATAL_ERROR;
|
||||
}
|
||||
return CMD_EXEC_FATAL_ERROR;
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
* Rebuild the nets(only sinks) around the configurable children for a given
|
||||
*module
|
||||
*******************************************************************/
|
||||
static int rebuild_submodule_configurable_children_nets(
|
||||
ModuleManager& module_manager, const ModuleId& module_id,
|
||||
const CircuitLibrary& circuit_lib, const ConfigProtocol& config_protocol) {
|
||||
switch (circuit_lib.design_tech_type(config_protocol.memory_model())) {
|
||||
case CIRCUIT_MODEL_DESIGN_CMOS:
|
||||
return rebuild_submodule_nets_cmos_memory_config_bus(
|
||||
module_manager, module_id, config_protocol.type());
|
||||
break;
|
||||
case CIRCUIT_MODEL_DESIGN_RRAM:
|
||||
/* TODO: */
|
||||
break;
|
||||
default:
|
||||
VTR_LOGF_ERROR(__FILE__, __LINE__,
|
||||
"Invalid type of memory design technology!\n");
|
||||
return CMD_EXEC_FATAL_ERROR;
|
||||
}
|
||||
return CMD_EXEC_FATAL_ERROR;
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
* Load and update the configurable children of a given module (not a top-level
|
||||
*module) Compare the configurable children list with fabric sub-keys.
|
||||
* - If match, nothing should be done
|
||||
* - If not match,
|
||||
* - remove the nets related to configurable children
|
||||
* - rebuild the configurable children list
|
||||
* - add the nets related to configurable children
|
||||
*******************************************************************/
|
||||
static int load_and_update_submodule_memory_modules_from_fabric_key(
|
||||
ModuleManager& module_manager, const ModuleId& module_id,
|
||||
const CircuitLibrary& circuit_lib, const ConfigProtocol& config_protocol,
|
||||
const FabricKey& fabric_key, const FabricKeyModuleId& key_module_id) {
|
||||
int status = CMD_EXEC_SUCCESS;
|
||||
/* Compare the configurable children list */
|
||||
if (submodule_memory_modules_match_fabric_key(module_manager, module_id,
|
||||
fabric_key, key_module_id)) {
|
||||
return CMD_EXEC_SUCCESS;
|
||||
}
|
||||
/* Do not match, now remove all the nets for the configurable children */
|
||||
status = remove_submodule_configurable_children_nets(
|
||||
module_manager, module_id, circuit_lib, config_protocol);
|
||||
if (status == CMD_EXEC_FATAL_ERROR) {
|
||||
return status;
|
||||
}
|
||||
/* Overwrite the configurable children list */
|
||||
status = update_submodule_memory_modules_from_fabric_key(
|
||||
module_manager, module_id, circuit_lib, config_protocol, fabric_key,
|
||||
key_module_id);
|
||||
if (status == CMD_EXEC_FATAL_ERROR) {
|
||||
return status;
|
||||
}
|
||||
/* TODO: Create the nets for the new list of configurable children */
|
||||
status = rebuild_submodule_configurable_children_nets(
|
||||
module_manager, module_id, circuit_lib, config_protocol);
|
||||
if (status == CMD_EXEC_FATAL_ERROR) {
|
||||
return status;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
* Load and update the configurable children of a given list of modules (not a
|
||||
*top-level module)
|
||||
*******************************************************************/
|
||||
int load_submodules_memory_modules_from_fabric_key(
|
||||
ModuleManager& module_manager, const CircuitLibrary& circuit_lib,
|
||||
const ConfigProtocol& config_protocol, const FabricKey& fabric_key) {
|
||||
int status = CMD_EXEC_SUCCESS;
|
||||
for (FabricKeyModuleId key_module_id : fabric_key.modules()) {
|
||||
std::string module_name = fabric_key.module_name(key_module_id);
|
||||
/* Ensure this is not a top module! */
|
||||
if (module_name == std::string(FPGA_TOP_MODULE_NAME)) {
|
||||
VTR_LOG_ERROR(
|
||||
"Expect a non-top-level name for the sub-module '%s' in fabric key!\n",
|
||||
module_name.c_str());
|
||||
return CMD_EXEC_FATAL_ERROR;
|
||||
}
|
||||
ModuleId module_id = module_manager.find_module(module_name);
|
||||
if (module_id) {
|
||||
/* This is a valid module, try to load and update */
|
||||
status = load_and_update_submodule_memory_modules_from_fabric_key(
|
||||
module_manager, module_id, circuit_lib, config_protocol, fabric_key,
|
||||
key_module_id);
|
||||
if (status == CMD_EXEC_FATAL_ERROR) {
|
||||
return status;
|
||||
}
|
||||
} else {
|
||||
/* Not a valid module, report error */
|
||||
VTR_LOG_ERROR(
|
||||
"The sub-module '%s' in fabric key is not a valid module in FPGA "
|
||||
"fabric!\n",
|
||||
module_name.c_str());
|
||||
return CMD_EXEC_FATAL_ERROR;
|
||||
}
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
} /* end namespace openfpga */
|
|
@ -0,0 +1,41 @@
|
|||
/******************************************************************************
|
||||
* This files includes declarations for most utilized functions
|
||||
* for data structures for module management.
|
||||
******************************************************************************/
|
||||
#ifndef MODULE_MANAGER_MEMORY_UTILS_H
|
||||
#define MODULE_MANAGER_MEMORY_UTILS_H
|
||||
|
||||
/********************************************************************
|
||||
* Include header files that are required by function declaration
|
||||
*******************************************************************/
|
||||
#include <tuple>
|
||||
#include <vector>
|
||||
|
||||
/* Headers from readarch library */
|
||||
#include "physical_types.h"
|
||||
|
||||
/* Headers from openfpgautil library */
|
||||
#include "openfpga_port.h"
|
||||
|
||||
/* Headers from readarchopenfpga library */
|
||||
#include "circuit_library.h"
|
||||
#include "circuit_types.h"
|
||||
#include "config_protocol.h"
|
||||
#include "decoder_library.h"
|
||||
#include "fabric_key.h"
|
||||
#include "module_manager.h"
|
||||
|
||||
/********************************************************************
|
||||
* Function declaration
|
||||
*******************************************************************/
|
||||
|
||||
/* begin namespace openfpga */
|
||||
namespace openfpga {
|
||||
|
||||
int load_submodules_memory_modules_from_fabric_key(
|
||||
ModuleManager& module_manager, const CircuitLibrary& circuit_lib,
|
||||
const ConfigProtocol& config_protocol, const FabricKey& fabric_key);
|
||||
|
||||
} /* end namespace openfpga */
|
||||
|
||||
#endif
|
|
@ -2532,531 +2532,4 @@ void add_module_bus_nets(
|
|||
*
|
||||
*******************************************************************/
|
||||
|
||||
/********************************************************************
|
||||
* Compare the configurable children list with a given list of fabric sub-keys
|
||||
* Return true if exact naming-matches are found
|
||||
* When searching for matching, we consider
|
||||
* - alias is treated as No. 1 reference
|
||||
* - the <name, value> pair as No. 2 reference
|
||||
*******************************************************************/
|
||||
static bool submodule_memory_modules_match_fabric_key(
|
||||
ModuleManager& module_manager, const ModuleId& module_id,
|
||||
const FabricKey& fabric_key, const FabricKeyModuleId& key_module_id) {
|
||||
/* If the length does not match, conclusion is easy to be made */
|
||||
size_t len_module_memory =
|
||||
module_manager.configurable_children(module_id).size();
|
||||
size_t len_fabric_sub_key = fabric_key.sub_keys(key_module_id).size();
|
||||
if (len_module_memory != len_fabric_sub_key) {
|
||||
return false;
|
||||
}
|
||||
/* Now walk through the child one by one */
|
||||
for (size_t ikey = 0; ikey < len_module_memory; ++ikey) {
|
||||
FabricSubKeyId key_id = fabric_key.sub_keys(key_module_id)[ikey];
|
||||
std::pair<ModuleId, size_t> inst_info(ModuleId::INVALID(), 0);
|
||||
/* Try to match the alias */
|
||||
if (!fabric_key.sub_key_alias(key_id).empty()) {
|
||||
if (!fabric_key.sub_key_name(key_id).empty()) {
|
||||
inst_info.first =
|
||||
module_manager.find_module(fabric_key.sub_key_name(key_id));
|
||||
inst_info.second = module_manager.instance_id(
|
||||
module_id, inst_info.first, fabric_key.sub_key_alias(key_id));
|
||||
} else {
|
||||
inst_info = find_module_manager_instance_module_info(
|
||||
module_manager, module_id, fabric_key.sub_key_alias(key_id));
|
||||
}
|
||||
} else {
|
||||
inst_info.first =
|
||||
module_manager.find_module(fabric_key.sub_key_name(key_id));
|
||||
inst_info.second = fabric_key.sub_key_value(key_id);
|
||||
}
|
||||
if (inst_info.first !=
|
||||
module_manager.configurable_children(module_id)[ikey] ||
|
||||
inst_info.second !=
|
||||
module_manager.configurable_child_instances(module_id)[ikey]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
* Update the configurable children list based on fabric key definitions
|
||||
*******************************************************************/
|
||||
static bool update_submodule_memory_modules_from_fabric_key(
|
||||
ModuleManager& module_manager, const ModuleId& module_id,
|
||||
const CircuitLibrary& circuit_lib, const ConfigProtocol& config_protocol,
|
||||
const FabricKey& fabric_key, const FabricKeyModuleId& key_module_id) {
|
||||
/* Reset the configurable children */
|
||||
module_manager.clear_configurable_children(module_id);
|
||||
|
||||
for (FabricSubKeyId key_id : fabric_key.sub_keys(key_module_id)) {
|
||||
std::pair<ModuleId, size_t> inst_info(ModuleId::INVALID(), 0);
|
||||
/* Try to match the alias */
|
||||
if (!fabric_key.sub_key_alias(key_id).empty()) {
|
||||
if (!fabric_key.sub_key_name(key_id).empty()) {
|
||||
inst_info.first =
|
||||
module_manager.find_module(fabric_key.sub_key_name(key_id));
|
||||
inst_info.second = module_manager.instance_id(
|
||||
module_id, inst_info.first, fabric_key.sub_key_alias(key_id));
|
||||
} else {
|
||||
inst_info = find_module_manager_instance_module_info(
|
||||
module_manager, module_id, fabric_key.sub_key_alias(key_id));
|
||||
}
|
||||
} else {
|
||||
inst_info.first =
|
||||
module_manager.find_module(fabric_key.sub_key_name(key_id));
|
||||
inst_info.second = fabric_key.sub_key_value(key_id);
|
||||
}
|
||||
if (false == module_manager.valid_module_id(inst_info.first)) {
|
||||
if (!fabric_key.sub_key_alias(key_id).empty()) {
|
||||
VTR_LOG_ERROR("Invalid key alias '%s'!\n",
|
||||
fabric_key.sub_key_alias(key_id).c_str());
|
||||
} else {
|
||||
VTR_LOG_ERROR("Invalid key name '%s'!\n",
|
||||
fabric_key.sub_key_name(key_id).c_str());
|
||||
}
|
||||
return CMD_EXEC_FATAL_ERROR;
|
||||
}
|
||||
|
||||
if (false == module_manager.valid_module_instance_id(
|
||||
module_id, inst_info.first, inst_info.second)) {
|
||||
if (!fabric_key.sub_key_alias(key_id).empty()) {
|
||||
VTR_LOG_ERROR("Invalid key alias '%s'!\n",
|
||||
fabric_key.sub_key_alias(key_id).c_str());
|
||||
} else {
|
||||
VTR_LOG_ERROR("Invalid key value '%ld'!\n", inst_info.second);
|
||||
}
|
||||
return CMD_EXEC_FATAL_ERROR;
|
||||
}
|
||||
|
||||
/* If the the child has not configuration bits, error out */
|
||||
if (0 == find_module_num_config_bits(
|
||||
module_manager, inst_info.first, circuit_lib,
|
||||
config_protocol.memory_model(), config_protocol.type())) {
|
||||
if (!fabric_key.sub_key_alias(key_id).empty()) {
|
||||
VTR_LOG_ERROR(
|
||||
"Invalid key alias '%s' which has zero configuration bits!\n",
|
||||
fabric_key.sub_key_alias(key_id).c_str());
|
||||
} else {
|
||||
VTR_LOG_ERROR(
|
||||
"Invalid key name '%s' which has zero configuration bits!\n",
|
||||
fabric_key.sub_key_name(key_id).c_str());
|
||||
}
|
||||
return CMD_EXEC_FATAL_ERROR;
|
||||
}
|
||||
|
||||
/* Now we can add the child to configurable children of the top module */
|
||||
module_manager.add_configurable_child(module_id, inst_info.first,
|
||||
inst_info.second, vtr::Point<int>());
|
||||
}
|
||||
return CMD_EXEC_SUCCESS;
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
* Remove the nets around the configuration chain (ccff_head and ccff_tails)
|
||||
*******************************************************************/
|
||||
static int remove_submodule_nets_cmos_memory_chain_config_bus(
|
||||
ModuleManager& module_manager, const ModuleId& parent_module,
|
||||
const e_config_protocol_type& sram_orgz_type) {
|
||||
for (size_t mem_index = 0;
|
||||
mem_index < module_manager.configurable_children(parent_module).size();
|
||||
++mem_index) {
|
||||
ModuleId net_src_module_id;
|
||||
size_t net_src_instance_id;
|
||||
ModulePortId net_src_port_id;
|
||||
|
||||
if (0 == mem_index) {
|
||||
/* Find the port name of configuration chain head */
|
||||
std::string src_port_name =
|
||||
generate_sram_port_name(sram_orgz_type, CIRCUIT_MODEL_PORT_INPUT);
|
||||
net_src_module_id = parent_module;
|
||||
net_src_instance_id = 0;
|
||||
net_src_port_id =
|
||||
module_manager.find_module_port(net_src_module_id, src_port_name);
|
||||
} else {
|
||||
/* Find the port name of previous memory module */
|
||||
std::string src_port_name = generate_configuration_chain_tail_name();
|
||||
net_src_module_id =
|
||||
module_manager.configurable_children(parent_module)[mem_index - 1];
|
||||
net_src_instance_id = module_manager.configurable_child_instances(
|
||||
parent_module)[mem_index - 1];
|
||||
net_src_port_id =
|
||||
module_manager.find_module_port(net_src_module_id, src_port_name);
|
||||
}
|
||||
|
||||
/* Get the pin id for source port */
|
||||
BasicPort net_src_port =
|
||||
module_manager.module_port(net_src_module_id, net_src_port_id);
|
||||
|
||||
/* Create a net for each pin */
|
||||
for (size_t pin_id = 0; pin_id < net_src_port.pins().size(); ++pin_id) {
|
||||
/* Find the net from which the source node is driving */
|
||||
ModuleNetId net = module_manager.module_instance_port_net(
|
||||
parent_module, net_src_module_id, net_src_instance_id, net_src_port_id,
|
||||
net_src_port.pins()[pin_id]);
|
||||
/* Remove the net including sources and sinks */
|
||||
module_manager.clear_module_net_sinks(parent_module, net);
|
||||
}
|
||||
}
|
||||
|
||||
/* For the last memory module:
|
||||
* net source is the configuration chain tail of the previous memory module
|
||||
* net sink is the configuration chain tail of the primitive module
|
||||
*/
|
||||
/* Find the port name of previous memory module */
|
||||
std::string src_port_name = generate_configuration_chain_tail_name();
|
||||
ModuleId net_src_module_id =
|
||||
module_manager.configurable_children(parent_module).back();
|
||||
size_t net_src_instance_id =
|
||||
module_manager.configurable_child_instances(parent_module).back();
|
||||
ModulePortId net_src_port_id =
|
||||
module_manager.find_module_port(net_src_module_id, src_port_name);
|
||||
|
||||
/* Get the pin id for source port */
|
||||
BasicPort net_src_port =
|
||||
module_manager.module_port(net_src_module_id, net_src_port_id);
|
||||
|
||||
/* Create a net for each pin */
|
||||
for (size_t pin_id = 0; pin_id < net_src_port.pins().size(); ++pin_id) {
|
||||
/* Find the net from which the source node is driving */
|
||||
ModuleNetId net = module_manager.module_instance_port_net(
|
||||
parent_module, net_src_module_id, net_src_instance_id,
|
||||
net_src_port_id, net_src_port.pins()[pin_id]);
|
||||
/* Remove the net including sources and sinks */
|
||||
module_manager.clear_module_net_sinks(parent_module, net);
|
||||
}
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
* Remove the nets around the configurable children for a given module which
|
||||
*should be in CMOS type
|
||||
*******************************************************************/
|
||||
static int remove_submodule_nets_cmos_memory_config_bus(
|
||||
ModuleManager& module_manager, const ModuleId& module_id,
|
||||
const e_config_protocol_type& sram_orgz_type) {
|
||||
switch (sram_orgz_type) {
|
||||
case CONFIG_MEM_SCAN_CHAIN: {
|
||||
remove_submodule_nets_cmos_memory_chain_config_bus(module_manager, module_id,
|
||||
sram_orgz_type);
|
||||
break;
|
||||
}
|
||||
case CONFIG_MEM_STANDALONE:
|
||||
case CONFIG_MEM_QL_MEMORY_BANK:
|
||||
/* TODO:
|
||||
add_module_nets_cmos_memory_bank_bl_config_bus(
|
||||
module_manager, parent_module, sram_orgz_type, CIRCUIT_MODEL_PORT_BL);
|
||||
add_module_nets_cmos_memory_bank_wl_config_bus(
|
||||
module_manager, parent_module, sram_orgz_type, CIRCUIT_MODEL_PORT_WL);
|
||||
add_module_nets_cmos_memory_bank_wl_config_bus(
|
||||
module_manager, parent_module, sram_orgz_type, CIRCUIT_MODEL_PORT_WLR);
|
||||
*/
|
||||
break;
|
||||
case CONFIG_MEM_MEMORY_BANK:
|
||||
/* TODO:
|
||||
add_module_nets_cmos_flatten_memory_config_bus(
|
||||
module_manager, parent_module, sram_orgz_type, CIRCUIT_MODEL_PORT_BL);
|
||||
add_module_nets_cmos_flatten_memory_config_bus(
|
||||
module_manager, parent_module, sram_orgz_type, CIRCUIT_MODEL_PORT_WL);
|
||||
*/
|
||||
break;
|
||||
case CONFIG_MEM_FRAME_BASED:
|
||||
/* TODO:
|
||||
add_module_nets_cmos_memory_frame_config_bus(module_manager, decoder_lib,
|
||||
parent_module);
|
||||
*/
|
||||
break;
|
||||
default:
|
||||
VTR_LOGF_ERROR(__FILE__, __LINE__,
|
||||
"Invalid type of SRAM organization!\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
* Remove the nets around the configurable children for a given module
|
||||
*******************************************************************/
|
||||
static int remove_submodule_configurable_children_nets(
|
||||
ModuleManager& module_manager, const ModuleId& module_id,
|
||||
const CircuitLibrary& circuit_lib, const ConfigProtocol& config_protocol) {
|
||||
switch (circuit_lib.design_tech_type(config_protocol.memory_model())) {
|
||||
case CIRCUIT_MODEL_DESIGN_CMOS:
|
||||
remove_submodule_nets_cmos_memory_config_bus(module_manager, module_id,
|
||||
config_protocol.type());
|
||||
break;
|
||||
case CIRCUIT_MODEL_DESIGN_RRAM:
|
||||
/* TODO: */
|
||||
break;
|
||||
default:
|
||||
VTR_LOGF_ERROR(__FILE__, __LINE__,
|
||||
"Invalid type of memory design technology!\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
* Rebuild the nets(only sinks) around the configuration chain (ccff_head and
|
||||
*ccff_tails)
|
||||
*******************************************************************/
|
||||
static int rebuild_submodule_nets_cmos_memory_chain_config_bus(
|
||||
ModuleManager& module_manager, const ModuleId& parent_module,
|
||||
const e_config_protocol_type& sram_orgz_type) {
|
||||
for (size_t mem_index = 0;
|
||||
mem_index < module_manager.configurable_children(parent_module).size();
|
||||
++mem_index) {
|
||||
ModuleId net_src_module_id;
|
||||
size_t net_src_instance_id;
|
||||
ModulePortId net_src_port_id;
|
||||
|
||||
ModuleId net_sink_module_id;
|
||||
size_t net_sink_instance_id;
|
||||
ModulePortId net_sink_port_id;
|
||||
|
||||
if (0 == mem_index) {
|
||||
/* Find the port name of configuration chain head */
|
||||
std::string src_port_name =
|
||||
generate_sram_port_name(sram_orgz_type, CIRCUIT_MODEL_PORT_INPUT);
|
||||
net_src_module_id = parent_module;
|
||||
net_src_instance_id = 0;
|
||||
net_src_port_id =
|
||||
module_manager.find_module_port(net_src_module_id, src_port_name);
|
||||
|
||||
/* Find the port name of next memory module */
|
||||
std::string sink_port_name = generate_configuration_chain_head_name();
|
||||
net_sink_module_id =
|
||||
module_manager.configurable_children(parent_module)[mem_index];
|
||||
net_sink_instance_id =
|
||||
module_manager.configurable_child_instances(parent_module)[mem_index];
|
||||
net_sink_port_id =
|
||||
module_manager.find_module_port(net_sink_module_id, sink_port_name);
|
||||
} else {
|
||||
/* Find the port name of previous memory module */
|
||||
std::string src_port_name = generate_configuration_chain_tail_name();
|
||||
net_src_module_id =
|
||||
module_manager.configurable_children(parent_module)[mem_index - 1];
|
||||
net_src_instance_id = module_manager.configurable_child_instances(
|
||||
parent_module)[mem_index - 1];
|
||||
net_src_port_id =
|
||||
module_manager.find_module_port(net_src_module_id, src_port_name);
|
||||
|
||||
/* Find the port name of next memory module */
|
||||
std::string sink_port_name = generate_configuration_chain_head_name();
|
||||
net_sink_module_id =
|
||||
module_manager.configurable_children(parent_module)[mem_index];
|
||||
net_sink_instance_id =
|
||||
module_manager.configurable_child_instances(parent_module)[mem_index];
|
||||
net_sink_port_id =
|
||||
module_manager.find_module_port(net_sink_module_id, sink_port_name);
|
||||
}
|
||||
|
||||
/* Get the pin id for source port */
|
||||
BasicPort net_src_port =
|
||||
module_manager.module_port(net_src_module_id, net_src_port_id);
|
||||
/* Get the pin id for sink port */
|
||||
BasicPort net_sink_port =
|
||||
module_manager.module_port(net_sink_module_id, net_sink_port_id);
|
||||
/* Port sizes of source and sink should match */
|
||||
VTR_ASSERT(net_src_port.get_width() == net_sink_port.get_width());
|
||||
|
||||
/* Create a net for each pin */
|
||||
for (size_t pin_id = 0; pin_id < net_src_port.pins().size(); ++pin_id) {
|
||||
/* Create a net and add source and sink to it */
|
||||
ModuleNetId net = create_module_source_pin_net(
|
||||
module_manager, parent_module, net_src_module_id, net_src_instance_id,
|
||||
net_src_port_id, net_src_port.pins()[pin_id]);
|
||||
/* Add net sink */
|
||||
module_manager.add_module_net_sink(parent_module, net, net_sink_module_id,
|
||||
net_sink_instance_id, net_sink_port_id,
|
||||
net_sink_port.pins()[pin_id]);
|
||||
}
|
||||
}
|
||||
|
||||
/* For the last memory module:
|
||||
* net source is the configuration chain tail of the previous memory module
|
||||
* net sink is the configuration chain tail of the primitive module
|
||||
*/
|
||||
/* Find the port name of previous memory module */
|
||||
std::string src_port_name = generate_configuration_chain_tail_name();
|
||||
ModuleId net_src_module_id =
|
||||
module_manager.configurable_children(parent_module).back();
|
||||
size_t net_src_instance_id =
|
||||
module_manager.configurable_child_instances(parent_module).back();
|
||||
ModulePortId net_src_port_id =
|
||||
module_manager.find_module_port(net_src_module_id, src_port_name);
|
||||
|
||||
/* Find the port name of next memory module */
|
||||
std::string sink_port_name =
|
||||
generate_sram_port_name(sram_orgz_type, CIRCUIT_MODEL_PORT_OUTPUT);
|
||||
ModuleId net_sink_module_id = parent_module;
|
||||
size_t net_sink_instance_id = 0;
|
||||
ModulePortId net_sink_port_id =
|
||||
module_manager.find_module_port(net_sink_module_id, sink_port_name);
|
||||
|
||||
/* Get the pin id for source port */
|
||||
BasicPort net_src_port =
|
||||
module_manager.module_port(net_src_module_id, net_src_port_id);
|
||||
/* Get the pin id for sink port */
|
||||
BasicPort net_sink_port =
|
||||
module_manager.module_port(net_sink_module_id, net_sink_port_id);
|
||||
/* Port sizes of source and sink should match */
|
||||
VTR_ASSERT(net_src_port.get_width() == net_sink_port.get_width());
|
||||
|
||||
/* Create a net for each pin */
|
||||
for (size_t pin_id = 0; pin_id < net_src_port.pins().size(); ++pin_id) {
|
||||
/* Create a net and add source and sink to it */
|
||||
ModuleNetId net = create_module_source_pin_net(
|
||||
module_manager, parent_module, net_src_module_id, net_src_instance_id,
|
||||
net_src_port_id, net_src_port.pins()[pin_id]);
|
||||
/* Add net sink */
|
||||
module_manager.add_module_net_sink(parent_module, net, net_sink_module_id,
|
||||
net_sink_instance_id, net_sink_port_id,
|
||||
net_sink_port.pins()[pin_id]);
|
||||
}
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
* Rebuild the nets around the configurable children for a given module which
|
||||
*should be in CMOS type
|
||||
*******************************************************************/
|
||||
static int rebuild_submodule_nets_cmos_memory_config_bus(
|
||||
ModuleManager& module_manager, const ModuleId& module_id,
|
||||
const e_config_protocol_type& sram_orgz_type) {
|
||||
switch (sram_orgz_type) {
|
||||
case CONFIG_MEM_SCAN_CHAIN: {
|
||||
rebuild_submodule_nets_cmos_memory_chain_config_bus(
|
||||
module_manager, module_id, sram_orgz_type);
|
||||
break;
|
||||
}
|
||||
case CONFIG_MEM_STANDALONE:
|
||||
case CONFIG_MEM_QL_MEMORY_BANK:
|
||||
/* TODO:
|
||||
add_module_nets_cmos_memory_bank_bl_config_bus(
|
||||
module_manager, parent_module, sram_orgz_type, CIRCUIT_MODEL_PORT_BL);
|
||||
add_module_nets_cmos_memory_bank_wl_config_bus(
|
||||
module_manager, parent_module, sram_orgz_type, CIRCUIT_MODEL_PORT_WL);
|
||||
add_module_nets_cmos_memory_bank_wl_config_bus(
|
||||
module_manager, parent_module, sram_orgz_type, CIRCUIT_MODEL_PORT_WLR);
|
||||
*/
|
||||
break;
|
||||
case CONFIG_MEM_MEMORY_BANK:
|
||||
/* TODO:
|
||||
add_module_nets_cmos_flatten_memory_config_bus(
|
||||
module_manager, parent_module, sram_orgz_type, CIRCUIT_MODEL_PORT_BL);
|
||||
add_module_nets_cmos_flatten_memory_config_bus(
|
||||
module_manager, parent_module, sram_orgz_type, CIRCUIT_MODEL_PORT_WL);
|
||||
*/
|
||||
break;
|
||||
case CONFIG_MEM_FRAME_BASED:
|
||||
/* TODO:
|
||||
add_module_nets_cmos_memory_frame_config_bus(module_manager, decoder_lib,
|
||||
parent_module);
|
||||
*/
|
||||
break;
|
||||
default:
|
||||
VTR_LOGF_ERROR(__FILE__, __LINE__,
|
||||
"Invalid type of SRAM organization!\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
* Rebuild the nets(only sinks) around the configurable children for a given
|
||||
*module
|
||||
*******************************************************************/
|
||||
static int rebuild_submodule_configurable_children_nets(
|
||||
ModuleManager& module_manager, const ModuleId& module_id,
|
||||
const CircuitLibrary& circuit_lib, const ConfigProtocol& config_protocol) {
|
||||
switch (circuit_lib.design_tech_type(config_protocol.memory_model())) {
|
||||
case CIRCUIT_MODEL_DESIGN_CMOS:
|
||||
rebuild_submodule_nets_cmos_memory_config_bus(module_manager, module_id,
|
||||
config_protocol.type());
|
||||
break;
|
||||
case CIRCUIT_MODEL_DESIGN_RRAM:
|
||||
/* TODO: */
|
||||
break;
|
||||
default:
|
||||
VTR_LOGF_ERROR(__FILE__, __LINE__,
|
||||
"Invalid type of memory design technology!\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
* Load and update the configurable children of a given module (not a top-level
|
||||
*module) Compare the configurable children list with fabric sub-keys.
|
||||
* - If match, nothing should be done
|
||||
* - If not match,
|
||||
* - remove the nets related to configurable children
|
||||
* - rebuild the configurable children list
|
||||
* - add the nets related to configurable children
|
||||
*******************************************************************/
|
||||
static int load_and_update_submodule_memory_modules_from_fabric_key(
|
||||
ModuleManager& module_manager, const ModuleId& module_id,
|
||||
const CircuitLibrary& circuit_lib, const ConfigProtocol& config_protocol,
|
||||
const FabricKey& fabric_key, const FabricKeyModuleId& key_module_id) {
|
||||
int status = CMD_EXEC_SUCCESS;
|
||||
/* Compare the configurable children list */
|
||||
if (submodule_memory_modules_match_fabric_key(module_manager, module_id,
|
||||
fabric_key, key_module_id)) {
|
||||
return CMD_EXEC_SUCCESS;
|
||||
}
|
||||
/* Do not match, now remove all the nets for the configurable children */
|
||||
status = remove_submodule_configurable_children_nets(
|
||||
module_manager, module_id, circuit_lib, config_protocol);
|
||||
if (status == CMD_EXEC_FATAL_ERROR) {
|
||||
return status;
|
||||
}
|
||||
/* Overwrite the configurable children list */
|
||||
status = update_submodule_memory_modules_from_fabric_key(
|
||||
module_manager, module_id, circuit_lib, config_protocol, fabric_key,
|
||||
key_module_id);
|
||||
if (status == CMD_EXEC_FATAL_ERROR) {
|
||||
return status;
|
||||
}
|
||||
/* TODO: Create the nets for the new list of configurable children */
|
||||
status = rebuild_submodule_configurable_children_nets(
|
||||
module_manager, module_id, circuit_lib, config_protocol);
|
||||
if (status == CMD_EXEC_FATAL_ERROR) {
|
||||
return status;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
* Load and update the configurable children of a given list of modules (not a
|
||||
*top-level module)
|
||||
*******************************************************************/
|
||||
int load_submodules_memory_modules_from_fabric_key(
|
||||
ModuleManager& module_manager, const CircuitLibrary& circuit_lib,
|
||||
const ConfigProtocol& config_protocol, const FabricKey& fabric_key) {
|
||||
int status = CMD_EXEC_SUCCESS;
|
||||
for (FabricKeyModuleId key_module_id : fabric_key.modules()) {
|
||||
std::string module_name = fabric_key.module_name(key_module_id);
|
||||
/* Ensure this is not a top module! */
|
||||
if (module_name == std::string(FPGA_TOP_MODULE_NAME)) {
|
||||
VTR_LOG_ERROR(
|
||||
"Expect a non-top-level name for the sub-module '%s' in fabric key!\n",
|
||||
module_name.c_str());
|
||||
return CMD_EXEC_FATAL_ERROR;
|
||||
}
|
||||
ModuleId module_id = module_manager.find_module(module_name);
|
||||
if (module_id) {
|
||||
/* This is a valid module, try to load and update */
|
||||
status = load_and_update_submodule_memory_modules_from_fabric_key(
|
||||
module_manager, module_id, circuit_lib, config_protocol, fabric_key,
|
||||
key_module_id);
|
||||
if (status == CMD_EXEC_FATAL_ERROR) {
|
||||
return status;
|
||||
}
|
||||
} else {
|
||||
/* Not a valid module, report error */
|
||||
VTR_LOG_ERROR(
|
||||
"The sub-module '%s' in fabric key is not a valid module in FPGA "
|
||||
"fabric!\n",
|
||||
module_name.c_str());
|
||||
return CMD_EXEC_FATAL_ERROR;
|
||||
}
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
} /* end namespace openfpga */
|
||||
|
|
|
@ -185,10 +185,6 @@ void add_module_bus_nets(
|
|||
const ModulePortId& src_module_port_id, const ModuleId& des_module_id,
|
||||
const size_t& des_instance_id, const ModulePortId& des_module_port_id);
|
||||
|
||||
int load_submodules_memory_modules_from_fabric_key(
|
||||
ModuleManager& module_manager, const CircuitLibrary& circuit_lib,
|
||||
const ConfigProtocol& config_protocol, const FabricKey& fabric_key);
|
||||
|
||||
} /* end namespace openfpga */
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue