add configuration protocol ports to top module for memory bank organization

This commit is contained in:
tangxifan 2020-05-30 15:49:15 -06:00
parent c00653961e
commit fa8dfc1fbd
7 changed files with 154 additions and 2 deletions

View File

@ -38,6 +38,8 @@ constexpr char* DECODER_ADDRESS_PORT_NAME = "address";
constexpr char* DECODER_DATA_IN_PORT_NAME = "data_in";
constexpr char* DECODER_DATA_OUT_PORT_NAME = "data_out";
constexpr char* DECODER_DATA_OUT_INV_PORT_NAME = "data_out_inv";
constexpr char* DECODER_BL_ADDRESS_PORT_NAME = "bl_address";
constexpr char* DECODER_WL_ADDRESS_PORT_NAME = "wl_address";
/* Inverted port naming */
constexpr char* INV_PORT_POSTFIX = "_inv";

View File

@ -384,7 +384,9 @@ void build_top_module(ModuleManager& module_manager,
*/
size_t module_num_config_bits = find_module_num_config_bits_from_child_modules(module_manager, top_module, circuit_lib, sram_model, sram_orgz_type);
if (0 < module_num_config_bits) {
add_sram_ports_to_module_manager(module_manager, top_module, circuit_lib, sram_model, sram_orgz_type, module_num_config_bits);
add_top_module_sram_ports(module_manager, top_module,
circuit_lib, sram_model,
sram_orgz_type, module_num_config_bits);
}
/* Add module nets to connect memory cells inside

View File

@ -13,6 +13,8 @@
#include "openfpga_reserved_words.h"
#include "openfpga_naming.h"
#include "memory_utils.h"
#include "decoder_library_utils.h"
#include "module_manager_utils.h"
#include "build_top_module_memory.h"
@ -361,6 +363,104 @@ void organize_top_module_memory_modules(ModuleManager& module_manager,
}
}
/********************************************************************
* Add a list of ports that are used for SRAM configuration to the FPGA
* 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)
********************************************************************/
void add_top_module_sram_ports(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_sram_port_size(sram_orgz_type, num_config_bits);
/* Add ports to the module manager */
switch (sram_orgz_type) {
case CONFIG_MEM_STANDALONE: {
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_MEMORY_BANK: {
BasicPort en_port(std::string(DECODER_ENABLE_PORT_NAME), 1);
module_manager.add_port(module_id, en_port, ModuleManager::MODULE_INPUT_PORT);
size_t bl_addr_size = find_memory_decoder_addr_size(num_config_bits);
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);
size_t wl_addr_size = find_memory_decoder_addr_size(num_config_bits);
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);
BasicPort din_port(std::string(DECODER_DATA_IN_PORT_NAME), 1);
module_manager.add_port(module_id, din_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 the port-to-port connection between all the memory modules

View File

@ -34,6 +34,13 @@ void organize_top_module_memory_modules(ModuleManager& module_manager,
const std::map<t_rr_type, vtr::Matrix<size_t>>& cb_instance_ids,
const bool& compact_routing_hierarchy);
void add_top_module_sram_ports(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_top_module_nets_memory_config_bus(ModuleManager& module_manager,
DecoderLibrary& decoder_lib,
const ModuleId& parent_module,

View File

@ -38,6 +38,45 @@ size_t find_mux_local_decoder_addr_size(const size_t& data_size) {
return ceil(log(data_size) / log(2));
}
/***************************************************************************************
* Find the size of address lines for a memory decoder to access a memory array
* Addr lines
* | | ... |
* v v v
* +-----------+
* / Local \
* / Decoder \
* +-----------------+
* | | | ... | | |
* v v v v v v
* Data outputs
*
* +------+ +------+ +------+
* | SRAM | | SRAM | ... | SRAM |
* | [0] | | [1] | | [i] |
* +------+ +------+ +------+
*
* +------+ +------+ +------+
* | SRAM | | SRAM | ... | SRAM |
* | [i+1]| | [i+2]| |[2i-1]|
* +------+ +------+ +------+
*
* ... ... ...
*
* +------+ +------+ +------+
* | SRAM | | SRAM | ... | SRAM |
* | [x] | | [x+1]| | [N] |
* +------+ +------+ +------+
*
* Due to the shared lines in the array,
* each memory decoder (BL or WL) will access sqrt(N) control lins (BL or WL)
* Then we can use the function for mux local encoder to compute the address size
*
***************************************************************************************/
size_t find_memory_decoder_addr_size(const size_t& num_mems) {
return find_mux_local_decoder_addr_size((size_t)std::ceil(std::sqrt((float)num_mems)));
}
/***************************************************************************************
* Try to find if the decoder already exists in the library,
* If there is no such decoder, add it to the library

View File

@ -13,6 +13,8 @@ bool need_mux_local_decoder(const size_t& data_size);
size_t find_mux_local_decoder_addr_size(const size_t& data_size);
size_t find_memory_decoder_addr_size(const size_t& num_mems);
DecoderId add_mux_local_decoder_to_library(DecoderLibrary& decoder_lib,
const size_t data_size);

View File

@ -163,7 +163,7 @@ void add_formal_verification_sram_ports_to_module_manager(ModuleManager& 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 regular output and inverted output
* 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