[OpenFPGA Tool] Support configurable regions in module manager

This commit is contained in:
tangxifan 2020-09-28 18:13:07 -06:00
parent 1e70825383
commit 552dddffd0
9 changed files with 358 additions and 71 deletions

View File

@ -120,7 +120,7 @@ int build_device_module_graph(ModuleManager& module_manager,
openfpga_ctx.device_rr_gsb(),
openfpga_ctx.tile_direct(),
openfpga_ctx.arch().arch_direct,
openfpga_ctx.arch().config_protocol.type(),
openfpga_ctx.arch().config_protocol,
sram_model,
frame_view, compress_routing, duplicate_grid_pin,
fabric_key, generate_random_fabric_key);

View File

@ -330,7 +330,7 @@ int build_top_module(ModuleManager& module_manager,
const DeviceRRGSB& device_rr_gsb,
const TileDirect& tile_direct,
const ArchDirect& arch_direct,
const e_config_protocol_type& sram_orgz_type,
const ConfigProtocol& config_protocol,
const CircuitModelId& sram_model,
const bool& frame_view,
const bool& compact_routing_hierarchy,
@ -396,7 +396,7 @@ int build_top_module(ModuleManager& module_manager,
*/
if (true == fabric_key.empty()) {
organize_top_module_memory_modules(module_manager, top_module,
circuit_lib, sram_orgz_type, sram_model,
circuit_lib, config_protocol, sram_model,
grids, grid_instance_ids,
device_rr_gsb, sb_instance_ids, cb_instance_ids,
compact_routing_hierarchy);
@ -411,7 +411,7 @@ int build_top_module(ModuleManager& module_manager,
/* Shuffle the configurable children in a random sequence */
if (true == generate_random_fabric_key) {
shuffle_top_module_configurable_children(module_manager, top_module);
shuffle_top_module_configurable_children(module_manager, top_module, config_protocol);
}
/* Add shared SRAM ports from the sub-modules under this Verilog module
@ -427,11 +427,11 @@ int build_top_module(ModuleManager& module_manager,
* This is a much easier job after adding sub modules (instances),
* we just need to find all the I/O ports from the child modules and build a list of it
*/
size_t module_num_config_bits = find_module_num_config_bits_from_child_modules(module_manager, top_module, circuit_lib, sram_model, sram_orgz_type);
size_t module_num_config_bits = find_module_num_config_bits_from_child_modules(module_manager, top_module, circuit_lib, sram_model, config_protocol.type());
if (0 < module_num_config_bits) {
add_top_module_sram_ports(module_manager, top_module,
circuit_lib, sram_model,
sram_orgz_type, module_num_config_bits);
config_protocol.type(), module_num_config_bits);
}
/* Add module nets to connect memory cells inside
@ -440,7 +440,7 @@ int build_top_module(ModuleManager& module_manager,
if (0 < module_manager.configurable_children(top_module).size()) {
add_top_module_nets_memory_config_bus(module_manager, decoder_lib,
top_module,
sram_orgz_type, circuit_lib.design_tech_type(sram_model),
config_protocol.type(), circuit_lib.design_tech_type(sram_model),
module_num_config_bits);
}

View File

@ -14,6 +14,7 @@
#include "decoder_library.h"
#include "tile_direct.h"
#include "arch_direct.h"
#include "config_protocol.h"
#include "module_manager.h"
#include "io_location_map.h"
#include "fabric_key.h"
@ -34,7 +35,7 @@ int build_top_module(ModuleManager& module_manager,
const DeviceRRGSB& device_rr_gsb,
const TileDirect& tile_direct,
const ArchDirect& arch_direct,
const e_config_protocol_type& sram_orgz_type,
const ConfigProtocol& config_protocol,
const CircuitModelId& sram_model,
const bool& frame_view,
const bool& compact_routing_hierarchy,

View File

@ -176,6 +176,94 @@ void organize_top_module_tile_memory_modules(ModuleManager& module_manager,
}
}
/********************************************************************
* Split memory modules into different configurable regions
* This function will create regions based on the definition
* in the configuration protocols, to accommodate each configurable
* child under the top-level module
*
* For example:
* FPGA Top-level module
* +----------------------+
* | | |
* | Region 0 | Region 1 |
* | | |
* +----------------------+
* | | |
* | Region 2 | Region 3 |
* | | |
* +----------------------+
*
* A typical organization of a Region X
* +-----------------------+
* | |
* | +------+ +------+ |
* | | | | | |
* | | Tile | | Tile | ... |
* | | | | | |
* | +------+ +------+ |
* | ... ... |
* | |
* | +------+ +------+ |
* | | | | | |
* | | Tile | | Tile | ... |
* | | | | | |
* | +------+ +------+ |
* +-----------------------+
*
* Note:
* - This function should NOT modify configurable children
*
*******************************************************************/
static
void build_top_module_configurable_regions(ModuleManager& module_manager,
const ModuleId& top_module,
const ConfigProtocol& config_protocol) {
/* Ensure we have valid configurable children */
VTR_ASSERT(false == module_manager.configurable_children(top_module).empty());
/* Ensure that our region definition is valid */
VTR_ASSERT(1 <= config_protocol.num_regions());
/* Exclude decoders from the list */
size_t num_configurable_children = module_manager.configurable_children(top_module).size();
if (CONFIG_MEM_MEMORY_BANK == config_protocol.type()) {
num_configurable_children -= 2;
} else if (CONFIG_MEM_FRAME_BASED == config_protocol.type()) {
num_configurable_children -= 1;
}
/* Evenly place each configurable child to each region */
size_t num_children_per_region = num_configurable_children / config_protocol.num_regions();
size_t region_child_counter = 0;
bool create_region = true;
ConfigRegionId curr_region = ConfigRegionId::INVALID();
for (size_t ichild = 0; ichild < num_configurable_children; ++ichild) {
if (true == create_region) {
curr_region = module_manager.add_config_region(top_module);
}
/* Add the child to a region */
module_manager.add_configurable_child_to_region(top_module,
curr_region,
module_manager.configurable_children(top_module)[ichild],
module_manager.configurable_child_instances(top_module)[ichild]);
/* See if the current region is full or not:
* For the last region, we will keep adding until we finish all the children
*/
region_child_counter++;
if (region_child_counter < num_children_per_region) {
create_region = false;
} else if (size_t(curr_region) < (size_t)config_protocol.num_regions() - 1) {
create_region = true;
region_child_counter = 0;
}
}
}
/********************************************************************
* Organize the list of memory modules and instances
* This function will record all the sub modules of the top-level module
@ -273,7 +361,7 @@ void organize_top_module_tile_memory_modules(ModuleManager& module_manager,
void organize_top_module_memory_modules(ModuleManager& module_manager,
const ModuleId& top_module,
const CircuitLibrary& circuit_lib,
const e_config_protocol_type& sram_orgz_type,
const ConfigProtocol& config_protocol,
const CircuitModelId& sram_model,
const DeviceGrid& grids,
const vtr::Matrix<size_t>& grid_instance_ids,
@ -332,7 +420,7 @@ void organize_top_module_memory_modules(ModuleManager& module_manager,
for (const vtr::Point<size_t>& io_coord : io_coords[io_side]) {
/* Identify the GSB that surrounds the grid */
organize_top_module_tile_memory_modules(module_manager, top_module,
circuit_lib, sram_orgz_type, sram_model,
circuit_lib, config_protocol.type(), sram_model,
grids, grid_instance_ids,
device_rr_gsb, sb_instance_ids, cb_instance_ids,
compact_routing_hierarchy,
@ -362,12 +450,15 @@ void organize_top_module_memory_modules(ModuleManager& module_manager,
for (const vtr::Point<size_t>& core_coord : core_coords) {
organize_top_module_tile_memory_modules(module_manager, top_module,
circuit_lib, sram_orgz_type, sram_model,
circuit_lib, config_protocol.type(), sram_model,
grids, grid_instance_ids,
device_rr_gsb, sb_instance_ids, cb_instance_ids,
compact_routing_hierarchy,
core_coord, NUM_SIDES);
}
/* Split memory modules into different regions */
build_top_module_configurable_regions(module_manager, top_module, config_protocol);
}
@ -375,13 +466,18 @@ void organize_top_module_memory_modules(ModuleManager& module_manager,
* Shuffle the configurable children in a random sequence
*
* TODO: May use a more customized shuffle mechanism
* TODO: Apply region-based shuffling
* The shuffling will be applied to each separated regions
* Configurable children will not shuffled from a region
* to another, instead they should stay in the same region
*
* Note:
* - This function should NOT be called
* before allocating any configurable child
********************************************************************/
void shuffle_top_module_configurable_children(ModuleManager& module_manager,
const ModuleId& top_module) {
const ModuleId& top_module,
const ConfigProtocol& config_protocol) {
size_t num_keys = module_manager.configurable_children(top_module).size();
std::vector<size_t> shuffled_keys;
shuffled_keys.reserve(num_keys);
@ -403,6 +499,9 @@ void shuffle_top_module_configurable_children(ModuleManager& module_manager,
orig_configurable_children[shuffled_keys[ikey]],
orig_configurable_child_instances[shuffled_keys[ikey]]);
}
/* Split memory modules into different regions */
build_top_module_configurable_regions(module_manager, top_module, config_protocol);
}
/********************************************************************
@ -421,52 +520,60 @@ int load_top_module_memory_modules_from_fabric_key(ModuleManager& module_manager
/* Ensure a clean start */
module_manager.clear_configurable_children(top_module);
for (const FabricKeyId& key : fabric_key.keys()) {
/* Find if instance id is valid */
std::pair<ModuleId, size_t> instance_info(ModuleId::INVALID(), 0);
/* If we have an alias, we try to find a instance in this name */
if (!fabric_key.key_alias(key).empty()) {
/* If we have the key, we can quickly spot instance id.
* Otherwise, we have to exhaustively find the module id and instance id
*/
if (!fabric_key.key_name(key).empty()) {
for (const FabricRegionId& region : fabric_key.regions()) {
/* Create a configurable region in the top module */
ConfigRegionId top_module_config_region = module_manager.add_config_region(top_module);
for (const FabricKeyId& key : fabric_key.region_keys(region)) {
/* Find if instance id is valid */
std::pair<ModuleId, size_t> instance_info(ModuleId::INVALID(), 0);
/* If we have an alias, we try to find a instance in this name */
if (!fabric_key.key_alias(key).empty()) {
/* If we have the key, we can quickly spot instance id.
* Otherwise, we have to exhaustively find the module id and instance id
*/
if (!fabric_key.key_name(key).empty()) {
instance_info.first = module_manager.find_module(fabric_key.key_name(key));
instance_info.second = module_manager.instance_id(top_module, instance_info.first, fabric_key.key_alias(key));
} else {
instance_info = find_module_manager_instance_module_info(module_manager, top_module, fabric_key.key_alias(key));
}
} else {
/* If we do not have an alias, we use the name and value to build the info deck */
instance_info.first = module_manager.find_module(fabric_key.key_name(key));
instance_info.second = module_manager.instance_id(top_module, instance_info.first, fabric_key.key_alias(key));
} else {
instance_info = find_module_manager_instance_module_info(module_manager, top_module, fabric_key.key_alias(key));
instance_info.second = fabric_key.key_value(key);
}
} else {
/* If we do not have an alias, we use the name and value to build the info deck */
instance_info.first = module_manager.find_module(fabric_key.key_name(key));
instance_info.second = fabric_key.key_value(key);
}
if (false == module_manager.valid_module_id(instance_info.first)) {
if (!fabric_key.key_alias(key).empty()) {
VTR_LOG_ERROR("Invalid key alias '%s'!\n",
fabric_key.key_alias(key).c_str());
} else {
VTR_LOG_ERROR("Invalid key name '%s'!\n",
fabric_key.key_name(key).c_str());
if (false == module_manager.valid_module_id(instance_info.first)) {
if (!fabric_key.key_alias(key).empty()) {
VTR_LOG_ERROR("Invalid key alias '%s'!\n",
fabric_key.key_alias(key).c_str());
} else {
VTR_LOG_ERROR("Invalid key name '%s'!\n",
fabric_key.key_name(key).c_str());
}
return CMD_EXEC_FATAL_ERROR;
}
return CMD_EXEC_FATAL_ERROR;
}
if (false == module_manager.valid_module_instance_id(top_module, instance_info.first, instance_info.second)) {
if (!fabric_key.key_alias(key).empty()) {
VTR_LOG_ERROR("Invalid key alias '%s'!\n",
fabric_key.key_alias(key).c_str());
} else {
VTR_LOG_ERROR("Invalid key value '%ld'!\n",
instance_info.second);
if (false == module_manager.valid_module_instance_id(top_module, instance_info.first, instance_info.second)) {
if (!fabric_key.key_alias(key).empty()) {
VTR_LOG_ERROR("Invalid key alias '%s'!\n",
fabric_key.key_alias(key).c_str());
} else {
VTR_LOG_ERROR("Invalid key value '%ld'!\n",
instance_info.second);
}
return CMD_EXEC_FATAL_ERROR;
}
return CMD_EXEC_FATAL_ERROR;
}
/* Now we can add the child to configurable children of the top module */
module_manager.add_configurable_child(top_module,
instance_info.first,
instance_info.second);
/* Now we can add the child to configurable children of the top module */
module_manager.add_configurable_child(top_module,
instance_info.first,
instance_info.second);
module_manager.add_configurable_child_to_region(top_module,
top_module_config_region,
instance_info.first,
instance_info.second);
}
}
return CMD_EXEC_SUCCESS;

View File

@ -11,6 +11,7 @@
#include "module_manager.h"
#include "circuit_types.h"
#include "circuit_library.h"
#include "config_protocol.h"
#include "decoder_library.h"
#include "device_grid.h"
#include "device_rr_gsb.h"
@ -26,7 +27,7 @@ namespace openfpga {
void organize_top_module_memory_modules(ModuleManager& module_manager,
const ModuleId& top_module,
const CircuitLibrary& circuit_lib,
const e_config_protocol_type& sram_orgz_type,
const ConfigProtocol& config_protocol,
const CircuitModelId& sram_model,
const DeviceGrid& grids,
const vtr::Matrix<size_t>& grid_instance_ids,
@ -36,7 +37,8 @@ void organize_top_module_memory_modules(ModuleManager& module_manager,
const bool& compact_routing_hierarchy);
void shuffle_top_module_configurable_children(ModuleManager& module_manager,
const ModuleId& top_module);
const ModuleId& top_module,
const ConfigProtocol& config_protocol);
int load_top_module_memory_modules_from_fabric_key(ModuleManager& module_manager,
const ModuleId& top_module,

View File

@ -65,32 +65,36 @@ int write_fabric_key_to_xml_file(const ModuleManager& module_manager,
num_keys -= 1;
}
/* FIXME: create a region for the keys. Later down the road, we will create multiple regions */
fabric_key.reserve_regions(1);
FabricRegionId region = fabric_key.create_region();
fabric_key.reserve_region_keys(region, num_keys);
fabric_key.reserve_keys(num_keys);
for (size_t ichild = 0; ichild < num_keys; ++ichild) {
ModuleId child_module = module_manager.configurable_children(top_module)[ichild];
size_t child_instance = module_manager.configurable_child_instances(top_module)[ichild];
size_t num_regions = module_manager.regions(top_module).size();
fabric_key.reserve_regions(num_regions);
FabricKeyId key = fabric_key.create_key();
fabric_key.set_key_name(key, module_manager.module_name(child_module));
fabric_key.set_key_value(key, child_instance);
/* Create regions for the keys and load keys by region */
for (const ConfigRegionId& config_region : module_manager.regions(top_module)) {
FabricRegionId fabric_region = fabric_key.create_region();
fabric_key.reserve_region_keys(fabric_region, module_manager.region_configurable_children(top_module, config_region).size());
if (false == module_manager.instance_name(top_module, child_module, child_instance).empty()) {
fabric_key.set_key_alias(key, module_manager.instance_name(top_module, child_module, child_instance));
for (size_t ichild = 0; ichild < num_keys; ++ichild) {
ModuleId child_module = module_manager.region_configurable_children(top_module, config_region)[ichild];
size_t child_instance = module_manager.region_configurable_child_instances(top_module, config_region)[ichild];
FabricKeyId key = fabric_key.create_key();
fabric_key.set_key_name(key, module_manager.module_name(child_module));
fabric_key.set_key_value(key, child_instance);
if (false == module_manager.instance_name(top_module, child_module, child_instance).empty()) {
fabric_key.set_key_alias(key, module_manager.instance_name(top_module, child_module, child_instance));
}
/* Add keys to the region */
fabric_key.add_key_to_region(fabric_region, key);
}
/* Add keys to the region */
fabric_key.add_key_to_region(region, key);
}
VTR_LOGV(verbose,
"Created %lu keys for the top module %s.\n",
num_keys, top_module_name.c_str());
"Created %lu regions and %lu keys for the top module %s.\n",
num_regions, num_keys, top_module_name.c_str());
/* Call the XML writer for fabric key */
int err_code = write_xml_fabric_key(fname.c_str(), fabric_key);

View File

@ -5,6 +5,7 @@
#include <numeric>
#include <algorithm>
#include "vtr_assert.h"
#include "vtr_log.h"
#include "circuit_library.h"
#include "module_manager.h"
@ -97,6 +98,43 @@ ModuleManager::module_net_sink_range ModuleManager::module_net_sinks(const Modul
return vtr::make_range(net_sink_ids_[module][net].begin(), net_sink_ids_[module][net].end());
}
ModuleManager::region_range ModuleManager::regions(const ModuleId& module) const {
VTR_ASSERT(valid_module_id(module));
return vtr::make_range(config_region_ids_[module].begin(), config_region_ids_[module].end());
}
std::vector<ModuleId> ModuleManager::region_configurable_children(const ModuleId& parent_module,
const ConfigRegionId& region) const {
/* Validate the module_id */
VTR_ASSERT(valid_module_id(parent_module));
VTR_ASSERT(valid_region_id(parent_module, region));
std::vector<ModuleId> region_config_children;
region_config_children.reserve(config_region_children_[parent_module][region].size());
for (const size_t& child_id : config_region_children_[parent_module][region]) {
region_config_children.push_back(configurable_children_[parent_module][child_id]);
}
return region_config_children;
}
std::vector<size_t> ModuleManager::region_configurable_child_instances(const ModuleId& parent_module,
const ConfigRegionId& region) const {
/* Validate the module_id */
VTR_ASSERT(valid_module_id(parent_module));
VTR_ASSERT(valid_region_id(parent_module, region));
std::vector<size_t> region_config_child_instances;
region_config_child_instances.reserve(config_region_children_[parent_module][region].size());
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]);
}
return region_config_child_instances;
}
/******************************************************************************
* Public Accessors
******************************************************************************/
@ -482,6 +520,10 @@ ModuleId ModuleManager::add_module(const std::string& name) {
child_instance_names_.emplace_back();
configurable_children_.emplace_back();
configurable_child_instances_.emplace_back();
configurable_child_regions_.emplace_back();
config_region_ids_.emplace_back();
config_region_children_.emplace_back();
port_ids_.emplace_back();
ports_.emplace_back();
@ -661,6 +703,7 @@ void ModuleManager::add_configurable_child(const ModuleId& parent_module,
configurable_children_[parent_module].push_back(child_module);
configurable_child_instances_[parent_module].push_back(child_instance);
configurable_child_regions_[parent_module].push_back(ConfigRegionId::INVALID());
}
void ModuleManager::reserve_configurable_child(const ModuleId& parent_module,
@ -673,6 +716,78 @@ void ModuleManager::reserve_configurable_child(const ModuleId& parent_module,
if (num_children > configurable_child_instances_[parent_module].size()) {
configurable_child_instances_[parent_module].reserve(num_children);
}
if (num_children > configurable_child_instances_[parent_module].size()) {
configurable_child_regions_[parent_module].reserve(num_children);
}
}
ConfigRegionId ModuleManager::add_config_region(const ModuleId& module) {
/* Validate the module id */
VTR_ASSERT ( valid_module_id(module) );
/* Create an new id */
ConfigRegionId config_region_id = ConfigRegionId(config_region_ids_[module].size());
config_region_ids_[module].push_back(config_region_id);
config_region_children_[module].emplace_back();
return config_region_id;
}
void ModuleManager::add_configurable_child_to_region(const ModuleId& parent_module,
const ConfigRegionId& config_region,
const ModuleId& child_module,
const size_t& child_instance) {
/* Validate the module id */
VTR_ASSERT ( valid_module_id(parent_module) );
VTR_ASSERT ( valid_module_id(child_module) );
VTR_ASSERT ( valid_region_id(parent_module, config_region) );
/* Ensure that the child module is in the configurable children list */
size_t config_child_id = configurable_children(parent_module).size();
for (size_t ichild = 0; ichild < configurable_children(parent_module).size(); ++ichild) {
if ( (child_module == configurable_children(parent_module)[ichild])
&& (child_instance == configurable_child_instances(parent_module)[ichild]) ) {
config_child_id = ichild;
break;
}
}
/* Error out as the child is not valid */
if (config_child_id == configurable_children(parent_module).size()) {
VTR_LOGF_ERROR(__FILE__, __LINE__,
"Try to add an invalid configurable child '%s[%lu]' to region '%lu'!\n",
module_name(child_module).c_str(),
child_instance,
size_t(config_region));
exit(1);
}
/* If the child is already in another region, error out */
if (config_region != 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]));
exit(1);
}
/* Ensure that the child is not in the list */
if (config_region_children_[parent_module][config_region].end() != std::find(config_region_children_[parent_module][config_region].begin(),
config_region_children_[parent_module][config_region].end(),
config_child_id)) {
VTR_LOGF_ERROR(__FILE__, __LINE__,
"The configurable child '%s[%lu]' is already in the region '%lu'! Skip adding\n",
module_name(child_module).c_str(),
child_instance,
size_t(config_region));
return;
}
/* Passed all the checks, add the child to the region */
config_region_children_[parent_module][config_region].push_back(config_child_id);
}
void ModuleManager::reserve_module_nets(const ModuleId& module,
@ -869,6 +984,14 @@ void ModuleManager::clear_configurable_children(const ModuleId& parent_module) {
configurable_children_[parent_module].clear();
configurable_child_instances_[parent_module].clear();
configurable_child_regions_[parent_module].clear();
}
void ModuleManager::clear_config_region(const ModuleId& parent_module) {
VTR_ASSERT(valid_module_id(parent_module));
config_region_ids_[parent_module].clear();
config_region_children_[parent_module].clear();
}
/******************************************************************************
@ -902,6 +1025,14 @@ bool ModuleManager::valid_module_instance_id(const ModuleId& parent_module,
return ( instance_id < num_instance(parent_module, child_module) );
}
bool ModuleManager::valid_region_id(const ModuleId& module,
const ConfigRegionId& region) const {
if (false == valid_module_id(module)) {
return false;
}
return ( size_t(region) < config_region_ids_[module].size() ) && ( region == config_region_ids_[module][region] );
}
void ModuleManager::invalidate_name2id_map() {
name_id_map_.clear();
}

View File

@ -124,12 +124,14 @@ class ModuleManager {
typedef lazy_id_iterator<ModuleNetId> module_net_iterator;
typedef vtr::vector<ModuleNetSrcId, ModuleNetSrcId>::const_iterator module_net_src_iterator;
typedef vtr::vector<ModuleNetSinkId, ModuleNetSinkId>::const_iterator module_net_sink_iterator;
typedef vtr::vector<ConfigRegionId, ConfigRegionId>::const_iterator region_iterator;
typedef vtr::Range<module_iterator> module_range;
typedef vtr::Range<module_port_iterator> module_port_range;
typedef vtr::Range<module_net_iterator> module_net_range;
typedef vtr::Range<module_net_src_iterator> module_net_src_range;
typedef vtr::Range<module_net_sink_iterator> module_net_sink_range;
typedef vtr::Range<region_iterator> region_range;
public: /* Public aggregators */
/* Find all the modules */
@ -151,6 +153,15 @@ class ModuleManager {
/* Find the sink ids of modules */
module_net_sink_range module_net_sinks(const ModuleId& module, const ModuleNetId& net) const;
/* Find all the regions */
region_range regions(const ModuleId& module) const;
/* Find all the configurable child modules under a region of a parent module */
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 */
std::vector<size_t> region_configurable_child_instances(const ModuleId& parent_module,
const ConfigRegionId& region) const;
public: /* Public accessors */
size_t num_modules() const;
size_t num_nets(const ModuleId& module) const;
@ -242,6 +253,18 @@ class ModuleManager {
*/
void reserve_configurable_child(const ModuleId& module, const size_t& num_children);
/* Create a new configurable region under a module */
ConfigRegionId add_config_region(const ModuleId& module);
/* Add a configurable child module to a region
* Note:
* - The child module must be added as a configurable child to the parent module
* before calling this function!
*/
void add_configurable_child_to_region(const ModuleId& parent_module,
const ConfigRegionId& config_region,
const ModuleId& child_module,
const size_t& child_instance);
/* Reserved a number of module nets for a given module
* for memory efficiency
*/
@ -281,6 +304,13 @@ class ModuleManager {
* Do NOT use unless you know what you are doing!!!
*/
void clear_configurable_children(const ModuleId& parent_module);
/* This is a strong function which will remove all the configurable regions
* under a given parent module
* It is mainly used by loading fabric keys
* Do NOT use unless you know what you are doing!!!
*/
void clear_config_region(const ModuleId& parent_module);
public: /* Public validators/invalidators */
bool valid_module_id(const ModuleId& module) const;
bool valid_module_port_id(const ModuleId& module, const ModulePortId& port) const;
@ -288,6 +318,8 @@ class ModuleManager {
bool valid_module_instance_id(const ModuleId& parent_module,
const ModuleId& child_module,
const size_t& instance_id) const;
bool valid_region_id(const ModuleId& module,
const ConfigRegionId& region) const;
private: /* Private validators/invalidators */
void invalidate_name2id_map();
void invalidate_port_lookup();
@ -310,6 +342,14 @@ class ModuleManager {
*/
vtr::vector<ModuleId, std::vector<ModuleId>> configurable_children_; /* Child modules with configurable memory bits that this module contain */
vtr::vector<ModuleId, std::vector<size_t>> configurable_child_instances_; /* Instances of child modules with configurable memory bits that this module contain */
vtr::vector<ModuleId, std::vector<ConfigRegionId>> configurable_child_regions_; /* Instances of child modules with configurable memory bits that this module contain */
/* Configurable regions to group the configurable children
* Note:
* - Each child can only be added a group
*/
vtr::vector<ModuleId, vtr::vector<ConfigRegionId, ConfigRegionId>> config_region_ids_;
vtr::vector<ModuleId, vtr::vector<ConfigRegionId, std::vector<size_t>>> config_region_children_;
/* Port-level data */
vtr::vector<ModuleId, vtr::vector<ModulePortId, ModulePortId>> port_ids_; /* List of ports for each Module */

View File

@ -19,6 +19,7 @@ struct module_pin_id_tag;
struct module_net_id_tag;
struct module_net_src_id_tag;
struct module_net_sink_id_tag;
struct config_region_id_tag;
typedef vtr::StrongId<module_id_tag> ModuleId;
typedef vtr::StrongId<instance_id_tag> InstanceId;
@ -27,6 +28,7 @@ typedef vtr::StrongId<module_pin_id_tag> ModulePinId;
typedef vtr::StrongId<module_net_id_tag> ModuleNetId;
typedef vtr::StrongId<module_net_src_id_tag> ModuleNetSrcId;
typedef vtr::StrongId<module_net_sink_id_tag> ModuleNetSinkId;
typedef vtr::StrongId<config_region_id_tag> ConfigRegionId;
class ModuleManager;