add configuration protocol ports to top module for memory bank organization
This commit is contained in:
parent
c00653961e
commit
fa8dfc1fbd
|
@ -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";
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue