From c05f12ac118d1578d8ef1f399530aa25fe3bbf47 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Wed, 2 Aug 2023 12:24:16 -0700 Subject: [PATCH] [core] sync up logical-to-physical configurable child mapping after physical memory build-up --- openfpga/src/fabric/build_grid_modules.cpp | 107 ++------------- openfpga/src/fabric/build_memory_modules.cpp | 114 ++++++++++++++++ openfpga/src/fabric/build_memory_modules.h | 7 + openfpga/src/fabric/build_routing_modules.cpp | 19 +++ openfpga/src/fabric/module_manager.cpp | 127 ++++++++++++++---- openfpga/src/fabric/module_manager.h | 31 ++++- openfpga/src/utils/memory_utils.cpp | 23 ++++ openfpga/src/utils/memory_utils.h | 7 + 8 files changed, 308 insertions(+), 127 deletions(-) diff --git a/openfpga/src/fabric/build_grid_modules.cpp b/openfpga/src/fabric/build_grid_modules.cpp index a9814d0f0..6001b00e4 100644 --- a/openfpga/src/fabric/build_grid_modules.cpp +++ b/openfpga/src/fabric/build_grid_modules.cpp @@ -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 required_phy_mem_modules; - status = rec_find_physical_memory_children(static_cast(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 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 diff --git a/openfpga/src/fabric/build_memory_modules.cpp b/openfpga/src/fabric/build_memory_modules.cpp index 1f7cb9bae..51821ffa7 100644 --- a/openfpga/src/fabric/build_memory_modules.cpp +++ b/openfpga/src/fabric/build_memory_modules.cpp @@ -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 required_phy_mem_modules; + status = rec_find_physical_memory_children(static_cast(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 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 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 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 */ diff --git a/openfpga/src/fabric/build_memory_modules.h b/openfpga/src/fabric/build_memory_modules.h index 6431eaf9a..116e3c8e6 100644 --- a/openfpga/src/fabric/build_memory_modules.h +++ b/openfpga/src/fabric/build_memory_modules.h @@ -37,6 +37,13 @@ int build_memory_group_module(ModuleManager& module_manager, const CircuitModelId& sram_model, const std::vector& 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 diff --git a/openfpga/src/fabric/build_routing_modules.cpp b/openfpga/src/fabric/build_routing_modules.cpp index a0b7cde15..b889f86fe 100644 --- a/openfpga/src/fabric/build_routing_modules.cpp +++ b/openfpga/src/fabric/build_routing_modules.cpp @@ -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); + } } /******************************************************************** diff --git a/openfpga/src/fabric/module_manager.cpp b/openfpga/src/fabric/module_manager.cpp index 4bc00cbb8..53239eaf0 100644 --- a/openfpga/src/fabric/module_manager.cpp +++ b/openfpga/src/fabric/module_manager.cpp @@ -77,29 +77,56 @@ std::vector ModuleManager::child_module_instances( } /* Find all the configurable child modules under a parent module */ -std::vector ModuleManager::configurable_children( +std::vector 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 ModuleManager::configurable_child_instances( +std::vector 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> ModuleManager::configurable_child_coordinates( +std::vector> 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 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 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 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 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 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) { diff --git a/openfpga/src/fabric/module_manager.h b/openfpga/src/fabric/module_manager.h index 1eced58bc..0d4a5b2f3 100644 --- a/openfpga/src/fabric/module_manager.h +++ b/openfpga/src/fabric/module_manager.h @@ -166,15 +166,28 @@ class ModuleManager { std::vector child_module_instances( const ModuleId& parent_module, const ModuleId& child_module) const; /* Find all the configurable child modules under a parent module */ - std::vector configurable_children( + std::vector logical_configurable_children( const ModuleId& parent_module) const; /* Find all the instances of configurable child modules under a parent module */ - std::vector configurable_child_instances( + std::vector logical_configurable_child_instances( const ModuleId& parent_module) const; /* Find the coordindate of a configurable child module under a parent module */ - std::vector> configurable_child_coordinates( + std::vector> logical_configurable_child_coordinates( + const ModuleId& parent_module) const; + + /* Find all the configurable child modules under a parent module */ + std::vector physical_configurable_children( + const ModuleId& parent_module) const; + /* Find all the instances of configurable child modules under a parent module + */ + std::vector 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 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 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 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> 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 coord = vtr::Point(-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); diff --git a/openfpga/src/utils/memory_utils.cpp b/openfpga/src/utils/memory_utils.cpp index 05dbf439b..7d3b6b23f 100644 --- a/openfpga/src/utils/memory_utils.cpp +++ b/openfpga/src/utils/memory_utils.cpp @@ -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& 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 */ diff --git a/openfpga/src/utils/memory_utils.h b/openfpga/src/utils/memory_utils.h index 5097c962d..7714242fa 100644 --- a/openfpga/src/utils/memory_utils.h +++ b/openfpga/src/utils/memory_utils.h @@ -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& 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& logical_mem_child_inst_count); + } /* end namespace openfpga */ #endif