[core] sync up logical-to-physical configurable child mapping after physical memory build-up

This commit is contained in:
tangxifan 2023-08-02 12:24:16 -07:00
parent 470ab84489
commit c05f12ac11
8 changed files with 308 additions and 127 deletions

View File

@ -15,6 +15,7 @@
#include "build_grid_module_duplicated_pins.h"
#include "build_grid_module_utils.h"
#include "build_grid_modules.h"
#include "build_memory_modules.h"
#include "circuit_library_utils.h"
#include "module_manager_utils.h"
#include "openfpga_interconnect_types.h"
@ -356,8 +357,17 @@ static void build_primitive_block_module(
module_manager, primitive_module, logic_module, logic_instance_id,
memory_module, memory_instance_id, circuit_lib, primitive_model);
/* Record memory-related information */
size_t config_child_id = module_manager.num_configurable_children(primitive_module);
module_manager.add_configurable_child(primitive_module, memory_module,
memory_instance_id, group_config_block);
/* For logical memory, define the physical memory here */
if (group_config_block) {
std::string physical_memory_module_name =
generate_memory_module_name(circuit_lib, primitive_model, sram_model,
std::string(MEMORY_MODULE_POSTFIX), false);
ModuleId physical_memory_module = module_manager.find_module(physical_memory_module_name);
module_manager.set_physical_configurable_child(primitive_module, config_child_id, physical_memory_module);
}
}
/* Add all the nets to connect configuration ports from memory module to
@ -1069,103 +1079,6 @@ static void rec_build_logical_tile_modules(
VTR_LOGV(verbose, "Done\n");
}
/*****************************************************************************
* This function creates a physical memory module and add it the current module
* The following tasks will be accomplished:
* - Traverse all the logical configurable children in the module tree, starting from the current module
* - Build a list of the leaf logical configurable children and count the total memory sizes, the memory size for each physical memory submodule. Note that the physical memory submodule should be cached already in each leaf logical configurable children
* - Get the physical memory module required by each leaf logical configurable child
* - Create a dedicated module name for the physical memory (check if already exists, if yes, skip creating a new module)
* - Instanciate the module
* - Built nets. Note that only the output ports of the physical memory block is required, since they should drive the dedicated memory ports of logical configurable children
*****************************************************************************/
static int add_physical_memory_module(ModuleManager& module_manager,
DecoderLibrary& decoder_lib,
const ModuleId& curr_module,
const CircuitLibrary& circuit_lib,
const e_config_protocol_type& sram_orgz_type,
const CircuitModelId& sram_model) {
int status = CMD_EXEC_SUCCESS;
std::vector<ModuleId> required_phy_mem_modules;
status = rec_find_physical_memory_children(static_cast<const ModuleManager&>(module_manager), curr_module, required_phy_mem_modules);
if (status != CMD_EXEC_SUCCESS) {
return CMD_EXEC_FATAL_ERROR;
}
size_t module_num_config_bits =
find_module_num_config_bits_from_child_modules(
module_manager, curr_module, circuit_lib, sram_model, CONFIG_MEM_FEEDTHROUGH);
std::string phy_mem_module_name = generate_physical_memory_module_name(module_num_config_bits);
ModuleId phy_mem_module = module_manager.find_module(phy_mem_module_name);
if (!module_manager.valid_module_id(phy_mem_module)) {
status = build_memory_group_module(module_manager, decode_lib, circuit_lib, sram_orgz_type, phy_mem_module_name, sram_model, required_phy_mem_modules);
}
if (status != CMD_EXEC_SUCCESS) {
VTR_LOG_ERROR("Failed to create the physical memory module '%s'!\n", phy_mem_module_name.c_str());
return CMD_EXEC_FATAL_ERROR;
}
phy_mem_module = module_manager.find_module(phy_mem_module_name);
if (!module_manager.valid_module_id(phy_mem_module)) {
VTR_LOG_ERROR("Failed to create the physical memory module '%s'!\n", phy_mem_module_name.c_str());
return CMD_EXEC_FATAL_ERROR;
}
/* Add the physical memory module to the current module */
size_t phy_mem_instance = module_manager.num_instance(curr_module, phy_mem_module);
module_manager.add_child_module(curr_module, phy_mem_module, false);
/* Register in the physical configurable children list */
module_manager.add_physical_configurable_child(curr_module, phy_mem_module, phy_mem_instance, curr_module);
/* Build nets between the data output of the physical memory module and the outputs of the logical configurable children */
size_t curr_mem_pin_index = 0;
std::map<CircuitPortType, std::string> mem2mem_port_map;
mem2mem_port_map[CIRCUIT_MODEL_PORT_BL] = std::string(CONFIGURABLE_MEMORY_DATA_OUT_NAME);
mem2mem_port_map[CIRCUIT_MODEL_PORT_BLB] = std::string(CONFIGURABLE_MEMORY_INVERTED_DATA_OUT_NAME);
for (size_t ichild = 0; ichild < module_manager.logical_configurable_children(curr_module).size(); ++ichild) {
for (CircuitPortType port_type : {CIRCUIT_MODEL_PORT_BL, CIRCUIT_MODEL_PORT_BLB}) {
std::string src_port_name = mem2mem_port_map[port_type];
std::string des_port_name =
generate_sram_port_name(CONFIG_MEM_FEEDTHROUGH, port_type);
/* Try to find these ports in the module manager */
ModulePortId src_port_id =
module_manager.find_module_port(phy_mem_module, src_port_name);
if (!module_manager.valid_module_port_id(phy_mem_module, src_port_id)) {
return CMD_EXEC_FATAL_ERROR;
}
BasicPort src_port =
module_manager.module_port(phy_mem_module, src_port_id);
ModuleId des_module = module_manager.logical_configurable_children(curr_module)[ichild];
size_t des_instance = module_manager.logical_configurable_child_instances(curr_module)[ichild];
ModulePortId des_port_id =
module_manager.find_module_port(des_module, des_port_name);
if (!module_manager.valid_module_port_id(des_module, des_port_id)) {
return CMD_EXEC_FATAL_ERROR;
}
BasicPort des_port =
module_manager.module_port(des_module, des_port_id);
/* Build nets */
for (size_t ipin = 0; ipin < des_port.pins().size(); ++ipin) {
/* Create a net and add source and sink to it */
ModuleNetId net = create_module_source_pin_net(
module_manager, curr_module, phy_mem_module, phy_mem_instance,
src_port_id, src_port.pins()[cur_mem_pin_index]);
if (module_manager.valid_module_net_id(curr_module, net)) {
return CMD_EXEC_FATAL_ERROR;
}
/* Add net sink */
module_manager.add_module_net_sink(curr_module, net, des_module,
des_instance, des_port_id,
des_port.pins()[ipin]);
curr_mem_pin_index++;
}
}
}
return status;
}
/*****************************************************************************
* This function will create a Verilog file and print out a Verilog netlist
* for a type of physical block

View File

@ -15,6 +15,7 @@
#include "module_manager_utils.h"
#include "mux_graph.h"
#include "mux_utils.h"
#include "memory_utils.h"
#include "openfpga_naming.h"
#include "openfpga_reserved_words.h"
#include "vtr_assert.h"
@ -1363,4 +1364,117 @@ int build_memory_group_module(ModuleManager& module_manager,
return CMD_EXEC_SUCCESS;
}
/*****************************************************************************
* This function creates a physical memory module and add it the current module
* The following tasks will be accomplished:
* - Traverse all the logical configurable children in the module tree, starting from the current module
* - Build a list of the leaf logical configurable children and count the total memory sizes, the memory size for each physical memory submodule. Note that the physical memory submodule should be cached already in each leaf logical configurable children
* - Get the physical memory module required by each leaf logical configurable child
* - Create a dedicated module name for the physical memory (check if already exists, if yes, skip creating a new module)
* - Instanciate the module
* - Built nets. Note that only the output ports of the physical memory block is required, since they should drive the dedicated memory ports of logical configurable children
*****************************************************************************/
int add_physical_memory_module(ModuleManager& module_manager,
DecoderLibrary& decoder_lib,
const ModuleId& curr_module,
const CircuitLibrary& circuit_lib,
const e_config_protocol_type& sram_orgz_type,
const CircuitModelId& sram_model) {
int status = CMD_EXEC_SUCCESS;
std::vector<ModuleId> required_phy_mem_modules;
status = rec_find_physical_memory_children(static_cast<const ModuleManager&>(module_manager), curr_module, required_phy_mem_modules);
if (status != CMD_EXEC_SUCCESS) {
return CMD_EXEC_FATAL_ERROR;
}
size_t module_num_config_bits =
find_module_num_config_bits_from_child_modules(
module_manager, curr_module, circuit_lib, sram_model, CONFIG_MEM_FEEDTHROUGH);
std::string phy_mem_module_name = generate_physical_memory_module_name(module_num_config_bits);
ModuleId phy_mem_module = module_manager.find_module(phy_mem_module_name);
if (!module_manager.valid_module_id(phy_mem_module)) {
status = build_memory_group_module(module_manager, decode_lib, circuit_lib, sram_orgz_type, phy_mem_module_name, sram_model, required_phy_mem_modules);
}
if (status != CMD_EXEC_SUCCESS) {
VTR_LOG_ERROR("Failed to create the physical memory module '%s'!\n", phy_mem_module_name.c_str());
return CMD_EXEC_FATAL_ERROR;
}
phy_mem_module = module_manager.find_module(phy_mem_module_name);
if (!module_manager.valid_module_id(phy_mem_module)) {
VTR_LOG_ERROR("Failed to create the physical memory module '%s'!\n", phy_mem_module_name.c_str());
return CMD_EXEC_FATAL_ERROR;
}
/* Add the physical memory module to the current module */
size_t phy_mem_instance = module_manager.num_instance(curr_module, phy_mem_module);
module_manager.add_child_module(curr_module, phy_mem_module, false);
/* Register in the physical configurable children list */
module_manager.add_physical_configurable_child(curr_module, phy_mem_module, phy_mem_instance, curr_module);
/* Build nets between the data output of the physical memory module and the outputs of the logical configurable children */
size_t curr_mem_pin_index = 0;
std::map<CircuitPortType, std::string> mem2mem_port_map;
mem2mem_port_map[CIRCUIT_MODEL_PORT_BL] = std::string(CONFIGURABLE_MEMORY_DATA_OUT_NAME);
mem2mem_port_map[CIRCUIT_MODEL_PORT_BLB] = std::string(CONFIGURABLE_MEMORY_INVERTED_DATA_OUT_NAME);
for (size_t ichild = 0; ichild < module_manager.logical_configurable_children(curr_module).size(); ++ichild) {
for (CircuitPortType port_type : {CIRCUIT_MODEL_PORT_BL, CIRCUIT_MODEL_PORT_BLB}) {
std::string src_port_name = mem2mem_port_map[port_type];
std::string des_port_name =
generate_sram_port_name(CONFIG_MEM_FEEDTHROUGH, port_type);
/* Try to find these ports in the module manager */
ModulePortId src_port_id =
module_manager.find_module_port(phy_mem_module, src_port_name);
if (!module_manager.valid_module_port_id(phy_mem_module, src_port_id)) {
return CMD_EXEC_FATAL_ERROR;
}
BasicPort src_port =
module_manager.module_port(phy_mem_module, src_port_id);
ModuleId des_module = module_manager.logical_configurable_children(curr_module)[ichild];
size_t des_instance = module_manager.logical_configurable_child_instances(curr_module)[ichild];
ModulePortId des_port_id =
module_manager.find_module_port(des_module, des_port_name);
if (!module_manager.valid_module_port_id(des_module, des_port_id)) {
return CMD_EXEC_FATAL_ERROR;
}
BasicPort des_port =
module_manager.module_port(des_module, des_port_id);
/* Build nets */
for (size_t ipin = 0; ipin < des_port.pins().size(); ++ipin) {
/* Create a net and add source and sink to it */
ModuleNetId net = create_module_source_pin_net(
module_manager, curr_module, phy_mem_module, phy_mem_instance,
src_port_id, src_port.pins()[cur_mem_pin_index]);
if (module_manager.valid_module_net_id(curr_module, net)) {
return CMD_EXEC_FATAL_ERROR;
}
/* Add net sink */
module_manager.add_module_net_sink(curr_module, net, des_module,
des_instance, des_port_id,
des_port.pins()[ipin]);
curr_mem_pin_index++;
}
}
}
/* TODO: Recursively update the logical configurable child with the physical memory module parent and its instance id */
std::map<ModuleId, size_t> logical_mem_child_inst_count;
status = rec_update_logical_memory_children_with_physical_mapping(module_manager, curr_module, phy_mem_module, logical_mem_child_inst_count);
if (status != CMD_EXEC_SUCCESS) {
return CMD_EXEC_FATAL_ERROR;
}
/* Sanity check */
std::map<ModuleId, size_t> required_mem_child_inst_count;
for (ModuleId curr_module : module_manager.child_modules(phy_mem_module)) {
if (logical_mem_child_inst_count[curr_module] != module_manager.num_instance(phy_mem_module, curr_module)) {
VTR_LOG_ERROR("Expect the %lu instances of module '%s' under its parent '%s' while only updated %lu during logical-to-physical configurable child mapping sync-up!\n", module_manager.num_instance(phy_mem_module, curr_module), module_manager.module_name(curr_module).c_str(), module_manager.module_name(phy_mem_module).c_str(), logical_mem_child_inst_count[curr_module]);
return CMD_EXEC_FATAL_ERROR;
}
}
return status;
}
} /* end namespace openfpga */

View File

@ -37,6 +37,13 @@ int build_memory_group_module(ModuleManager& module_manager,
const CircuitModelId& sram_model,
const std::vector<ModuleId>& child_modules);
int add_physical_memory_module(ModuleManager& module_manager,
DecoderLibrary& decoder_lib,
const ModuleId& curr_module,
const CircuitLibrary& circuit_lib,
const e_config_protocol_type& sram_orgz_type,
const CircuitModelId& sram_model);
} /* end namespace openfpga */
#endif

View File

@ -17,6 +17,7 @@
#include "build_module_graph_utils.h"
#include "build_routing_module_utils.h"
#include "build_routing_modules.h"
#include "build_memory_modules.h"
#include "module_manager_utils.h"
#include "openfpga_naming.h"
#include "openfpga_reserved_words.h"
@ -240,7 +241,16 @@ static void build_switch_block_mux_module(
module_manager, sb_module, mux_module, mux_instance_id, mem_module,
mem_instance_id, circuit_lib, mux_model);
/* Update memory and instance list */
size_t config_child_id = module_manager.num_configurable_children(sb_module);
module_manager.add_configurable_child(sb_module, mem_module, mem_instance_id, group_config_block);
/* For logical memory, define the physical memory here */
if (group_config_block) {
std::string physical_mem_module_name =
generate_mux_subckt_name(circuit_lib, mux_model, datapath_mux_size,
std::string(MEMORY_MODULE_POSTFIX));
ModuleId physical_mem_module = module_manager.find_module(physical_mem_module_name);
module_manager.set_physical_configurable_child(sb_module, config_child_id, physical_mem_module);
}
}
/*********************************************************************
@ -740,7 +750,16 @@ static void build_connection_block_mux_module(
module_manager, cb_module, mux_module, mux_instance_id, mem_module,
mem_instance_id, circuit_lib, mux_model);
/* Update memory and instance list */
size_t config_child_id = module_manager.num_configurable_children(cb_module);
module_manager.add_configurable_child(cb_module, mem_module, mem_instance_id, group_config_block);
/* For logical memory, define the physical memory here */
if (group_config_block) {
std::string physical_mem_module_name =
generate_mux_subckt_name(circuit_lib, mux_model, datapath_mux_size,
std::string(MEMORY_MODULE_POSTFIX));
ModuleId physical_mem_module = module_manager.find_module(physical_mem_module_name);
module_manager.set_physical_configurable_child(cb_module, config_child_id, physical_mem_module);
}
}
/********************************************************************

View File

@ -77,29 +77,56 @@ std::vector<size_t> ModuleManager::child_module_instances(
}
/* Find all the configurable child modules under a parent module */
std::vector<ModuleId> ModuleManager::configurable_children(
std::vector<ModuleId> ModuleManager::logical_configurable_children(
const ModuleId& parent_module) const {
/* Validate the module_id */
VTR_ASSERT(valid_module_id(parent_module));
return configurable_children_[parent_module];
return logical_configurable_children_[parent_module];
}
/* Find all the instances of configurable child modules under a parent module */
std::vector<size_t> ModuleManager::configurable_child_instances(
std::vector<size_t> ModuleManager::logical_configurable_child_instances(
const ModuleId& parent_module) const {
/* Validate the module_id */
VTR_ASSERT(valid_module_id(parent_module));
return configurable_child_instances_[parent_module];
return logical_configurable_child_instances_[parent_module];
}
std::vector<vtr::Point<int>> ModuleManager::configurable_child_coordinates(
std::vector<vtr::Point<int>> ModuleManager::logical_configurable_child_coordinates(
const ModuleId& parent_module) const {
/* Validate the module_id */
VTR_ASSERT(valid_module_id(parent_module));
return configurable_child_coordinates_[parent_module];
return logical_configurable_child_coordinates_[parent_module];
}
/* Find all the configurable child modules under a parent module */
std::vector<ModuleId> ModuleManager::physical_configurable_children(
const ModuleId& parent_module) const {
/* Validate the module_id */
VTR_ASSERT(valid_module_id(parent_module));
return physical_configurable_children_[parent_module];
}
/* Find all the instances of configurable child modules under a parent module */
std::vector<size_t> ModuleManager::physical_configurable_child_instances(
const ModuleId& parent_module) const {
/* Validate the module_id */
VTR_ASSERT(valid_module_id(parent_module));
return physical_configurable_child_instances_[parent_module];
}
/* Find all the instances of configurable child modules under a parent module */
std::vector<ModuleId> ModuleManager::physical_configurable_child_parents(
const ModuleId& parent_module) const {
/* Validate the module_id */
VTR_ASSERT(valid_module_id(parent_module));
return physical_configurable_child_parents_[parent_module];
}
/* Find all the configurable child modules under a parent module */
@ -166,7 +193,7 @@ std::vector<ModuleId> ModuleManager::region_configurable_children(
for (const size_t& child_id :
config_region_children_[parent_module][region]) {
region_config_children.push_back(
configurable_children_[parent_module][child_id]);
logical_configurable_children_[parent_module][child_id]);
}
return region_config_children;
@ -185,7 +212,7 @@ std::vector<size_t> ModuleManager::region_configurable_child_instances(
for (const size_t& child_id :
config_region_children_[parent_module][region]) {
region_config_child_instances.push_back(
configurable_child_instances_[parent_module][child_id]);
logical_configurable_child_instances_[parent_module][child_id]);
}
return region_config_child_instances;
@ -205,7 +232,7 @@ ModuleManager::region_configurable_child_coordinates(
for (const size_t& child_id :
config_region_children_[parent_module][region]) {
region_config_child_coordinates.push_back(
configurable_child_coordinates_[parent_module][child_id]);
logical_configurable_child_coordinates_[parent_module][child_id]);
}
return region_config_child_coordinates;
@ -376,6 +403,11 @@ size_t ModuleManager::instance_id(const ModuleId& parent_module,
return size_t(-1);
}
size_t ModuleManager::num_logical_configurable_children(const ModuleId& parent_module) const {
VTR_ASSERT(valid_module_id(parent_module));
return logical_configurable_children_[parent_module].size();
}
ModuleManager::e_module_port_type ModuleManager::port_type(
const ModuleId& module, const ModulePortId& port) const {
/* validate both module id and port id*/
@ -654,10 +686,14 @@ ModuleId ModuleManager::add_module(const std::string& name) {
children_.emplace_back();
num_child_instances_.emplace_back();
child_instance_names_.emplace_back();
configurable_children_.emplace_back();
configurable_child_instances_.emplace_back();
configurable_child_regions_.emplace_back();
configurable_child_coordinates_.emplace_back();
logical_configurable_children_.emplace_back();
logical_configurable_child_instances_.emplace_back();
logical_configurable_child_regions_.emplace_back();
logical_configurable_child_coordinates_.emplace_back();
physical_configurable_children_.emplace_back();
physical_configurable_child_instances_.emplace_back();
physical_configurable_child_parents_.emplace_back();
config_region_ids_.emplace_back();
config_region_children_.emplace_back();
@ -921,10 +957,38 @@ void ModuleManager::add_configurable_child(const ModuleId& parent_module,
physical_configurable_children_[parent_module].push_back(child_module);
physical_configurable_child_instances_[parent_module].push_back(child_instance);
physical_configurable_child_parents_[parent_module].push_back(parent_module);
} else {
physical_configurable_children_[parent_module].emplace_back();
physical_configurable_child_instances_[parent_module].emplace_back();
physical_configurable_child_parents_[parent_module].emplace_back();
}
}
void ModuleManager::reserve_logical_configurable_child(const ModuleId& parent_module,
void ModuleManager::set_physical_configurable_child(const ModuleId& parent_module, const size_t& logical_child_id, const ModuleId& physical_child_module) {
/* Sanity checks */
VTR_ASSERT(valid_module_id(parent_module));
VTR_ASSERT(logical_child_id < num_logical_configurable_children(parent_module));
/* Create the pair */
physical_configurable_children_[parent_module][logical_child_id] = physical_child_module;
}
void ModuleManager::set_physical_configurable_child_instance(const ModuleId& parent_module, const size_t& logical_child_id, const size_t& physical_child_instance) {
/* Sanity checks */
VTR_ASSERT(valid_module_id(parent_module));
VTR_ASSERT(logical_child_id < num_logical_configurable_children(parent_module));
/* Create the pair */
physical_configurable_child_instances_[parent_module][logical_child_id] = physical_child_instance;
}
void ModuleManager::set_physical_configurable_child_parent_module(const ModuleId& parent_module, const size_t& logical_child_id, const ModuleId& physical_child_parent_module) {
/* Sanity checks */
VTR_ASSERT(valid_module_id(parent_module));
VTR_ASSERT(logical_child_id < num_logical_configurable_children(parent_module));
/* Create the pair */
physical_configurable_child_parents_[parent_module][logical_child_id] = physical_child_parent_module;
}
void ModuleManager::reserve_configurable_child(const ModuleId& parent_module,
const size_t& num_children) {
VTR_ASSERT(valid_module_id(parent_module));
/* Do reserve when the number of children is larger than current size of lists
@ -935,12 +999,21 @@ void ModuleManager::reserve_logical_configurable_child(const ModuleId& parent_mo
if (num_children > logical_configurable_child_instances_[parent_module].size()) {
logical_configurable_child_instances_[parent_module].reserve(num_children);
}
if (num_children > configurable_child_regions_[parent_module].size()) {
if (num_children > logical_configurable_child_regions_[parent_module].size()) {
logical_configurable_child_regions_[parent_module].reserve(num_children);
}
if (num_children > configurable_child_coordinates_[parent_module].size()) {
if (num_children > logical_configurable_child_coordinates_[parent_module].size()) {
logical_configurable_child_coordinates_[parent_module].reserve(num_children);
}
if (num_children > physical_configurable_children_[parent_module].size()) {
physical_configurable_children_[parent_module].reserve(num_children);
}
if (num_children > physical_configurable_child_instances_[parent_module].size()) {
physical_configurable_child_instances_[parent_module].reserve(num_children);
}
if (num_children > physical_configurable_child_parents_[parent_module].size()) {
physical_configurable_child_parents_[parent_module].reserve(num_children);
}
}
ConfigRegionId ModuleManager::add_config_region(const ModuleId& module) {
@ -968,23 +1041,23 @@ void ModuleManager::add_configurable_child_to_region(
/* Ensure that the child module is in the configurable children list */
VTR_ASSERT(child_module ==
configurable_children(parent_module)[config_child_id]);
logical_configurable_children(parent_module)[config_child_id]);
VTR_ASSERT(child_instance ==
configurable_child_instances(parent_module)[config_child_id]);
logical_configurable_child_instances(parent_module)[config_child_id]);
/* If the child is already in another region, error out */
if ((true ==
valid_region_id(
parent_module,
configurable_child_regions_[parent_module][config_child_id])) &&
logical_configurable_child_regions_[parent_module][config_child_id])) &&
(config_region !=
configurable_child_regions_[parent_module][config_child_id])) {
logical_configurable_child_regions_[parent_module][config_child_id])) {
VTR_LOGF_ERROR(
__FILE__, __LINE__,
"Try to add a configurable child '%s[%lu]' to region '%lu' which is "
"already added to another region '%lu'!\n",
module_name(child_module).c_str(), child_instance, size_t(config_region),
size_t(configurable_child_regions_[parent_module][config_child_id]));
size_t(logical_configurable_child_regions_[parent_module][config_child_id]));
exit(1);
}
@ -1306,10 +1379,14 @@ ModuleId ModuleManager::create_wrapper_module(
void ModuleManager::clear_configurable_children(const ModuleId& parent_module) {
VTR_ASSERT(valid_module_id(parent_module));
configurable_children_[parent_module].clear();
configurable_child_instances_[parent_module].clear();
configurable_child_regions_[parent_module].clear();
configurable_child_coordinates_[parent_module].clear();
logical_configurable_children_[parent_module].clear();
logical_configurable_child_instances_[parent_module].clear();
logical_configurable_child_regions_[parent_module].clear();
logical_configurable_child_coordinates_[parent_module].clear();
parent_configurable_children_[parent_module].clear();
parent_configurable_child_instances_[parent_module].clear();
parent_configurable_child_parents_[parent_module].clear();
}
void ModuleManager::clear_config_region(const ModuleId& parent_module) {

View File

@ -166,15 +166,28 @@ class ModuleManager {
std::vector<size_t> child_module_instances(
const ModuleId& parent_module, const ModuleId& child_module) const;
/* Find all the configurable child modules under a parent module */
std::vector<ModuleId> configurable_children(
std::vector<ModuleId> logical_configurable_children(
const ModuleId& parent_module) const;
/* Find all the instances of configurable child modules under a parent module
*/
std::vector<size_t> configurable_child_instances(
std::vector<size_t> logical_configurable_child_instances(
const ModuleId& parent_module) const;
/* Find the coordindate of a configurable child module under a parent module
*/
std::vector<vtr::Point<int>> configurable_child_coordinates(
std::vector<vtr::Point<int>> logical_configurable_child_coordinates(
const ModuleId& parent_module) const;
/* Find all the configurable child modules under a parent module */
std::vector<ModuleId> physical_configurable_children(
const ModuleId& parent_module) const;
/* Find all the instances of configurable child modules under a parent module
*/
std::vector<size_t> physical_configurable_child_instances(
const ModuleId& parent_module) const;
/* Find all the parent modules of physical configurable child modules under a parent module
* Note that a physical configurable child module may be at another module; Only the logical child module is under the current parent module
*/
std::vector<ModuleId> physical_configurable_child_parents(
const ModuleId& parent_module) const;
/* Find all the I/O child modules under a parent module */
@ -195,16 +208,17 @@ class ModuleManager {
/* Find all the regions */
region_range regions(const ModuleId& module) const;
/* Find all the configurable child modules under a region of a parent module
* Note that we use logical children here
*/
std::vector<ModuleId> region_configurable_children(
const ModuleId& parent_module, const ConfigRegionId& region) const;
/* Find all the instances of configurable child modules under a region of a
* parent module */
* parent module; Note that we use logical children here */
std::vector<size_t> region_configurable_child_instances(
const ModuleId& parent_module, const ConfigRegionId& region) const;
/* Find all the coordinates of configurable child modules under a region of a
* parent module */
* parent module; Note that we use logical children here */
std::vector<vtr::Point<int>> region_configurable_child_coordinates(
const ModuleId& parent_module, const ConfigRegionId& region) const;
@ -238,6 +252,8 @@ class ModuleManager {
size_t instance_id(const ModuleId& parent_module,
const ModuleId& child_module,
const std::string& instance_name) const;
/** @brief Count the number of logical configurable children */
size_t num_logical_configurable_children(const ModuleId& parent_module) const;
/* Find the type of a port */
ModuleManager::e_module_port_type port_type(const ModuleId& module,
const ModulePortId& port) const;
@ -360,6 +376,11 @@ class ModuleManager {
const size_t& child_instance,
const bool& logical_only,
const vtr::Point<int> coord = vtr::Point<int>(-1, -1));
/** @brief Create a pair of mapping from a logical configurable child to a physical configurable child */
void set_physical_configurable_child(const ModuleId& parent_module, const size_t& logical_child_id, const ModuleId& physical_child_module);
/** @brief Create a pair of mapping from a logical configurable child to a physical configurable child */
void set_physical_configurable_child_instance(const ModuleId& parent_module, const size_t& logical_child_id, const size_t& physical_child_instance);
void set_physical_configurable_child_parent_module(const ModuleId& parent_module, const size_t& logical_child_id, const ModuleId& physical_child_parent_module);
/* Reserved a number of configurable children for memory efficiency */
void reserve_configurable_child(const ModuleId& module,
const size_t& num_children);

View File

@ -512,4 +512,27 @@ int rec_find_physical_memory_children(const ModuleManager& module_manager, const
return CMD_EXEC_SUCCESS;
}
int rec_update_logical_memory_children_with_physical_mapping(ModuleManager& module_manager, const ModuleId& curr_module, const ModuleId& phy_mem_module, std::map<ModuleId, size_t>& logical_mem_child_inst_count) {
if (module_manager.logical_configurable_children(curr_module).empty()) {
return CMD_EXEC_SUCCESS;
}
for (size_t ichild = 0; ichild < module_manager.logical_configurable_children(curr_module).size(); ++ichild) {
ModuleId logical_child = module_manager.logical_configurable_children(curr_module)[ichild];
if (module_manager.logical_configurable_children(logical_child).empty()) {
/* This is a leaf node, update its physical information */
ModuleId phy_mem_submodule = module_manager.physical_configurable_children(curr_module)[ichild]
auto result = logical_mem_child_inst_count.find(phy_mem_submodule);
if (result == logical_mem_child_inst_count.end()) {
logical_mem_child_inst_count.find[phy_mem_submodule] = 0;
}
module_manager.set_physical_configurable_child_instance(curr_module, ichild, logical_mem_child_inst_count[phy_mem_submodule]);
module_manager.set_physical_configurable_child_parent_module(curr_module, ichild, phy_mem_module);
logical_mem_child_inst_count[phy_mem_submodule]++;
} else {
rec_find_physical_memory_children(module_manager, logical_child, physical_memory_children, logical_mem_child_inst_count);
}
}
return CMD_EXEC_SUCCESS;
}
} /* end namespace openfpga */

View File

@ -60,6 +60,13 @@ size_t estimate_num_configurable_children_to_skip_by_config_protocol(
*/
int rec_find_physical_memory_children(const ModuleManager& module_manager, const ModuleId& curr_module, std::vector<ModuleId>& physical_memory_children);
/**
* @brief Update all the mappings between logical-to-physical memory children with a given root module
* This function will walk through the module tree in a recursive way until reaching the leaf node (which require configurable memories)
* Keep a scoreboard of instance number for checking. Note that when calling this the function, use an empty scoreboard!
*/
int rec_update_logical_memory_children_with_physical_mapping(ModuleManager& module_manager, const ModuleId& curr_module, const ModuleId& phy_mem_module, std::map<ModuleId, size_t>& logical_mem_child_inst_count);
} /* end namespace openfpga */
#endif