[Engine] Start developing QL memory bank: upgrade infrastructures of fabric builder
This commit is contained in:
parent
c206c4e95e
commit
5759f5f35b
|
@ -125,10 +125,11 @@ enum e_config_protocol_type {
|
|||
CONFIG_MEM_STANDALONE,
|
||||
CONFIG_MEM_SCAN_CHAIN,
|
||||
CONFIG_MEM_MEMORY_BANK,
|
||||
CONFIG_MEM_QL_MEMORY_BANK,
|
||||
CONFIG_MEM_FRAME_BASED,
|
||||
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
|
||||
|
|
|
@ -407,7 +407,7 @@ 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
|
||||
*/
|
||||
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()) {
|
||||
add_top_module_sram_ports(module_manager, top_module,
|
||||
|
|
|
@ -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,
|
||||
circuit_lib, sram_model,
|
||||
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 ! */
|
||||
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
|
||||
* This function is designed for organizing memory modules in top-level
|
||||
* 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
|
||||
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,
|
||||
circuit_lib, sram_model,
|
||||
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,
|
||||
circuit_lib, sram_model,
|
||||
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
|
||||
* 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 */
|
||||
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<vtr::Point<int>> orig_configurable_child_coordinates = module_manager.configurable_child_coordinates(top_module);
|
||||
|
||||
/* Reorganize the configurable children */
|
||||
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) {
|
||||
module_manager.add_configurable_child(top_module,
|
||||
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 */
|
||||
|
@ -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
|
||||
* is loaded to the top-level module!
|
||||
********************************************************************/
|
||||
vtr::vector<ConfigRegionId, size_t> find_top_module_regional_num_config_bit(const ModuleManager& module_manager,
|
||||
const ModuleId& top_module,
|
||||
const CircuitLibrary& circuit_lib,
|
||||
const CircuitModelId& sram_model,
|
||||
const e_config_protocol_type& config_protocol_type) {
|
||||
vtr::vector<ConfigRegionId, TopModuleNumConfigBits> find_top_module_regional_num_config_bit(const ModuleManager& module_manager,
|
||||
const ModuleId& top_module,
|
||||
const CircuitLibrary& circuit_lib,
|
||||
const CircuitModelId& sram_model,
|
||||
const e_config_protocol_type& config_protocol_type) {
|
||||
/* 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) {
|
||||
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 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;
|
||||
|
@ -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 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);
|
||||
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
|
||||
* Otherwise, we can just short wire the address port to the children
|
||||
*/
|
||||
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
|
||||
* The type and names of added ports strongly depend on the
|
||||
* organization of SRAMs.
|
||||
* 1. Standalone SRAMs:
|
||||
* two ports will be added, which are BL and WL
|
||||
* 2. Scan-chain Flip-flops:
|
||||
* two ports will be added, which are the head of scan-chain
|
||||
* and the tail of scan-chain
|
||||
* IMPORTANT: the port size will be forced to 1 in this case
|
||||
* because the head and tail are both 1-bit ports!!!
|
||||
* 3. Memory decoders:
|
||||
* - An enable signal
|
||||
* - A BL address port
|
||||
* - A WL address port
|
||||
* - A data-in port for the BL decoder
|
||||
* 4. 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)
|
||||
* - Standalone SRAMs:
|
||||
* two ports will be added, which are BL and WL
|
||||
* - Scan-chain Flip-flops:
|
||||
* two ports will be added, which are the head of scan-chain
|
||||
* and the tail of scan-chain
|
||||
* IMPORTANT: the port size will be forced to 1 in this case
|
||||
* because the head and tail are both 1-bit ports!!!
|
||||
* - Memory decoders:
|
||||
* - An enable signal
|
||||
* - A BL address port
|
||||
* - A WL address port
|
||||
* - A data-in port for the BL decoder
|
||||
* - QL memory decoder:
|
||||
* - An enable signal
|
||||
* - An BL address port
|
||||
* - A WL address port
|
||||
* - 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,
|
||||
const ModuleId& module_id,
|
||||
const CircuitLibrary& circuit_lib,
|
||||
const CircuitModelId& sram_model,
|
||||
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());
|
||||
size_t total_num_config_bits = 0;
|
||||
for (const size_t& curr_num_config_bits : num_config_bits) {
|
||||
total_num_config_bits += curr_num_config_bits;
|
||||
for (const auto& curr_num_config_bits : 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);
|
||||
|
||||
|
@ -754,7 +824,7 @@ void add_top_module_sram_ports(ModuleManager& module_manager,
|
|||
/* 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]));
|
||||
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);
|
||||
|
@ -762,7 +832,33 @@ void add_top_module_sram_ports(ModuleManager& module_manager,
|
|||
/* 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]));
|
||||
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);
|
||||
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);
|
||||
|
||||
size_t max_num_config_bits = 0;
|
||||
for (const size_t& curr_num_config_bits : num_config_bits) {
|
||||
max_num_config_bits = std::max(max_num_config_bits, curr_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.first);
|
||||
}
|
||||
|
||||
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,
|
||||
DecoderLibrary& decoder_lib,
|
||||
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 */
|
||||
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);
|
||||
|
@ -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 */
|
||||
size_t num_bls = 0;
|
||||
for (const size_t& curr_config_bits : num_config_bits) {
|
||||
num_bls = std::max(num_bls, find_memory_decoder_data_size(curr_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.first));
|
||||
}
|
||||
|
||||
size_t num_wls = 0;
|
||||
for (const size_t& curr_config_bits : num_config_bits) {
|
||||
num_wls = std::max(num_wls, find_memory_decoder_data_size(curr_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.first));
|
||||
}
|
||||
|
||||
/* 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,
|
||||
DecoderLibrary& decoder_lib,
|
||||
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 */
|
||||
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);
|
||||
|
@ -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
|
||||
*/
|
||||
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);
|
||||
} else {
|
||||
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,
|
||||
const ModuleId& parent_module,
|
||||
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()) {
|
||||
case CONFIG_MEM_STANDALONE:
|
||||
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 ConfigProtocol& config_protocol,
|
||||
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");
|
||||
|
||||
|
|
|
@ -26,6 +26,8 @@
|
|||
/* begin namespace openfpga */
|
||||
namespace openfpga {
|
||||
|
||||
typedef std::pair<size_t, size_t> TopModuleNumConfigBits;
|
||||
|
||||
void organize_top_module_memory_modules(ModuleManager& module_manager,
|
||||
const ModuleId& top_module,
|
||||
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 FabricKey& fabric_key);
|
||||
|
||||
vtr::vector<ConfigRegionId, size_t> find_top_module_regional_num_config_bit(const ModuleManager& module_manager,
|
||||
const ModuleId& top_module,
|
||||
const CircuitLibrary& circuit_lib,
|
||||
const CircuitModelId& sram_model,
|
||||
const e_config_protocol_type& config_protocol_type);
|
||||
vtr::vector<ConfigRegionId, TopModuleNumConfigBits> find_top_module_regional_num_config_bit(const ModuleManager& module_manager,
|
||||
const ModuleId& top_module,
|
||||
const CircuitLibrary& circuit_lib,
|
||||
const CircuitModelId& sram_model,
|
||||
const e_config_protocol_type& config_protocol_type);
|
||||
|
||||
void add_top_module_sram_ports(ModuleManager& module_manager,
|
||||
const ModuleId& module_id,
|
||||
const CircuitLibrary& circuit_lib,
|
||||
const CircuitModelId& sram_model,
|
||||
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,
|
||||
DecoderLibrary& decoder_lib,
|
||||
const ModuleId& parent_module,
|
||||
const ConfigProtocol& config_protocol,
|
||||
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 */
|
||||
|
||||
|
|
|
@ -84,6 +84,13 @@ std::vector<size_t> ModuleManager::configurable_child_instances(const ModuleId&
|
|||
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 */
|
||||
ModuleManager::module_net_src_range ModuleManager::module_net_sources(const ModuleId& module, const ModuleNetId& net) const {
|
||||
/* Validate the module_id */
|
||||
|
@ -135,6 +142,22 @@ std::vector<size_t> ModuleManager::region_configurable_child_instances(const Mod
|
|||
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
|
||||
******************************************************************************/
|
||||
|
@ -534,6 +557,7 @@ ModuleId ModuleManager::add_module(const std::string& name) {
|
|||
configurable_children_.emplace_back();
|
||||
configurable_child_instances_.emplace_back();
|
||||
configurable_child_regions_.emplace_back();
|
||||
configurable_child_coordinates_.emplace_back();
|
||||
|
||||
config_region_ids_.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,
|
||||
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 */
|
||||
VTR_ASSERT ( valid_module_id(parent_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_child_instances_[parent_module].push_back(child_instance);
|
||||
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,
|
||||
|
@ -738,9 +764,12 @@ 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()) {
|
||||
if (num_children > configurable_child_regions_[parent_module].size()) {
|
||||
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) {
|
||||
|
@ -981,6 +1010,7 @@ 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();
|
||||
configurable_child_coordinates_[parent_module].clear();
|
||||
}
|
||||
|
||||
void ModuleManager::clear_config_region(const ModuleId& parent_module) {
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include <unordered_map>
|
||||
|
||||
#include "vtr_vector.h"
|
||||
#include "vtr_geometry.h"
|
||||
#include "module_manager_fwd.h"
|
||||
#include "openfpga_port.h"
|
||||
|
||||
|
@ -148,6 +149,8 @@ class ModuleManager {
|
|||
std::vector<ModuleId> configurable_children(const ModuleId& parent_module) const;
|
||||
/* Find all the instances of configurable child modules under a parent module */
|
||||
std::vector<size_t> configurable_child_instances(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 */
|
||||
module_net_src_range module_net_sources(const ModuleId& module, const ModuleNetId& net) const;
|
||||
/* Find the sink ids of modules */
|
||||
|
@ -162,6 +165,10 @@ class ModuleManager {
|
|||
std::vector<size_t> region_configurable_child_instances(const ModuleId& parent_module,
|
||||
const ConfigRegionId& region) const;
|
||||
|
||||
/* Find all the coordinates of configurable child modules under a region of a parent module */
|
||||
std::vector<vtr::Point<int>> region_configurable_child_coordinates(const ModuleId& parent_module,
|
||||
const ConfigRegionId& region) const;
|
||||
|
||||
public: /* Public accessors */
|
||||
size_t num_modules() const;
|
||||
size_t num_nets(const ModuleId& module) const;
|
||||
|
@ -252,8 +259,13 @@ class ModuleManager {
|
|||
void add_child_module(const ModuleId& parent_module, const ModuleId& 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);
|
||||
/* Add a configurable child module to module */
|
||||
void add_configurable_child(const ModuleId& module, const ModuleId& child_module, const size_t& child_instance);
|
||||
/* Add a configurable child module to module
|
||||
* 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
|
||||
* 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<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<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
|
||||
* Note:
|
||||
|
|
Loading…
Reference in New Issue