[Engine] Start developing QL memory bank: upgrade infrastructures of fabric builder

This commit is contained in:
tangxifan 2021-09-03 17:55:23 -07:00
parent c206c4e95e
commit 5759f5f35b
6 changed files with 202 additions and 60 deletions

View File

@ -125,10 +125,11 @@ enum e_config_protocol_type {
CONFIG_MEM_STANDALONE, CONFIG_MEM_STANDALONE,
CONFIG_MEM_SCAN_CHAIN, CONFIG_MEM_SCAN_CHAIN,
CONFIG_MEM_MEMORY_BANK, CONFIG_MEM_MEMORY_BANK,
CONFIG_MEM_QL_MEMORY_BANK,
CONFIG_MEM_FRAME_BASED, CONFIG_MEM_FRAME_BASED,
NUM_CONFIG_PROTOCOL_TYPES NUM_CONFIG_PROTOCOL_TYPES
}; };
constexpr std::array<const char*, NUM_CONFIG_PROTOCOL_TYPES> CONFIG_PROTOCOL_TYPE_STRING = {{"standalone", "scan_chain", "memory_bank", "frame_based"}}; constexpr std::array<const char*, NUM_CONFIG_PROTOCOL_TYPES> CONFIG_PROTOCOL_TYPE_STRING = {{"standalone", "scan_chain", "memory_bank", "ql_memory_bank", "frame_based"}};
#endif #endif

View File

@ -407,7 +407,7 @@ int build_top_module(ModuleManager& module_manager,
* This is a much easier job after adding sub modules (instances), * 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 * we just need to find all the I/O ports from the child modules and build a list of it
*/ */
vtr::vector<ConfigRegionId, size_t> top_module_num_config_bits = find_top_module_regional_num_config_bit(module_manager, top_module, circuit_lib, sram_model, config_protocol.type()); vtr::vector<ConfigRegionId, TopModuleNumConfigBits> top_module_num_config_bits = find_top_module_regional_num_config_bit(module_manager, top_module, circuit_lib, sram_model, config_protocol.type());
if (!top_module_num_config_bits.empty()) { if (!top_module_num_config_bits.empty()) {
add_top_module_sram_ports(module_manager, top_module, add_top_module_sram_ports(module_manager, top_module,

View File

@ -74,8 +74,9 @@ void organize_top_module_tile_cb_modules(ModuleManager& module_manager,
if (0 < find_module_num_config_bits(module_manager, cb_module, if (0 < find_module_num_config_bits(module_manager, cb_module,
circuit_lib, sram_model, circuit_lib, sram_model,
sram_orgz_type)) { sram_orgz_type)) {
vtr::Point<int> config_coord(rr_gsb.get_cb_x(cb_type) * 2, rr_gsb.get_cb_y(cb_type) * 2);
/* Note that use the original CB coodinate for instance id searching ! */ /* Note that use the original CB coodinate for instance id searching ! */
module_manager.add_configurable_child(top_module, cb_module, cb_instance_ids[rr_gsb.get_cb_x(cb_type)][rr_gsb.get_cb_y(cb_type)]); module_manager.add_configurable_child(top_module, cb_module, cb_instance_ids[rr_gsb.get_cb_x(cb_type)][rr_gsb.get_cb_y(cb_type)], config_coord);
} }
} }
@ -84,6 +85,37 @@ void organize_top_module_tile_cb_modules(ModuleManager& module_manager,
* to the memory modules and memory instances * to the memory modules and memory instances
* This function is designed for organizing memory modules in top-level * This function is designed for organizing memory modules in top-level
* module * module
* This function also adds coordindates for each configurable child under the top-level module
* of a FPGA fabric. A configurable child could be a programmable block (grid),
* a Connection Block (CBx/y) or a Switch block (SB).
* This function, we consider a coordinate system as follows
* - Each row may consist of either (1) grid and CBy or (2) CBx and SB
* - Each column may consist of either (1) grid and CBx or (2) CBy and SB
*
* Column 0 Column 1
*
* +---------------+----------+
* | | |
* | | |
* | Grid | CBY | Row 3
* | | |
* | | |
* +---------------+----------+
* | | |
* | CBX | SB | Row 2
* | | |
* +---------------+----------+
* | | |
* | | |
* | Grid | CBY | Row 1
* | | |
* | | |
* +---------------+----------+
* | | |
* | CBX | SB | Row 0
* | | |
* +---------------+----------+
*******************************************************************/ *******************************************************************/
static static
void organize_top_module_tile_memory_modules(ModuleManager& module_manager, void organize_top_module_tile_memory_modules(ModuleManager& module_manager,
@ -130,7 +162,8 @@ void organize_top_module_tile_memory_modules(ModuleManager& module_manager,
if (0 < find_module_num_config_bits(module_manager, sb_module, if (0 < find_module_num_config_bits(module_manager, sb_module,
circuit_lib, sram_model, circuit_lib, sram_model,
sram_orgz_type)) { sram_orgz_type)) {
module_manager.add_configurable_child(top_module, sb_module, sb_instance_ids[rr_gsb.get_sb_x()][rr_gsb.get_sb_y()]); vtr::Point<int> config_coord(rr_gsb.get_sb_x() * 2 + 1, rr_gsb.get_sb_y() * 2 + 1);
module_manager.add_configurable_child(top_module, sb_module, sb_instance_ids[rr_gsb.get_sb_x()][rr_gsb.get_sb_y()], config_coord);
} }
} }
@ -172,11 +205,11 @@ void organize_top_module_tile_memory_modules(ModuleManager& module_manager,
if (0 < find_module_num_config_bits(module_manager, grid_module, if (0 < find_module_num_config_bits(module_manager, grid_module,
circuit_lib, sram_model, circuit_lib, sram_model,
sram_orgz_type)) { sram_orgz_type)) {
module_manager.add_configurable_child(top_module, grid_module, grid_instance_ids[tile_coord.x()][tile_coord.y()]); vtr::Point<int> config_coord(tile_coord.x() * 2, tile_coord.y() * 2);
module_manager.add_configurable_child(top_module, grid_module, grid_instance_ids[tile_coord.x()][tile_coord.y()], config_coord);
} }
} }
/******************************************************************** /********************************************************************
* Split memory modules into different configurable regions * Split memory modules into different configurable regions
* This function will create regions based on the definition * This function will create regions based on the definition
@ -496,6 +529,7 @@ void shuffle_top_module_configurable_children(ModuleManager& module_manager,
/* Cache the configurable children and their instances */ /* Cache the configurable children and their instances */
std::vector<ModuleId> orig_configurable_children = module_manager.configurable_children(top_module); std::vector<ModuleId> orig_configurable_children = module_manager.configurable_children(top_module);
std::vector<size_t> orig_configurable_child_instances = module_manager.configurable_child_instances(top_module); std::vector<size_t> orig_configurable_child_instances = module_manager.configurable_child_instances(top_module);
std::vector<vtr::Point<int>> orig_configurable_child_coordinates = module_manager.configurable_child_coordinates(top_module);
/* Reorganize the configurable children */ /* Reorganize the configurable children */
module_manager.clear_configurable_children(top_module); module_manager.clear_configurable_children(top_module);
@ -503,7 +537,8 @@ void shuffle_top_module_configurable_children(ModuleManager& module_manager,
for (size_t ikey = 0; ikey < num_keys; ++ikey) { for (size_t ikey = 0; ikey < num_keys; ++ikey) {
module_manager.add_configurable_child(top_module, module_manager.add_configurable_child(top_module,
orig_configurable_children[shuffled_keys[ikey]], orig_configurable_children[shuffled_keys[ikey]],
orig_configurable_child_instances[shuffled_keys[ikey]]); orig_configurable_child_instances[shuffled_keys[ikey]],
orig_configurable_child_coordinates[shuffled_keys[ikey]]);
} }
/* Reset configurable regions */ /* Reset configurable regions */
@ -614,13 +649,13 @@ int load_top_module_memory_modules_from_fabric_key(ModuleManager& module_manager
* - This function should be called after the configurable children * - This function should be called after the configurable children
* is loaded to the top-level module! * is loaded to the top-level module!
********************************************************************/ ********************************************************************/
vtr::vector<ConfigRegionId, size_t> find_top_module_regional_num_config_bit(const ModuleManager& module_manager, vtr::vector<ConfigRegionId, TopModuleNumConfigBits> find_top_module_regional_num_config_bit(const ModuleManager& module_manager,
const ModuleId& top_module, const ModuleId& top_module,
const CircuitLibrary& circuit_lib, const CircuitLibrary& circuit_lib,
const CircuitModelId& sram_model, const CircuitModelId& sram_model,
const e_config_protocol_type& config_protocol_type) { const e_config_protocol_type& config_protocol_type) {
/* Initialize the number of configuration bits for each region */ /* Initialize the number of configuration bits for each region */
vtr::vector<ConfigRegionId, size_t> num_config_bits(module_manager.regions(top_module).size(), 0); vtr::vector<ConfigRegionId, TopModuleNumConfigBits> num_config_bits(module_manager.regions(top_module).size(), TopModuleNumConfigBits(0, 0));
switch (config_protocol_type) { switch (config_protocol_type) {
case CONFIG_MEM_STANDALONE: case CONFIG_MEM_STANDALONE:
@ -632,7 +667,36 @@ vtr::vector<ConfigRegionId, size_t> find_top_module_regional_num_config_bit(cons
*/ */
for (const ConfigRegionId& config_region : module_manager.regions(top_module)) { for (const ConfigRegionId& config_region : module_manager.regions(top_module)) {
for (const ModuleId& child_module : module_manager.region_configurable_children(top_module, config_region)) { for (const ModuleId& child_module : module_manager.region_configurable_children(top_module, config_region)) {
num_config_bits[config_region] += find_module_num_config_bits(module_manager, child_module, circuit_lib, sram_model, config_protocol_type); num_config_bits[config_region].first += find_module_num_config_bits(module_manager, child_module, circuit_lib, sram_model, config_protocol_type);
}
}
break;
}
case CONFIG_MEM_QL_MEMORY_BANK: {
/* For QL memory bank: we will use the row and column information for each configuration child
* in order to identify the number of unique BLs and WLs
* In this configuration protocol,
* - all the configurable child in the same row will share the same WLs
* - the number of WLs per row is limited by the configurable child which requires most WLs
* - each row has independent WLs
* - all the configurable child in the same column will share the same BLs
* - the number of BLs per column is limited by the configurable child which requires most BLs
* - each column has independent BLs
*/
for (const ConfigRegionId& config_region : module_manager.regions(top_module)) {
std::map<int, size_t> num_bls;
std::map<int, size_t> num_wls;
for (size_t child_id = 0; child_id < module_manager.region_configurable_children(top_module, config_region).size(); ++child_id) {
ModuleId child_module = module_manager.region_configurable_children(top_module, config_region)[child_id];
vtr::Point<int> coord = module_manager.region_configurable_child_coordinates(top_module, config_region)[child_id];
num_bls[coord.x()] = std::max(num_bls[coord.x()], find_module_num_config_bits(module_manager, child_module, circuit_lib, sram_model, config_protocol_type));
num_wls[coord.y()] = std::max(num_wls[coord.y()], find_module_num_config_bits(module_manager, child_module, circuit_lib, sram_model, config_protocol_type));
for (const auto& kv : num_bls) {
num_config_bits[config_region].first += kv.first;
}
for (const auto& kv : num_wls) {
num_config_bits[config_region].second += kv.second;
}
} }
} }
break; break;
@ -646,14 +710,14 @@ vtr::vector<ConfigRegionId, size_t> find_top_module_regional_num_config_bit(cons
for (const ConfigRegionId& config_region : module_manager.regions(top_module)) { for (const ConfigRegionId& config_region : module_manager.regions(top_module)) {
for (const ModuleId& child_module : module_manager.region_configurable_children(top_module, config_region)) { for (const ModuleId& child_module : module_manager.region_configurable_children(top_module, config_region)) {
size_t temp_num_config_bits = find_module_num_config_bits(module_manager, child_module, circuit_lib, sram_model, config_protocol_type); size_t temp_num_config_bits = find_module_num_config_bits(module_manager, child_module, circuit_lib, sram_model, config_protocol_type);
num_config_bits[config_region] = std::max((int)temp_num_config_bits, (int)num_config_bits[config_region]); num_config_bits[config_region].first = std::max(temp_num_config_bits, num_config_bits[config_region].first);
} }
/* If there are more than 2 configurable children, we need a decoder /* If there are more than 2 configurable children, we need a decoder
* Otherwise, we can just short wire the address port to the children * Otherwise, we can just short wire the address port to the children
*/ */
if (1 < module_manager.region_configurable_children(top_module, config_region).size()) { if (1 < module_manager.region_configurable_children(top_module, config_region).size()) {
num_config_bits[config_region] += find_mux_local_decoder_addr_size(module_manager.region_configurable_children(top_module, config_region).size()); num_config_bits[config_region].first += find_mux_local_decoder_addr_size(module_manager.region_configurable_children(top_module, config_region).size());
} }
} }
@ -706,34 +770,40 @@ size_t generate_top_module_sram_port_size(const ConfigProtocol& config_protocol,
* top-level module * top-level module
* The type and names of added ports strongly depend on the * The type and names of added ports strongly depend on the
* organization of SRAMs. * organization of SRAMs.
* 1. Standalone SRAMs: * - Standalone SRAMs:
* two ports will be added, which are BL and WL * two ports will be added, which are BL and WL
* 2. Scan-chain Flip-flops: * - Scan-chain Flip-flops:
* two ports will be added, which are the head of scan-chain * two ports will be added, which are the head of scan-chain
* and the tail of scan-chain * and the tail of scan-chain
* IMPORTANT: the port size will be forced to 1 in this case * IMPORTANT: the port size will be forced to 1 in this case
* because the head and tail are both 1-bit ports!!! * because the head and tail are both 1-bit ports!!!
* 3. Memory decoders: * - Memory decoders:
* - An enable signal * - An enable signal
* - A BL address port * - A BL address port
* - A WL address port * - A WL address port
* - A data-in port for the BL decoder * - A data-in port for the BL decoder
* 4. Frame-based memory: * - QL memory decoder:
* - An Enable signal * - An enable signal
* - An address port, whose size depends on the number of config bits * - An BL address port
* and the maximum size of address ports of configurable children * - A WL address port
* - An data_in port (single-bit) * - A data-in port for the BL decoder
* @note In this memory decoders, the address size will be computed in a different way than the regular one
* - Frame-based memory:
* - An Enable signal
* - An address port, whose size depends on the number of config bits
* and the maximum size of address ports of configurable children
* - An data_in port (single-bit)
********************************************************************/ ********************************************************************/
void add_top_module_sram_ports(ModuleManager& module_manager, void add_top_module_sram_ports(ModuleManager& module_manager,
const ModuleId& module_id, const ModuleId& module_id,
const CircuitLibrary& circuit_lib, const CircuitLibrary& circuit_lib,
const CircuitModelId& sram_model, const CircuitModelId& sram_model,
const ConfigProtocol& config_protocol, const ConfigProtocol& config_protocol,
const vtr::vector<ConfigRegionId, size_t>& num_config_bits) { const vtr::vector<ConfigRegionId, TopModuleNumConfigBits>& num_config_bits) {
std::vector<std::string> sram_port_names = generate_sram_port_names(circuit_lib, sram_model, config_protocol.type()); std::vector<std::string> sram_port_names = generate_sram_port_names(circuit_lib, sram_model, config_protocol.type());
size_t total_num_config_bits = 0; size_t total_num_config_bits = 0;
for (const size_t& curr_num_config_bits : num_config_bits) { for (const auto& curr_num_config_bits : num_config_bits) {
total_num_config_bits += curr_num_config_bits; total_num_config_bits += curr_num_config_bits.first;
} }
size_t sram_port_size = generate_top_module_sram_port_size(config_protocol, total_num_config_bits); size_t sram_port_size = generate_top_module_sram_port_size(config_protocol, total_num_config_bits);
@ -754,7 +824,7 @@ void add_top_module_sram_ports(ModuleManager& module_manager,
/* BL address size is the largest among all the regions */ /* BL address size is the largest among all the regions */
size_t bl_addr_size = 0; size_t bl_addr_size = 0;
for (const ConfigRegionId& config_region : module_manager.regions(module_id)) { for (const ConfigRegionId& config_region : module_manager.regions(module_id)) {
bl_addr_size = std::max(bl_addr_size, find_memory_decoder_addr_size(num_config_bits[config_region])); bl_addr_size = std::max(bl_addr_size, find_memory_decoder_addr_size(num_config_bits[config_region].first));
} }
BasicPort bl_addr_port(std::string(DECODER_BL_ADDRESS_PORT_NAME), bl_addr_size); BasicPort bl_addr_port(std::string(DECODER_BL_ADDRESS_PORT_NAME), bl_addr_size);
module_manager.add_port(module_id, bl_addr_port, ModuleManager::MODULE_INPUT_PORT); module_manager.add_port(module_id, bl_addr_port, ModuleManager::MODULE_INPUT_PORT);
@ -762,7 +832,33 @@ void add_top_module_sram_ports(ModuleManager& module_manager,
/* WL address size is the largest among all the regions */ /* WL address size is the largest among all the regions */
size_t wl_addr_size = 0; size_t wl_addr_size = 0;
for (const ConfigRegionId& config_region : module_manager.regions(module_id)) { for (const ConfigRegionId& config_region : module_manager.regions(module_id)) {
wl_addr_size = std::max(wl_addr_size, find_memory_decoder_addr_size(num_config_bits[config_region])); wl_addr_size = std::max(wl_addr_size, find_memory_decoder_addr_size(num_config_bits[config_region].first));
}
BasicPort wl_addr_port(std::string(DECODER_WL_ADDRESS_PORT_NAME), wl_addr_size);
module_manager.add_port(module_id, wl_addr_port, ModuleManager::MODULE_INPUT_PORT);
/* Data input should be dependent on the number of configuration regions*/
BasicPort din_port(std::string(DECODER_DATA_IN_PORT_NAME), config_protocol.num_regions());
module_manager.add_port(module_id, din_port, ModuleManager::MODULE_INPUT_PORT);
break;
}
case CONFIG_MEM_QL_MEMORY_BANK: {
BasicPort en_port(std::string(DECODER_ENABLE_PORT_NAME), 1);
module_manager.add_port(module_id, en_port, ModuleManager::MODULE_INPUT_PORT);
/* BL address size is the largest among all the regions */
size_t bl_addr_size = 0;
for (const ConfigRegionId& config_region : module_manager.regions(module_id)) {
bl_addr_size = std::max(bl_addr_size, find_memory_decoder_addr_size(num_config_bits[config_region].first));
}
BasicPort bl_addr_port(std::string(DECODER_BL_ADDRESS_PORT_NAME), bl_addr_size);
module_manager.add_port(module_id, bl_addr_port, ModuleManager::MODULE_INPUT_PORT);
/* WL address size is the largest among all the regions */
size_t wl_addr_size = 0;
for (const ConfigRegionId& config_region : module_manager.regions(module_id)) {
wl_addr_size = std::max(wl_addr_size, find_memory_decoder_addr_size(num_config_bits[config_region].second));
} }
BasicPort wl_addr_port(std::string(DECODER_WL_ADDRESS_PORT_NAME), wl_addr_size); BasicPort wl_addr_port(std::string(DECODER_WL_ADDRESS_PORT_NAME), wl_addr_size);
module_manager.add_port(module_id, wl_addr_port, ModuleManager::MODULE_INPUT_PORT); module_manager.add_port(module_id, wl_addr_port, ModuleManager::MODULE_INPUT_PORT);
@ -798,8 +894,8 @@ void add_top_module_sram_ports(ModuleManager& module_manager,
module_manager.add_port(module_id, en_port, ModuleManager::MODULE_INPUT_PORT); module_manager.add_port(module_id, en_port, ModuleManager::MODULE_INPUT_PORT);
size_t max_num_config_bits = 0; size_t max_num_config_bits = 0;
for (const size_t& curr_num_config_bits : num_config_bits) { for (const auto& curr_num_config_bits : num_config_bits) {
max_num_config_bits = std::max(max_num_config_bits, curr_num_config_bits); max_num_config_bits = std::max(max_num_config_bits, curr_num_config_bits.first);
} }
BasicPort addr_port(std::string(DECODER_ADDRESS_PORT_NAME), max_num_config_bits); BasicPort addr_port(std::string(DECODER_ADDRESS_PORT_NAME), max_num_config_bits);
@ -910,7 +1006,7 @@ static
void add_top_module_nets_cmos_memory_bank_config_bus(ModuleManager& module_manager, void add_top_module_nets_cmos_memory_bank_config_bus(ModuleManager& module_manager,
DecoderLibrary& decoder_lib, DecoderLibrary& decoder_lib,
const ModuleId& top_module, const ModuleId& top_module,
const vtr::vector<ConfigRegionId, size_t>& num_config_bits) { const vtr::vector<ConfigRegionId, TopModuleNumConfigBits>& num_config_bits) {
/* Find Enable port from the top-level module */ /* Find Enable port from the top-level module */
ModulePortId en_port = module_manager.find_module_port(top_module, std::string(DECODER_ENABLE_PORT_NAME)); ModulePortId en_port = module_manager.find_module_port(top_module, std::string(DECODER_ENABLE_PORT_NAME));
BasicPort en_port_info = module_manager.module_port(top_module, en_port); BasicPort en_port_info = module_manager.module_port(top_module, en_port);
@ -935,13 +1031,13 @@ void add_top_module_nets_cmos_memory_bank_config_bus(ModuleManager& module_manag
/* Each memory bank has a unified number of BL/WLs */ /* Each memory bank has a unified number of BL/WLs */
size_t num_bls = 0; size_t num_bls = 0;
for (const size_t& curr_config_bits : num_config_bits) { for (const auto& curr_config_bits : num_config_bits) {
num_bls = std::max(num_bls, find_memory_decoder_data_size(curr_config_bits)); num_bls = std::max(num_bls, find_memory_decoder_data_size(curr_config_bits.first));
} }
size_t num_wls = 0; size_t num_wls = 0;
for (const size_t& curr_config_bits : num_config_bits) { for (const auto& curr_config_bits : num_config_bits) {
num_wls = std::max(num_wls, find_memory_decoder_data_size(curr_config_bits)); num_wls = std::max(num_wls, find_memory_decoder_data_size(curr_config_bits.first));
} }
/* Create separated memory bank circuitry, i.e., BL/WL decoders for each region */ /* Create separated memory bank circuitry, i.e., BL/WL decoders for each region */
@ -1582,7 +1678,7 @@ static
void add_top_module_nets_cmos_memory_frame_config_bus(ModuleManager& module_manager, void add_top_module_nets_cmos_memory_frame_config_bus(ModuleManager& module_manager,
DecoderLibrary& decoder_lib, DecoderLibrary& decoder_lib,
const ModuleId& top_module, const ModuleId& top_module,
const vtr::vector<ConfigRegionId, size_t>& num_config_bits) { const vtr::vector<ConfigRegionId, TopModuleNumConfigBits>& num_config_bits) {
/* Find the number of address bits for the top-level module */ /* Find the number of address bits for the top-level module */
ModulePortId top_addr_port = module_manager.find_module_port(top_module, std::string(DECODER_ADDRESS_PORT_NAME)); ModulePortId top_addr_port = module_manager.find_module_port(top_module, std::string(DECODER_ADDRESS_PORT_NAME));
BasicPort top_addr_port_info = module_manager.module_port(top_module, top_addr_port); BasicPort top_addr_port_info = module_manager.module_port(top_module, top_addr_port);
@ -1598,7 +1694,7 @@ void add_top_module_nets_cmos_memory_frame_config_bus(ModuleManager& module_mana
* - The number of address bits of the configurable child is the same as top-level * - The number of address bits of the configurable child is the same as top-level
*/ */
if ( (1 == module_manager.region_configurable_children(top_module, config_region).size()) if ( (1 == module_manager.region_configurable_children(top_module, config_region).size())
&& (num_config_bits[config_region] == top_addr_size)) { && (num_config_bits[config_region].first == top_addr_size)) {
add_top_module_nets_cmos_memory_frame_short_config_bus(module_manager, top_module, config_region); add_top_module_nets_cmos_memory_frame_short_config_bus(module_manager, top_module, config_region);
} else { } else {
add_top_module_nets_cmos_memory_frame_decoder_config_bus(module_manager, decoder_lib, top_module, config_region); add_top_module_nets_cmos_memory_frame_decoder_config_bus(module_manager, decoder_lib, top_module, config_region);
@ -1655,7 +1751,7 @@ void add_top_module_nets_cmos_memory_config_bus(ModuleManager& module_manager,
DecoderLibrary& decoder_lib, DecoderLibrary& decoder_lib,
const ModuleId& parent_module, const ModuleId& parent_module,
const ConfigProtocol& config_protocol, const ConfigProtocol& config_protocol,
const vtr::vector<ConfigRegionId, size_t>& num_config_bits) { const vtr::vector<ConfigRegionId, TopModuleNumConfigBits>& num_config_bits) {
switch (config_protocol.type()) { switch (config_protocol.type()) {
case CONFIG_MEM_STANDALONE: case CONFIG_MEM_STANDALONE:
add_module_nets_cmos_flatten_memory_config_bus(module_manager, parent_module, add_module_nets_cmos_flatten_memory_config_bus(module_manager, parent_module,
@ -1717,7 +1813,7 @@ void add_top_module_nets_memory_config_bus(ModuleManager& module_manager,
const ModuleId& parent_module, const ModuleId& parent_module,
const ConfigProtocol& config_protocol, const ConfigProtocol& config_protocol,
const e_circuit_model_design_tech& mem_tech, const e_circuit_model_design_tech& mem_tech,
const vtr::vector<ConfigRegionId, size_t>& num_config_bits) { const vtr::vector<ConfigRegionId, TopModuleNumConfigBits>& num_config_bits) {
vtr::ScopedStartFinishTimer timer("Add module nets for configuration buses"); vtr::ScopedStartFinishTimer timer("Add module nets for configuration buses");

View File

@ -26,6 +26,8 @@
/* begin namespace openfpga */ /* begin namespace openfpga */
namespace openfpga { namespace openfpga {
typedef std::pair<size_t, size_t> TopModuleNumConfigBits;
void organize_top_module_memory_modules(ModuleManager& module_manager, void organize_top_module_memory_modules(ModuleManager& module_manager,
const ModuleId& top_module, const ModuleId& top_module,
const CircuitLibrary& circuit_lib, const CircuitLibrary& circuit_lib,
@ -48,25 +50,25 @@ int load_top_module_memory_modules_from_fabric_key(ModuleManager& module_manager
const ConfigProtocol& config_protocol, const ConfigProtocol& config_protocol,
const FabricKey& fabric_key); const FabricKey& fabric_key);
vtr::vector<ConfigRegionId, size_t> find_top_module_regional_num_config_bit(const ModuleManager& module_manager, vtr::vector<ConfigRegionId, TopModuleNumConfigBits> find_top_module_regional_num_config_bit(const ModuleManager& module_manager,
const ModuleId& top_module, const ModuleId& top_module,
const CircuitLibrary& circuit_lib, const CircuitLibrary& circuit_lib,
const CircuitModelId& sram_model, const CircuitModelId& sram_model,
const e_config_protocol_type& config_protocol_type); const e_config_protocol_type& config_protocol_type);
void add_top_module_sram_ports(ModuleManager& module_manager, void add_top_module_sram_ports(ModuleManager& module_manager,
const ModuleId& module_id, const ModuleId& module_id,
const CircuitLibrary& circuit_lib, const CircuitLibrary& circuit_lib,
const CircuitModelId& sram_model, const CircuitModelId& sram_model,
const ConfigProtocol& config_protocol, const ConfigProtocol& config_protocol,
const vtr::vector<ConfigRegionId, size_t>& num_config_bits); const vtr::vector<ConfigRegionId, TopModuleNumConfigBits>& num_config_bits);
void add_top_module_nets_memory_config_bus(ModuleManager& module_manager, void add_top_module_nets_memory_config_bus(ModuleManager& module_manager,
DecoderLibrary& decoder_lib, DecoderLibrary& decoder_lib,
const ModuleId& parent_module, const ModuleId& parent_module,
const ConfigProtocol& config_protocol, const ConfigProtocol& config_protocol,
const e_circuit_model_design_tech& mem_tech, const e_circuit_model_design_tech& mem_tech,
const vtr::vector<ConfigRegionId, size_t>& num_config_bits); const vtr::vector<ConfigRegionId, TopModuleNumConfigBits>& num_config_bits);
} /* end namespace openfpga */ } /* end namespace openfpga */

View File

@ -84,6 +84,13 @@ std::vector<size_t> ModuleManager::configurable_child_instances(const ModuleId&
return configurable_child_instances_[parent_module]; return configurable_child_instances_[parent_module];
} }
std::vector<vtr::Point<int>> ModuleManager::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];
}
/* Find the source ids of modules */ /* Find the source ids of modules */
ModuleManager::module_net_src_range ModuleManager::module_net_sources(const ModuleId& module, const ModuleNetId& net) const { ModuleManager::module_net_src_range ModuleManager::module_net_sources(const ModuleId& module, const ModuleNetId& net) const {
/* Validate the module_id */ /* Validate the module_id */
@ -135,6 +142,22 @@ std::vector<size_t> ModuleManager::region_configurable_child_instances(const Mod
return region_config_child_instances; return region_config_child_instances;
} }
std::vector<vtr::Point<int>> ModuleManager::region_configurable_child_coordinates(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<vtr::Point<int>> region_config_child_coordinates;
region_config_child_coordinates.reserve(config_region_children_[parent_module][region].size());
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]);
}
return region_config_child_coordinates;
}
/****************************************************************************** /******************************************************************************
* Public Accessors * Public Accessors
******************************************************************************/ ******************************************************************************/
@ -534,6 +557,7 @@ ModuleId ModuleManager::add_module(const std::string& name) {
configurable_children_.emplace_back(); configurable_children_.emplace_back();
configurable_child_instances_.emplace_back(); configurable_child_instances_.emplace_back();
configurable_child_regions_.emplace_back(); configurable_child_regions_.emplace_back();
configurable_child_coordinates_.emplace_back();
config_region_ids_.emplace_back(); config_region_ids_.emplace_back();
config_region_children_.emplace_back(); config_region_children_.emplace_back();
@ -716,7 +740,8 @@ void ModuleManager::set_child_instance_name(const ModuleId& parent_module,
*/ */
void ModuleManager::add_configurable_child(const ModuleId& parent_module, void ModuleManager::add_configurable_child(const ModuleId& parent_module,
const ModuleId& child_module, const ModuleId& child_module,
const size_t& child_instance) { const size_t& child_instance,
const vtr::Point<int> coord) {
/* Validate the id of both parent and child modules */ /* Validate the id of both parent and child modules */
VTR_ASSERT ( valid_module_id(parent_module) ); VTR_ASSERT ( valid_module_id(parent_module) );
VTR_ASSERT ( valid_module_id(child_module) ); VTR_ASSERT ( valid_module_id(child_module) );
@ -726,6 +751,7 @@ void ModuleManager::add_configurable_child(const ModuleId& parent_module,
configurable_children_[parent_module].push_back(child_module); configurable_children_[parent_module].push_back(child_module);
configurable_child_instances_[parent_module].push_back(child_instance); configurable_child_instances_[parent_module].push_back(child_instance);
configurable_child_regions_[parent_module].push_back(ConfigRegionId::INVALID()); configurable_child_regions_[parent_module].push_back(ConfigRegionId::INVALID());
configurable_child_coordinates_[parent_module].push_back(coord);
} }
void ModuleManager::reserve_configurable_child(const ModuleId& parent_module, void ModuleManager::reserve_configurable_child(const ModuleId& parent_module,
@ -738,9 +764,12 @@ void ModuleManager::reserve_configurable_child(const ModuleId& parent_module,
if (num_children > configurable_child_instances_[parent_module].size()) { if (num_children > configurable_child_instances_[parent_module].size()) {
configurable_child_instances_[parent_module].reserve(num_children); configurable_child_instances_[parent_module].reserve(num_children);
} }
if (num_children > configurable_child_instances_[parent_module].size()) { if (num_children > configurable_child_regions_[parent_module].size()) {
configurable_child_regions_[parent_module].reserve(num_children); configurable_child_regions_[parent_module].reserve(num_children);
} }
if (num_children > configurable_child_coordinates_[parent_module].size()) {
configurable_child_coordinates_[parent_module].reserve(num_children);
}
} }
ConfigRegionId ModuleManager::add_config_region(const ModuleId& module) { ConfigRegionId ModuleManager::add_config_region(const ModuleId& module) {
@ -981,6 +1010,7 @@ void ModuleManager::clear_configurable_children(const ModuleId& parent_module) {
configurable_children_[parent_module].clear(); configurable_children_[parent_module].clear();
configurable_child_instances_[parent_module].clear(); configurable_child_instances_[parent_module].clear();
configurable_child_regions_[parent_module].clear(); configurable_child_regions_[parent_module].clear();
configurable_child_coordinates_[parent_module].clear();
} }
void ModuleManager::clear_config_region(const ModuleId& parent_module) { void ModuleManager::clear_config_region(const ModuleId& parent_module) {

View File

@ -8,6 +8,7 @@
#include <unordered_map> #include <unordered_map>
#include "vtr_vector.h" #include "vtr_vector.h"
#include "vtr_geometry.h"
#include "module_manager_fwd.h" #include "module_manager_fwd.h"
#include "openfpga_port.h" #include "openfpga_port.h"
@ -148,6 +149,8 @@ class ModuleManager {
std::vector<ModuleId> configurable_children(const ModuleId& parent_module) const; std::vector<ModuleId> configurable_children(const ModuleId& parent_module) const;
/* Find all the instances of configurable child modules under a parent module */ /* Find all the instances of configurable child modules under a parent module */
std::vector<size_t> configurable_child_instances(const ModuleId& parent_module) const; std::vector<size_t> configurable_child_instances(const ModuleId& parent_module) const;
/* Find the coordindate of a configurable child module under a parent module */
std::vector<vtr::Point<int>> configurable_child_coordinates(const ModuleId& parent_module) const;
/* Find the source ids of modules */ /* Find the source ids of modules */
module_net_src_range module_net_sources(const ModuleId& module, const ModuleNetId& net) const; module_net_src_range module_net_sources(const ModuleId& module, const ModuleNetId& net) const;
/* Find the sink ids of modules */ /* Find the sink ids of modules */
@ -161,6 +164,10 @@ class ModuleManager {
/* Find all the instances of configurable child modules under a region of a parent module */ /* 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, std::vector<size_t> region_configurable_child_instances(const ModuleId& parent_module,
const ConfigRegionId& region) const; const ConfigRegionId& region) const;
/* Find all the coordinates of configurable child modules under a region of a parent module */
std::vector<vtr::Point<int>> region_configurable_child_coordinates(const ModuleId& parent_module,
const ConfigRegionId& region) const;
public: /* Public accessors */ public: /* Public accessors */
size_t num_modules() const; size_t num_modules() const;
@ -252,8 +259,13 @@ class ModuleManager {
void add_child_module(const ModuleId& parent_module, const ModuleId& child_module); void add_child_module(const ModuleId& parent_module, const ModuleId& child_module);
/* Set the instance name of a child module */ /* Set the instance name of a child module */
void set_child_instance_name(const ModuleId& parent_module, const ModuleId& child_module, const size_t& instance_id, const std::string& instance_name); void set_child_instance_name(const ModuleId& parent_module, const ModuleId& child_module, const size_t& instance_id, const std::string& instance_name);
/* Add a configurable child module to module */ /* Add a configurable child module to module
void add_configurable_child(const ModuleId& module, const ModuleId& child_module, const size_t& child_instance); * This function also set the coordinate of a configurable child
* The coordinate is a relative position in each region, which is used to
* idenify BL/WL sharing
* By default, it is an invalid coordinate
*/
void add_configurable_child(const ModuleId& module, const ModuleId& child_module, const size_t& child_instance, const vtr::Point<int> coord = vtr::Point<int>(-1, -1));
/* Reserved a number of configurable children /* Reserved a number of configurable children
* for memory efficiency * for memory efficiency
*/ */
@ -350,6 +362,7 @@ 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<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<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 */ vtr::vector<ModuleId, std::vector<ConfigRegionId>> configurable_child_regions_; /* Instances of child modules with configurable memory bits that this module contain */
vtr::vector<ModuleId, std::vector<vtr::Point<int>>> configurable_child_coordinates_; /* Relative coorindates of child modules with configurable memory bits that this module contain */
/* Configurable regions to group the configurable children /* Configurable regions to group the configurable children
* Note: * Note: