[OpenFPGA Tool] Support configurable regions in module manager
This commit is contained in:
parent
1e70825383
commit
552dddffd0
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
Loading…
Reference in New Issue