[Engine] Merge BL/WLs in the Grid/CB/SB modules
This commit is contained in:
parent
4af6413c97
commit
26b1e48723
|
@ -1114,14 +1114,14 @@ void build_physical_tile_module(ModuleManager& module_manager,
|
|||
*/
|
||||
size_t module_num_config_bits = find_module_num_config_bits_from_child_modules(module_manager, grid_module, circuit_lib, sram_model, sram_orgz_type);
|
||||
if (0 < module_num_config_bits) {
|
||||
add_sram_ports_to_module_manager(module_manager, grid_module, circuit_lib, sram_model, sram_orgz_type, module_num_config_bits);
|
||||
add_pb_sram_ports_to_module_manager(module_manager, grid_module, circuit_lib, sram_model, sram_orgz_type, module_num_config_bits);
|
||||
}
|
||||
|
||||
/* Add module nets to connect memory cells inside
|
||||
* This is a one-shot addition that covers all the memory modules in this pb module!
|
||||
*/
|
||||
if (0 < module_manager.configurable_children(grid_module).size()) {
|
||||
add_module_nets_memory_config_bus(module_manager, decoder_lib, grid_module,
|
||||
add_pb_module_nets_memory_config_bus(module_manager, decoder_lib, grid_module,
|
||||
sram_orgz_type, circuit_lib.design_tech_type(sram_model));
|
||||
}
|
||||
|
||||
|
|
|
@ -462,14 +462,14 @@ void build_switch_block_module(ModuleManager& module_manager,
|
|||
*/
|
||||
size_t module_num_config_bits = find_module_num_config_bits_from_child_modules(module_manager, sb_module, circuit_lib, sram_model, sram_orgz_type);
|
||||
if (0 < module_num_config_bits) {
|
||||
add_sram_ports_to_module_manager(module_manager, sb_module, circuit_lib, sram_model, sram_orgz_type, module_num_config_bits);
|
||||
add_pb_sram_ports_to_module_manager(module_manager, sb_module, circuit_lib, sram_model, sram_orgz_type, module_num_config_bits);
|
||||
}
|
||||
|
||||
/* Add all the nets to connect configuration ports from memory module to primitive modules
|
||||
* This is a one-shot addition that covers all the memory modules in this primitive module!
|
||||
*/
|
||||
if (0 < module_manager.configurable_children(sb_module).size()) {
|
||||
add_module_nets_memory_config_bus(module_manager, decoder_lib,
|
||||
add_pb_module_nets_memory_config_bus(module_manager, decoder_lib,
|
||||
sb_module,
|
||||
sram_orgz_type, circuit_lib.design_tech_type(sram_model));
|
||||
}
|
||||
|
@ -890,14 +890,14 @@ void build_connection_block_module(ModuleManager& module_manager,
|
|||
*/
|
||||
size_t module_num_config_bits = find_module_num_config_bits_from_child_modules(module_manager, cb_module, circuit_lib, sram_model, sram_orgz_type);
|
||||
if (0 < module_num_config_bits) {
|
||||
add_sram_ports_to_module_manager(module_manager, cb_module, circuit_lib, sram_model, sram_orgz_type, module_num_config_bits);
|
||||
add_pb_sram_ports_to_module_manager(module_manager, cb_module, circuit_lib, sram_model, sram_orgz_type, module_num_config_bits);
|
||||
}
|
||||
|
||||
/* Add all the nets to connect configuration ports from memory module to primitive modules
|
||||
* This is a one-shot addition that covers all the memory modules in this primitive module!
|
||||
*/
|
||||
if (0 < module_manager.configurable_children(cb_module).size()) {
|
||||
add_module_nets_memory_config_bus(module_manager, decoder_lib,
|
||||
add_pb_module_nets_memory_config_bus(module_manager, decoder_lib,
|
||||
cb_module,
|
||||
sram_orgz_type, circuit_lib.design_tech_type(sram_model));
|
||||
}
|
||||
|
|
|
@ -697,8 +697,7 @@ TopModuleNumConfigBits find_top_module_regional_num_config_bit(const ModuleManag
|
|||
circuit_lib, sram_model);
|
||||
std::map<int, size_t> num_wls_per_tile = compute_memory_bank_regional_wordline_numbers_per_tile(module_manager, top_module,
|
||||
config_region,
|
||||
circuit_lib, sram_model,
|
||||
num_bls_per_tile);
|
||||
circuit_lib, sram_model);
|
||||
for (const auto& kv : num_bls_per_tile) {
|
||||
num_config_bits[config_region].first += kv.second;
|
||||
}
|
||||
|
|
|
@ -290,8 +290,7 @@ void add_top_module_nets_cmos_ql_memory_bank_config_bus(ModuleManager& module_ma
|
|||
circuit_lib, sram_model);
|
||||
std::map<int, size_t> num_wls_per_tile = compute_memory_bank_regional_wordline_numbers_per_tile(module_manager, top_module,
|
||||
config_region,
|
||||
circuit_lib, sram_model,
|
||||
num_bls_per_tile);
|
||||
circuit_lib, sram_model);
|
||||
|
||||
std::map<int, size_t> bl_start_index_per_tile = compute_memory_bank_regional_blwl_start_index_per_tile(child_x_range, num_bls_per_tile);
|
||||
std::map<int, size_t> wl_start_index_per_tile = compute_memory_bank_regional_blwl_start_index_per_tile(child_y_range, num_wls_per_tile);
|
||||
|
@ -324,7 +323,6 @@ void add_top_module_nets_cmos_ql_memory_bank_config_bus(ModuleManager& module_ma
|
|||
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];
|
||||
int child_num_unique_blwls = num_bls_per_tile.at(coord.x());
|
||||
|
||||
size_t child_instance = module_manager.region_configurable_child_instances(top_module, config_region)[child_id];
|
||||
|
||||
|
@ -335,7 +333,7 @@ void add_top_module_nets_cmos_ql_memory_bank_config_bus(ModuleManager& module_ma
|
|||
size_t cur_bl_index = 0;
|
||||
|
||||
for (const size_t& sink_bl_pin : child_bl_port_info.pins()) {
|
||||
size_t bl_pin_id = bl_start_index_per_tile[coord.x()] + cur_bl_index % child_num_unique_blwls;
|
||||
size_t bl_pin_id = bl_start_index_per_tile[coord.x()] + cur_bl_index;
|
||||
/* Find the BL decoder data index:
|
||||
* It should be the starting index plus an offset which is the residual when divided by the number of BLs in this tile
|
||||
*/
|
||||
|
@ -365,7 +363,6 @@ void add_top_module_nets_cmos_ql_memory_bank_config_bus(ModuleManager& module_ma
|
|||
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];
|
||||
int child_num_unique_blwls = num_bls_per_tile.at(coord.x());
|
||||
|
||||
size_t child_instance = module_manager.region_configurable_child_instances(top_module, config_region)[child_id];
|
||||
|
||||
|
@ -376,7 +373,7 @@ void add_top_module_nets_cmos_ql_memory_bank_config_bus(ModuleManager& module_ma
|
|||
size_t cur_wl_index = 0;
|
||||
|
||||
for (const size_t& sink_wl_pin : child_wl_port_info.pins()) {
|
||||
size_t wl_pin_id = wl_start_index_per_tile[coord.y()] + std::floor(cur_wl_index / child_num_unique_blwls);
|
||||
size_t wl_pin_id = wl_start_index_per_tile[coord.y()] + cur_wl_index;
|
||||
VTR_ASSERT(wl_pin_id < wl_decoder_dout_port_info.pins().size());
|
||||
|
||||
/* Create net */
|
||||
|
|
|
@ -243,8 +243,7 @@ void build_module_fabric_dependent_bitstream_ql_memory_bank(const ConfigProtocol
|
|||
circuit_lib, config_protocol.memory_model());
|
||||
std::map<int, size_t> num_wls_per_tile = compute_memory_bank_regional_wordline_numbers_per_tile(module_manager, top_module,
|
||||
config_region,
|
||||
circuit_lib, config_protocol.memory_model(),
|
||||
num_bls_per_tile);
|
||||
circuit_lib, config_protocol.memory_model());
|
||||
|
||||
std::map<int, size_t> bl_start_index_per_tile = compute_memory_bank_regional_blwl_start_index_per_tile(child_x_range, num_bls_per_tile);
|
||||
std::map<int, size_t> wl_start_index_per_tile = compute_memory_bank_regional_blwl_start_index_per_tile(child_y_range, num_wls_per_tile);
|
||||
|
|
|
@ -56,6 +56,38 @@ std::pair<int, int> compute_memory_bank_regional_configurable_child_y_range(cons
|
|||
return child_y_range;
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
* Find the size of BL ports for module
|
||||
*******************************************************************/
|
||||
static
|
||||
size_t find_module_ql_memory_bank_num_blwls(const ModuleManager& module_manager,
|
||||
const ModuleId& module_id,
|
||||
const CircuitLibrary& circuit_lib,
|
||||
const CircuitModelId& sram_model,
|
||||
const e_config_protocol_type& sram_orgz_type,
|
||||
const e_circuit_model_port_type& circuit_port_type) {
|
||||
std::vector<std::string> config_port_names = generate_sram_port_names(circuit_lib, sram_model, sram_orgz_type);
|
||||
size_t num_blwls = 0; /* By default it has zero configuration bits*/
|
||||
|
||||
/* Try to find these ports in the module manager */
|
||||
for (const std::string& config_port_name : config_port_names) {
|
||||
ModulePortId module_port_id = module_manager.find_module_port(module_id, config_port_name);
|
||||
/* If the port does not exist, go to the next */
|
||||
if (false == module_manager.valid_module_port_id(module_id, module_port_id)) {
|
||||
continue;
|
||||
}
|
||||
/* We only care about a give type of ports */
|
||||
if (circuit_port_type != circuit_lib.port_type(circuit_lib.model_port(sram_model, config_port_name))) {
|
||||
continue;
|
||||
}
|
||||
/* The port exist, find the port size and update the num_config_bits if the size is larger */
|
||||
BasicPort module_port = module_manager.module_port(module_id, module_port_id);
|
||||
num_blwls = std::max((int)num_blwls, (int)module_port.get_width());
|
||||
}
|
||||
|
||||
return num_blwls;
|
||||
}
|
||||
|
||||
std::map<int, size_t> compute_memory_bank_regional_bitline_numbers_per_tile(const ModuleManager& module_manager,
|
||||
const ModuleId& top_module,
|
||||
const ConfigRegionId& config_region,
|
||||
|
@ -66,7 +98,7 @@ std::map<int, size_t> compute_memory_bank_regional_bitline_numbers_per_tile(cons
|
|||
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_per_tile[coord.x()] = std::max(num_bls_per_tile[coord.x()], find_memory_decoder_data_size(find_module_num_config_bits(module_manager, child_module, circuit_lib, sram_model, CONFIG_MEM_QL_MEMORY_BANK)));
|
||||
num_bls_per_tile[coord.x()] = std::max(num_bls_per_tile[coord.x()], find_module_ql_memory_bank_num_blwls(module_manager, child_module, circuit_lib, sram_model, CONFIG_MEM_QL_MEMORY_BANK, CIRCUIT_MODEL_PORT_BL));
|
||||
}
|
||||
|
||||
return num_bls_per_tile;
|
||||
|
@ -76,14 +108,13 @@ std::map<int, size_t> compute_memory_bank_regional_wordline_numbers_per_tile(con
|
|||
const ModuleId& top_module,
|
||||
const ConfigRegionId& config_region,
|
||||
const CircuitLibrary& circuit_lib,
|
||||
const CircuitModelId& sram_model,
|
||||
const std::map<int, size_t>& num_bls_per_tile) {
|
||||
const CircuitModelId& sram_model) {
|
||||
std::map<int, size_t> num_wls_per_tile;
|
||||
|
||||
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_wls_per_tile[coord.y()] = std::max(num_wls_per_tile[coord.y()], find_memory_wl_decoder_data_size(find_module_num_config_bits(module_manager, child_module, circuit_lib, sram_model, CONFIG_MEM_QL_MEMORY_BANK), num_bls_per_tile.at(coord.x())));
|
||||
num_wls_per_tile[coord.y()] = std::max(num_wls_per_tile[coord.y()], find_module_ql_memory_bank_num_blwls(module_manager, child_module, circuit_lib, sram_model, CONFIG_MEM_QL_MEMORY_BANK, CIRCUIT_MODEL_PORT_WL));
|
||||
}
|
||||
|
||||
return num_wls_per_tile;
|
||||
|
|
|
@ -66,8 +66,7 @@ std::map<int, size_t> compute_memory_bank_regional_wordline_numbers_per_tile(con
|
|||
const ModuleId& top_module,
|
||||
const ConfigRegionId& config_region,
|
||||
const CircuitLibrary& circuit_lib,
|
||||
const CircuitModelId& sram_model,
|
||||
const std::map<int, size_t>& num_bls_per_tile);
|
||||
const CircuitModelId& sram_model);
|
||||
|
||||
/**
|
||||
* @brief Precompute the BLs and WLs distribution across the FPGA fabric
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include "vtr_log.h"
|
||||
|
||||
#include "openfpga_naming.h"
|
||||
#include "decoder_library_utils.h"
|
||||
#include "memory_utils.h"
|
||||
|
||||
/* begin namespace openfpga */
|
||||
|
@ -393,4 +394,39 @@ size_t generate_sram_port_size(const e_config_protocol_type sram_orgz_type,
|
|||
return sram_port_size;
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
* @brief Generate a list of ports that are used for SRAM configuration to a module
|
||||
* - Standalone SRAMs: use the suggested port_size
|
||||
* - Scan-chain Flip-flops: the port size will be forced to 1 in this case
|
||||
* - Memory decoders: use the suggested port_size
|
||||
* - QL Memory decoders: Apply square root as BL/WLs will be grouped
|
||||
********************************************************************/
|
||||
size_t generate_pb_sram_port_size(const e_config_protocol_type sram_orgz_type,
|
||||
const size_t& num_config_bits) {
|
||||
size_t sram_port_size = num_config_bits;
|
||||
|
||||
switch (sram_orgz_type) {
|
||||
case CONFIG_MEM_STANDALONE:
|
||||
break;
|
||||
case CONFIG_MEM_SCAN_CHAIN:
|
||||
/* CCFF head/tail are single-bit ports */
|
||||
sram_port_size = 1;
|
||||
break;
|
||||
case CONFIG_MEM_QL_MEMORY_BANK:
|
||||
sram_port_size = find_memory_decoder_data_size(num_config_bits);
|
||||
break;
|
||||
case CONFIG_MEM_MEMORY_BANK:
|
||||
break;
|
||||
case CONFIG_MEM_FRAME_BASED:
|
||||
break;
|
||||
default:
|
||||
VTR_LOGF_ERROR(__FILE__, __LINE__,
|
||||
"Invalid type of SRAM organization!\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
return sram_port_size;
|
||||
}
|
||||
|
||||
|
||||
} /* end namespace openfpga */
|
||||
|
|
|
@ -37,6 +37,9 @@ std::vector<std::string> generate_sram_port_names(const CircuitLibrary& circuit_
|
|||
size_t generate_sram_port_size(const e_config_protocol_type sram_orgz_type,
|
||||
const size_t& num_config_bits);
|
||||
|
||||
size_t generate_pb_sram_port_size(const e_config_protocol_type sram_orgz_type,
|
||||
const size_t& num_config_bits);
|
||||
|
||||
} /* end namespace openfpga */
|
||||
|
||||
#endif
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
******************************************************************************/
|
||||
|
||||
#include <map>
|
||||
#include <cmath>
|
||||
#include <algorithm>
|
||||
|
||||
/* Headers from vtrutil library */
|
||||
|
@ -276,7 +277,6 @@ void add_formal_verification_sram_ports_to_module_manager(ModuleManager& module_
|
|||
module_manager.set_port_preproc_flag(module_id, port_id, preproc_flag);
|
||||
}
|
||||
|
||||
|
||||
/********************************************************************
|
||||
* Add a list of ports that are used for SRAM configuration to a module
|
||||
* in the module manager
|
||||
|
@ -361,6 +361,90 @@ void add_sram_ports_to_module_manager(ModuleManager& module_manager,
|
|||
}
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
* @brief Add a list of ports that are used for SRAM configuration to module
|
||||
* in the module manager
|
||||
* @note
|
||||
* This function is only applicable to programmable blocks, which are
|
||||
* - Grid
|
||||
* - CBX/CBY
|
||||
* - SB
|
||||
* @note
|
||||
* The major difference between this function and the add_sram_ports_to_module_manager()
|
||||
* is the size of sram ports to be added when QL memory bank is selected
|
||||
* This function will merge/group BL/WLs by considering a memory bank organization
|
||||
* at block-level
|
||||
********************************************************************/
|
||||
void add_pb_sram_ports_to_module_manager(ModuleManager& module_manager,
|
||||
const ModuleId& module_id,
|
||||
const CircuitLibrary& circuit_lib,
|
||||
const CircuitModelId& sram_model,
|
||||
const e_config_protocol_type sram_orgz_type,
|
||||
const size_t& num_config_bits) {
|
||||
std::vector<std::string> sram_port_names = generate_sram_port_names(circuit_lib, sram_model, sram_orgz_type);
|
||||
size_t sram_port_size = generate_pb_sram_port_size(sram_orgz_type, num_config_bits);
|
||||
|
||||
/* Add ports to the module manager */
|
||||
switch (sram_orgz_type) {
|
||||
case CONFIG_MEM_STANDALONE:
|
||||
case CONFIG_MEM_QL_MEMORY_BANK:
|
||||
for (const std::string& sram_port_name : sram_port_names) {
|
||||
/* Add generated ports to the ModuleManager */
|
||||
BasicPort sram_port(sram_port_name, sram_port_size);
|
||||
/* For WL ports, we need to fine-tune it */
|
||||
if (CIRCUIT_MODEL_PORT_WL == circuit_lib.port_type(circuit_lib.model_port(sram_model, sram_port_name))) {
|
||||
sram_port.set_width(find_memory_wl_decoder_data_size(num_config_bits, sram_port_size));
|
||||
}
|
||||
module_manager.add_port(module_id, sram_port, ModuleManager::MODULE_INPUT_PORT);
|
||||
}
|
||||
break;
|
||||
case CONFIG_MEM_MEMORY_BANK: {
|
||||
for (const std::string& sram_port_name : sram_port_names) {
|
||||
/* Add generated ports to the ModuleManager */
|
||||
BasicPort sram_port(sram_port_name, sram_port_size);
|
||||
module_manager.add_port(module_id, sram_port, ModuleManager::MODULE_INPUT_PORT);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CONFIG_MEM_SCAN_CHAIN: {
|
||||
/* Note that configuration chain tail is an output while head is an input
|
||||
* IMPORTANT: this is co-designed with function generate_sram_port_names()
|
||||
* If the return vector is changed, the following codes MUST be adapted!
|
||||
*/
|
||||
VTR_ASSERT(2 == sram_port_names.size());
|
||||
size_t port_counter = 0;
|
||||
for (const std::string& sram_port_name : sram_port_names) {
|
||||
/* Add generated ports to the ModuleManager */
|
||||
BasicPort sram_port(sram_port_name, sram_port_size);
|
||||
if (0 == port_counter) {
|
||||
module_manager.add_port(module_id, sram_port, ModuleManager::MODULE_INPUT_PORT);
|
||||
} else {
|
||||
VTR_ASSERT(1 == port_counter);
|
||||
module_manager.add_port(module_id, sram_port, ModuleManager::MODULE_OUTPUT_PORT);
|
||||
}
|
||||
port_counter++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CONFIG_MEM_FRAME_BASED: {
|
||||
BasicPort en_port(std::string(DECODER_ENABLE_PORT_NAME), 1);
|
||||
module_manager.add_port(module_id, en_port, ModuleManager::MODULE_INPUT_PORT);
|
||||
|
||||
BasicPort addr_port(std::string(DECODER_ADDRESS_PORT_NAME), num_config_bits);
|
||||
module_manager.add_port(module_id, addr_port, ModuleManager::MODULE_INPUT_PORT);
|
||||
|
||||
BasicPort din_port(std::string(DECODER_DATA_IN_PORT_NAME), 1);
|
||||
module_manager.add_port(module_id, din_port, ModuleManager::MODULE_INPUT_PORT);
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
VTR_LOGF_ERROR(__FILE__, __LINE__,
|
||||
"Invalid type of SRAM organization !\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
* Add ports of a pb_type block to module manager
|
||||
* Port addition will follow the sequence: inout, input, output, clock
|
||||
|
@ -863,6 +947,158 @@ void add_module_nets_cmos_flatten_memory_config_bus(ModuleManager& module_manage
|
|||
VTR_ASSERT(net_src_port.get_width() == cur_src_pin_id);
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
* @brief Connect all the Bit Lines (BL) of child memory modules under the
|
||||
* parent module in a memory bank organization
|
||||
*
|
||||
* BL<0> BL<1> BL<i>
|
||||
* | | |
|
||||
* v v v
|
||||
* +--------+ +--------+ +--------+
|
||||
* | Memory | | Memory | ... | Memory |
|
||||
* | Module | | Module | | Module |
|
||||
* | [0,0] | | [1,0] | | [i,0] |
|
||||
* +--------+ +--------+ +--------+
|
||||
* | | |
|
||||
* v v v
|
||||
* +--------+ +--------+ +--------+
|
||||
* | Memory | | Memory | ... | Memory |
|
||||
* | Module | | Module | | Module |
|
||||
* | [0,1] | | [1,1] | | [i,1] |
|
||||
* +--------+ +--------+ +--------+
|
||||
*
|
||||
*********************************************************************/
|
||||
void add_module_nets_cmos_memory_bank_bl_config_bus(ModuleManager& module_manager,
|
||||
const ModuleId& parent_module,
|
||||
const e_config_protocol_type& sram_orgz_type,
|
||||
const e_circuit_model_port_type& config_port_type) {
|
||||
/* A counter for the current pin id for the source port of parent module */
|
||||
size_t cur_src_pin_id = 0;
|
||||
|
||||
ModuleId net_src_module_id;
|
||||
size_t net_src_instance_id;
|
||||
ModulePortId net_src_port_id;
|
||||
|
||||
/* Find the port name of parent module */
|
||||
std::string src_port_name = generate_sram_port_name(sram_orgz_type, config_port_type);
|
||||
net_src_module_id = parent_module;
|
||||
net_src_instance_id = 0;
|
||||
net_src_port_id = module_manager.find_module_port(net_src_module_id, src_port_name);
|
||||
|
||||
/* Get the pin id for source port */
|
||||
BasicPort net_src_port = module_manager.module_port(net_src_module_id, net_src_port_id);
|
||||
|
||||
for (size_t mem_index = 0; mem_index < module_manager.configurable_children(parent_module).size(); ++mem_index) {
|
||||
ModuleId net_sink_module_id;
|
||||
size_t net_sink_instance_id;
|
||||
ModulePortId net_sink_port_id;
|
||||
|
||||
/* Find the port name of next memory module */
|
||||
std::string sink_port_name = generate_sram_port_name(sram_orgz_type, config_port_type);
|
||||
net_sink_module_id = module_manager.configurable_children(parent_module)[mem_index];
|
||||
net_sink_instance_id = module_manager.configurable_child_instances(parent_module)[mem_index];
|
||||
net_sink_port_id = module_manager.find_module_port(net_sink_module_id, sink_port_name);
|
||||
|
||||
/* Get the pin id for sink port */
|
||||
BasicPort net_sink_port = module_manager.module_port(net_sink_module_id, net_sink_port_id);
|
||||
|
||||
/* Create a net for each pin */
|
||||
for (size_t pin_id = 0; pin_id < net_sink_port.pins().size(); ++pin_id) {
|
||||
size_t cur_bl_src_pin_id = cur_src_pin_id % net_src_port.pins().size();
|
||||
/* Create a net and add source and sink to it */
|
||||
ModuleNetId net = create_module_source_pin_net(module_manager, parent_module,
|
||||
net_src_module_id, net_src_instance_id,
|
||||
net_src_port_id, net_src_port.pins()[cur_bl_src_pin_id]);
|
||||
VTR_ASSERT(ModuleNetId::INVALID() != net);
|
||||
|
||||
/* Add net sink */
|
||||
module_manager.add_module_net_sink(parent_module, net, net_sink_module_id, net_sink_instance_id, net_sink_port_id, net_sink_port.pins()[pin_id]);
|
||||
|
||||
/* Move to the next src pin */
|
||||
cur_src_pin_id++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
* @brief Connect all the Word Lines (WL) of child memory modules under the
|
||||
* parent module in a memory bank organization
|
||||
*
|
||||
* +--------+ +--------+ +--------+
|
||||
* | Memory | | Memory | ... | Memory |
|
||||
* | Module | | Module | | Module |
|
||||
* | [0,0] | | [1,0] | | [i,0] |
|
||||
* +--------+ +--------+ +--------+
|
||||
* ^ ^ ^
|
||||
* | | |
|
||||
* +------------+----------------------+
|
||||
* |
|
||||
* WL<0>
|
||||
*
|
||||
* +--------+ +--------+ +--------+
|
||||
* | Memory | | Memory | ... | Memory |
|
||||
* | Module | | Module | | Module |
|
||||
* | [0,1] | | [1,1] | | [i,1] |
|
||||
* +--------+ +--------+ +--------+
|
||||
* ^ ^ ^
|
||||
* | | |
|
||||
* +------------+----------------------+
|
||||
* |
|
||||
* WL<1>
|
||||
*
|
||||
*********************************************************************/
|
||||
void add_module_nets_cmos_memory_bank_wl_config_bus(ModuleManager& module_manager,
|
||||
const ModuleId& parent_module,
|
||||
const e_config_protocol_type& sram_orgz_type,
|
||||
const e_circuit_model_port_type& config_port_type) {
|
||||
/* A counter for the current pin id for the source port of parent module */
|
||||
size_t cur_src_pin_id = 0;
|
||||
|
||||
ModuleId net_src_module_id;
|
||||
size_t net_src_instance_id;
|
||||
ModulePortId net_src_port_id;
|
||||
|
||||
/* Find the port name of parent module */
|
||||
std::string src_port_name = generate_sram_port_name(sram_orgz_type, config_port_type);
|
||||
net_src_module_id = parent_module;
|
||||
net_src_instance_id = 0;
|
||||
net_src_port_id = module_manager.find_module_port(net_src_module_id, src_port_name);
|
||||
|
||||
/* Get the pin id for source port */
|
||||
BasicPort net_src_port = module_manager.module_port(net_src_module_id, net_src_port_id);
|
||||
|
||||
for (size_t mem_index = 0; mem_index < module_manager.configurable_children(parent_module).size(); ++mem_index) {
|
||||
ModuleId net_sink_module_id;
|
||||
size_t net_sink_instance_id;
|
||||
ModulePortId net_sink_port_id;
|
||||
|
||||
/* Find the port name of next memory module */
|
||||
std::string sink_port_name = generate_sram_port_name(sram_orgz_type, config_port_type);
|
||||
net_sink_module_id = module_manager.configurable_children(parent_module)[mem_index];
|
||||
net_sink_instance_id = module_manager.configurable_child_instances(parent_module)[mem_index];
|
||||
net_sink_port_id = module_manager.find_module_port(net_sink_module_id, sink_port_name);
|
||||
|
||||
/* Get the pin id for sink port */
|
||||
BasicPort net_sink_port = module_manager.module_port(net_sink_module_id, net_sink_port_id);
|
||||
|
||||
/* Create a net for each pin */
|
||||
for (size_t pin_id = 0; pin_id < net_sink_port.pins().size(); ++pin_id) {
|
||||
size_t cur_wl_src_pin_id = std::floor(cur_src_pin_id / net_src_port.pins().size());
|
||||
/* Create a net and add source and sink to it */
|
||||
ModuleNetId net = create_module_source_pin_net(module_manager, parent_module,
|
||||
net_src_module_id, net_src_instance_id,
|
||||
net_src_port_id, net_src_port.pins()[cur_wl_src_pin_id]);
|
||||
VTR_ASSERT(ModuleNetId::INVALID() != net);
|
||||
|
||||
/* Add net sink */
|
||||
module_manager.add_module_net_sink(parent_module, net, net_sink_module_id, net_sink_instance_id, net_sink_port_id, net_sink_port.pins()[pin_id]);
|
||||
|
||||
/* Move to the next src pin */
|
||||
cur_src_pin_id++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
* Connect all the memory modules under the parent module in a chain
|
||||
*
|
||||
|
@ -1306,6 +1542,73 @@ void add_module_nets_cmos_memory_config_bus(ModuleManager& module_manager,
|
|||
}
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @brief Add the port-to-port connection between all the memory modules
|
||||
* and their parent module. This function creates nets to wire the control
|
||||
* signals of memory module to the configuration ports of primitive module
|
||||
*
|
||||
* @note This function is only applicable to programmable blocks, which are
|
||||
* grid, CBX/CBY, SB. Different from the add_pb_module_nets_cmos_memory_config_bus(),
|
||||
* this function will merge BL/WLs of child module when connect them to the parent module
|
||||
*
|
||||
* QL Memory bank
|
||||
* --------------
|
||||
*
|
||||
* config_bus (BL) config_bus (WL)
|
||||
* | |
|
||||
* parent | |
|
||||
* +---------------------------------------------+
|
||||
* | | | |
|
||||
* | +---------------+ | |
|
||||
* | | | | |
|
||||
* | | +-----------|---+ |
|
||||
* | | | | | |
|
||||
* | v v v v |
|
||||
* | +-------------------------------------+ |
|
||||
* | | Child Mem 0 | ... | Child Mem N-1 | |
|
||||
* | +-------------------------------------+ |
|
||||
* | | | |
|
||||
* | v v |
|
||||
* | sram_out sram_outb |
|
||||
* | |
|
||||
* +---------------------------------------------+
|
||||
|
||||
*
|
||||
**********************************************************************/
|
||||
static
|
||||
void add_pb_module_nets_cmos_memory_config_bus(ModuleManager& module_manager,
|
||||
DecoderLibrary& decoder_lib,
|
||||
const ModuleId& parent_module,
|
||||
const e_config_protocol_type& sram_orgz_type) {
|
||||
switch (sram_orgz_type) {
|
||||
case CONFIG_MEM_SCAN_CHAIN: {
|
||||
add_module_nets_cmos_memory_chain_config_bus(module_manager, parent_module,
|
||||
sram_orgz_type);
|
||||
break;
|
||||
}
|
||||
case CONFIG_MEM_STANDALONE:
|
||||
case CONFIG_MEM_QL_MEMORY_BANK:
|
||||
add_module_nets_cmos_memory_bank_bl_config_bus(module_manager, parent_module,
|
||||
sram_orgz_type, CIRCUIT_MODEL_PORT_BL);
|
||||
add_module_nets_cmos_memory_bank_wl_config_bus(module_manager, parent_module,
|
||||
sram_orgz_type, CIRCUIT_MODEL_PORT_WL);
|
||||
break;
|
||||
case CONFIG_MEM_MEMORY_BANK:
|
||||
add_module_nets_cmos_flatten_memory_config_bus(module_manager, parent_module,
|
||||
sram_orgz_type, CIRCUIT_MODEL_PORT_BL);
|
||||
add_module_nets_cmos_flatten_memory_config_bus(module_manager, parent_module,
|
||||
sram_orgz_type, CIRCUIT_MODEL_PORT_WL);
|
||||
break;
|
||||
case CONFIG_MEM_FRAME_BASED:
|
||||
add_module_nets_cmos_memory_frame_config_bus(module_manager, decoder_lib, parent_module);
|
||||
break;
|
||||
default:
|
||||
VTR_LOGF_ERROR(__FILE__, __LINE__,
|
||||
"Invalid type of SRAM organization!\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* TODO:
|
||||
* Add the port-to-port connection between a logic module
|
||||
|
@ -1331,7 +1634,6 @@ void add_module_nets_cmos_memory_config_bus(ModuleManager& module_manager,
|
|||
**********************************************************************/
|
||||
|
||||
/********************************************************************
|
||||
* TODO:
|
||||
* Add the port-to-port connection between a memory module
|
||||
* and the configuration bus of a primitive module
|
||||
*
|
||||
|
@ -1382,6 +1684,40 @@ void add_module_nets_memory_config_bus(ModuleManager& module_manager,
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/********************************************************************
|
||||
* Add the port-to-port connection between the configuration lines of
|
||||
* a programmable block module (grid, CBX/CBY, SB) and its child module
|
||||
*
|
||||
* The configuration bus connection will depend not only
|
||||
* the design technology of the memory cells but also the
|
||||
* configuration styles of FPGA fabric.
|
||||
* Here we will branch on the design technology
|
||||
*
|
||||
* Note: this function SHOULD be called after the pb_type_module is created
|
||||
* and its child module (logic_module and memory_module) is created!
|
||||
*******************************************************************/
|
||||
void add_pb_module_nets_memory_config_bus(ModuleManager& module_manager,
|
||||
DecoderLibrary& decoder_lib,
|
||||
const ModuleId& parent_module,
|
||||
const e_config_protocol_type& sram_orgz_type,
|
||||
const e_circuit_model_design_tech& mem_tech) {
|
||||
switch (mem_tech) {
|
||||
case CIRCUIT_MODEL_DESIGN_CMOS:
|
||||
add_pb_module_nets_cmos_memory_config_bus(module_manager, decoder_lib,
|
||||
parent_module,
|
||||
sram_orgz_type);
|
||||
break;
|
||||
case CIRCUIT_MODEL_DESIGN_RRAM:
|
||||
/* TODO: */
|
||||
break;
|
||||
default:
|
||||
VTR_LOGF_ERROR(__FILE__, __LINE__,
|
||||
"Invalid type of memory design technology!\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
* Find the size of shared(reserved) configuration ports for module
|
||||
*******************************************************************/
|
||||
|
|
|
@ -69,6 +69,13 @@ void add_sram_ports_to_module_manager(ModuleManager& module_manager,
|
|||
const e_config_protocol_type sram_orgz_type,
|
||||
const size_t& num_config_bits);
|
||||
|
||||
void add_pb_sram_ports_to_module_manager(ModuleManager& module_manager,
|
||||
const ModuleId& module_id,
|
||||
const CircuitLibrary& circuit_lib,
|
||||
const CircuitModelId& sram_model,
|
||||
const e_config_protocol_type sram_orgz_type,
|
||||
const size_t& num_config_bits);
|
||||
|
||||
void add_primitive_pb_type_ports_to_module_manager(ModuleManager& module_manager,
|
||||
const ModuleId& module_id,
|
||||
t_pb_type* cur_pb_type,
|
||||
|
@ -109,6 +116,16 @@ void add_module_nets_cmos_flatten_memory_config_bus(ModuleManager& module_manage
|
|||
const e_config_protocol_type& sram_orgz_type,
|
||||
const e_circuit_model_port_type& config_port_type);
|
||||
|
||||
void add_module_nets_cmos_memory_bank_bl_config_bus(ModuleManager& module_manager,
|
||||
const ModuleId& parent_module,
|
||||
const e_config_protocol_type& sram_orgz_type,
|
||||
const e_circuit_model_port_type& config_port_type);
|
||||
|
||||
void add_module_nets_cmos_memory_bank_wl_config_bus(ModuleManager& module_manager,
|
||||
const ModuleId& parent_module,
|
||||
const e_config_protocol_type& sram_orgz_type,
|
||||
const e_circuit_model_port_type& config_port_type);
|
||||
|
||||
void add_module_nets_cmos_memory_chain_config_bus(ModuleManager& module_manager,
|
||||
const ModuleId& parent_module,
|
||||
const e_config_protocol_type& sram_orgz_type);
|
||||
|
@ -123,6 +140,12 @@ void add_module_nets_memory_config_bus(ModuleManager& module_manager,
|
|||
const e_config_protocol_type& sram_orgz_type,
|
||||
const e_circuit_model_design_tech& mem_tech);
|
||||
|
||||
void add_pb_module_nets_memory_config_bus(ModuleManager& module_manager,
|
||||
DecoderLibrary& decoder_lib,
|
||||
const ModuleId& parent_module,
|
||||
const e_config_protocol_type& sram_orgz_type,
|
||||
const e_circuit_model_design_tech& mem_tech);
|
||||
|
||||
size_t find_module_num_shared_config_bits(const ModuleManager& module_manager,
|
||||
const ModuleId& module_id);
|
||||
|
||||
|
|
Loading…
Reference in New Issue