[Engine] Merge BL/WLs in the Grid/CB/SB modules

This commit is contained in:
tangxifan 2021-09-15 11:27:55 -07:00
parent 4af6413c97
commit 26b1e48723
11 changed files with 452 additions and 29 deletions

View File

@ -1114,15 +1114,15 @@ 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,
sram_orgz_type, circuit_lib.design_tech_type(sram_model));
add_pb_module_nets_memory_config_bus(module_manager, decoder_lib, grid_module,
sram_orgz_type, circuit_lib.design_tech_type(sram_model));
}
VTR_LOGV(verbose, "Done\n");

View File

@ -462,16 +462,16 @@ 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,
sb_module,
sram_orgz_type, circuit_lib.design_tech_type(sram_model));
add_pb_module_nets_memory_config_bus(module_manager, decoder_lib,
sb_module,
sram_orgz_type, circuit_lib.design_tech_type(sram_model));
}
VTR_LOGV(verbose, "Done\n");
@ -890,16 +890,16 @@ 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,
cb_module,
sram_orgz_type, circuit_lib.design_tech_type(sram_model));
add_pb_module_nets_memory_config_bus(module_manager, decoder_lib,
cb_module,
sram_orgz_type, circuit_lib.design_tech_type(sram_model));
}
VTR_LOGV(verbose, "Done\n");

View File

@ -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;
}

View File

@ -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 */

View File

@ -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);

View File

@ -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;

View File

@ -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

View File

@ -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 */

View File

@ -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

View File

@ -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
*******************************************************************/

View File

@ -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);