add configuration bus nets for memory bank decoders at top module
This commit is contained in:
parent
fa8dfc1fbd
commit
0e16ee1030
|
@ -156,6 +156,34 @@ std::string generate_frame_memory_decoder_subckt_name(const size_t& addr_size,
|
||||||
return subckt_name;
|
return subckt_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/************************************************
|
||||||
|
* Generate the module name of a bit-line decoder
|
||||||
|
* for memories
|
||||||
|
***********************************************/
|
||||||
|
std::string generate_bl_memory_decoder_subckt_name(const size_t& addr_size,
|
||||||
|
const size_t& data_size) {
|
||||||
|
std::string subckt_name = "bl_decoder";
|
||||||
|
subckt_name += std::to_string(addr_size);
|
||||||
|
subckt_name += "to";
|
||||||
|
subckt_name += std::to_string(data_size);
|
||||||
|
|
||||||
|
return subckt_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************
|
||||||
|
* Generate the module name of a word-line decoder
|
||||||
|
* for memories
|
||||||
|
***********************************************/
|
||||||
|
std::string generate_wl_memory_decoder_subckt_name(const size_t& addr_size,
|
||||||
|
const size_t& data_size) {
|
||||||
|
std::string subckt_name = "wl_decoder";
|
||||||
|
subckt_name += std::to_string(addr_size);
|
||||||
|
subckt_name += "to";
|
||||||
|
subckt_name += std::to_string(data_size);
|
||||||
|
|
||||||
|
return subckt_name;
|
||||||
|
}
|
||||||
|
|
||||||
/************************************************
|
/************************************************
|
||||||
* Generate the module name of a routing track wire
|
* Generate the module name of a routing track wire
|
||||||
***********************************************/
|
***********************************************/
|
||||||
|
|
|
@ -53,6 +53,12 @@ std::string generate_mux_local_decoder_subckt_name(const size_t& addr_size,
|
||||||
std::string generate_frame_memory_decoder_subckt_name(const size_t& addr_size,
|
std::string generate_frame_memory_decoder_subckt_name(const size_t& addr_size,
|
||||||
const size_t& data_size);
|
const size_t& data_size);
|
||||||
|
|
||||||
|
std::string generate_bl_memory_decoder_subckt_name(const size_t& addr_size,
|
||||||
|
const size_t& data_size);
|
||||||
|
|
||||||
|
std::string generate_wl_memory_decoder_subckt_name(const size_t& addr_size,
|
||||||
|
const size_t& data_size);
|
||||||
|
|
||||||
std::string generate_segment_wire_subckt_name(const std::string& wire_model_name,
|
std::string generate_segment_wire_subckt_name(const std::string& wire_model_name,
|
||||||
const size_t& segment_id);
|
const size_t& segment_id);
|
||||||
|
|
||||||
|
|
|
@ -74,6 +74,119 @@ ModuleId build_frame_memory_decoder_module(ModuleManager& module_manager,
|
||||||
return module_id;
|
return module_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/***************************************************************************************
|
||||||
|
* Create a module for a BL decoder with a given output size
|
||||||
|
*
|
||||||
|
* BL Address
|
||||||
|
* | | ... |
|
||||||
|
* v v v
|
||||||
|
* +-----------+
|
||||||
|
* / \<-- data_in
|
||||||
|
* enable-->/ Decoder \
|
||||||
|
* +-----------------+
|
||||||
|
* | | | ... | | |
|
||||||
|
* v v v v v v
|
||||||
|
* Data Outputs
|
||||||
|
*
|
||||||
|
* The outputs are assumes to be one-hot codes (at most only one '1' exist)
|
||||||
|
* Considering this fact, there are only num_of_outputs conditions to be encoded.
|
||||||
|
* Therefore, the number of inputs is ceil(log(num_of_outputs)/log(2))
|
||||||
|
***************************************************************************************/
|
||||||
|
ModuleId build_bl_memory_decoder_module(ModuleManager& module_manager,
|
||||||
|
const DecoderLibrary& decoder_lib,
|
||||||
|
const DecoderId& decoder) {
|
||||||
|
/* Get the number of inputs */
|
||||||
|
size_t addr_size = decoder_lib.addr_size(decoder);
|
||||||
|
size_t data_size = decoder_lib.data_size(decoder);
|
||||||
|
|
||||||
|
/* Create a name for the local encoder */
|
||||||
|
std::string module_name = generate_bl_memory_decoder_subckt_name(addr_size, data_size);
|
||||||
|
|
||||||
|
/* Create a Verilog Module based on the circuit model, and add to module manager */
|
||||||
|
ModuleId module_id = module_manager.add_module(module_name);
|
||||||
|
VTR_ASSERT(true == module_manager.valid_module_id(module_id));
|
||||||
|
|
||||||
|
/* Add enable port */
|
||||||
|
BasicPort en_port(std::string(DECODER_ENABLE_PORT_NAME), 1);
|
||||||
|
module_manager.add_port(module_id, en_port, ModuleManager::MODULE_INPUT_PORT);
|
||||||
|
/* Add each input port */
|
||||||
|
BasicPort addr_port(std::string(DECODER_ADDRESS_PORT_NAME), addr_size);
|
||||||
|
module_manager.add_port(module_id, addr_port, ModuleManager::MODULE_INPUT_PORT);
|
||||||
|
/* Add each 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);
|
||||||
|
/* Add each output port */
|
||||||
|
BasicPort data_port(std::string(DECODER_DATA_OUT_PORT_NAME), data_size);
|
||||||
|
module_manager.add_port(module_id, data_port, ModuleManager::MODULE_OUTPUT_PORT);
|
||||||
|
|
||||||
|
/* Data port is registered. It should be outputted as
|
||||||
|
* output reg [lsb:msb] data
|
||||||
|
*/
|
||||||
|
module_manager.set_port_is_register(module_id, data_port.get_name(), true);
|
||||||
|
/* Add data_in port */
|
||||||
|
if (true == decoder_lib.use_data_inv_port(decoder)) {
|
||||||
|
BasicPort data_inv_port(std::string(DECODER_DATA_OUT_INV_PORT_NAME), data_size);
|
||||||
|
module_manager.add_port(module_id, data_inv_port, ModuleManager::MODULE_OUTPUT_PORT);
|
||||||
|
}
|
||||||
|
|
||||||
|
return module_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/***************************************************************************************
|
||||||
|
* Create a module for a Word-line decoder with a given output size
|
||||||
|
*
|
||||||
|
* WL Address
|
||||||
|
* | | ... |
|
||||||
|
* v v v
|
||||||
|
* +-----------+
|
||||||
|
* / \
|
||||||
|
* enable-->/ Decoder \
|
||||||
|
* +-----------------+
|
||||||
|
* | | | ... | | |
|
||||||
|
* v v v v v v
|
||||||
|
* Data Outputs
|
||||||
|
*
|
||||||
|
* The outputs are assumes to be one-hot codes (at most only one '1' exist)
|
||||||
|
* Considering this fact, there are only num_of_outputs conditions to be encoded.
|
||||||
|
* Therefore, the number of inputs is ceil(log(num_of_outputs)/log(2))
|
||||||
|
***************************************************************************************/
|
||||||
|
ModuleId build_wl_memory_decoder_module(ModuleManager& module_manager,
|
||||||
|
const DecoderLibrary& decoder_lib,
|
||||||
|
const DecoderId& decoder) {
|
||||||
|
/* Get the number of inputs */
|
||||||
|
size_t addr_size = decoder_lib.addr_size(decoder);
|
||||||
|
size_t data_size = decoder_lib.data_size(decoder);
|
||||||
|
|
||||||
|
/* Create a name for the local encoder */
|
||||||
|
std::string module_name = generate_wl_memory_decoder_subckt_name(addr_size, data_size);
|
||||||
|
|
||||||
|
/* Create a Verilog Module based on the circuit model, and add to module manager */
|
||||||
|
ModuleId module_id = module_manager.add_module(module_name);
|
||||||
|
VTR_ASSERT(true == module_manager.valid_module_id(module_id));
|
||||||
|
|
||||||
|
/* Add enable port */
|
||||||
|
BasicPort en_port(std::string(DECODER_ENABLE_PORT_NAME), 1);
|
||||||
|
module_manager.add_port(module_id, en_port, ModuleManager::MODULE_INPUT_PORT);
|
||||||
|
/* Add each input port */
|
||||||
|
BasicPort addr_port(std::string(DECODER_ADDRESS_PORT_NAME), addr_size);
|
||||||
|
module_manager.add_port(module_id, addr_port, ModuleManager::MODULE_INPUT_PORT);
|
||||||
|
/* Add each output port */
|
||||||
|
BasicPort data_port(std::string(DECODER_DATA_OUT_PORT_NAME), data_size);
|
||||||
|
module_manager.add_port(module_id, data_port, ModuleManager::MODULE_OUTPUT_PORT);
|
||||||
|
|
||||||
|
/* Data port is registered. It should be outputted as
|
||||||
|
* output reg [lsb:msb] data
|
||||||
|
*/
|
||||||
|
module_manager.set_port_is_register(module_id, data_port.get_name(), true);
|
||||||
|
/* Add data_in port */
|
||||||
|
if (true == decoder_lib.use_data_inv_port(decoder)) {
|
||||||
|
BasicPort data_inv_port(std::string(DECODER_DATA_OUT_INV_PORT_NAME), data_size);
|
||||||
|
module_manager.add_port(module_id, data_inv_port, ModuleManager::MODULE_OUTPUT_PORT);
|
||||||
|
}
|
||||||
|
|
||||||
|
return module_id;
|
||||||
|
}
|
||||||
|
|
||||||
/***************************************************************************************
|
/***************************************************************************************
|
||||||
* Create a module for a decoder with a given output size
|
* Create a module for a decoder with a given output size
|
||||||
*
|
*
|
||||||
|
|
|
@ -20,6 +20,14 @@ ModuleId build_frame_memory_decoder_module(ModuleManager& module_manager,
|
||||||
const DecoderLibrary& decoder_lib,
|
const DecoderLibrary& decoder_lib,
|
||||||
const DecoderId& decoder);
|
const DecoderId& decoder);
|
||||||
|
|
||||||
|
ModuleId build_bl_memory_decoder_module(ModuleManager& module_manager,
|
||||||
|
const DecoderLibrary& decoder_lib,
|
||||||
|
const DecoderId& decoder);
|
||||||
|
|
||||||
|
ModuleId build_wl_memory_decoder_module(ModuleManager& module_manager,
|
||||||
|
const DecoderLibrary& decoder_lib,
|
||||||
|
const DecoderId& decoder);
|
||||||
|
|
||||||
void build_mux_local_decoder_modules(ModuleManager& module_manager,
|
void build_mux_local_decoder_modules(ModuleManager& module_manager,
|
||||||
const MuxLibrary& mux_lib,
|
const MuxLibrary& mux_lib,
|
||||||
const CircuitLibrary& circuit_lib);
|
const CircuitLibrary& circuit_lib);
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
#include "memory_utils.h"
|
#include "memory_utils.h"
|
||||||
#include "decoder_library_utils.h"
|
#include "decoder_library_utils.h"
|
||||||
#include "module_manager_utils.h"
|
#include "module_manager_utils.h"
|
||||||
|
#include "build_decoder_modules.h"
|
||||||
#include "build_top_module_memory.h"
|
#include "build_top_module_memory.h"
|
||||||
|
|
||||||
/* begin namespace openfpga */
|
/* begin namespace openfpga */
|
||||||
|
@ -461,6 +462,249 @@ void add_top_module_sram_ports(ModuleManager& module_manager,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
* Top-level function to add nets for memory banks
|
||||||
|
* - Find the number of BLs and WLs required
|
||||||
|
* - Create BL and WL decoders, and add them to decoder library
|
||||||
|
* - Create nets to connect from top-level module inputs to inputs of decoders
|
||||||
|
* - Create nets to connect from outputs of decoders to BL/WL of configurable children
|
||||||
|
*
|
||||||
|
* WL_enable WL address
|
||||||
|
* | |
|
||||||
|
* v v
|
||||||
|
* +-----------------------------------------------+
|
||||||
|
* | Word Line Decoder |
|
||||||
|
* +-----------------------------------------------+
|
||||||
|
* +---------+ | | |
|
||||||
|
* BL | | | | |
|
||||||
|
* enable ---->| |-----------+--------------+---- ... |------+--> BL[0]
|
||||||
|
* | | | | | | | |
|
||||||
|
* | | | v | v | v
|
||||||
|
* | Bit | | +------+ | +------+ | +------+
|
||||||
|
* BL | Line | +-->| SRAM | +-->| SRAM | +->| SRAM |
|
||||||
|
* address ---->| Decoder | | | [0] | | | [1] | ... | | [i] |
|
||||||
|
* | | | +------+ | +------+ | +------+
|
||||||
|
* | | | | |
|
||||||
|
* | |-----------+--------------+---- --- | -----+--> BL[1]
|
||||||
|
* | | | | | | | |
|
||||||
|
* | | | v | v | v
|
||||||
|
* | | | +------+ | +------+ | +------+
|
||||||
|
* | | +-->| SRAM | | | SRAM | +->| SRAM |
|
||||||
|
* | | | | [x] | | | [x+1]| ... | | [x+i]|
|
||||||
|
* | | | +------+ | +------+ | +------+
|
||||||
|
* | | | |
|
||||||
|
* | | | ... ... ... | ...
|
||||||
|
* | | | | |
|
||||||
|
* | |-----------+--------------+---- --- | -----+--> BL[y]
|
||||||
|
* | | | | | | | |
|
||||||
|
* | | | v | v | v
|
||||||
|
* | | | +------+ | +------+ | +------+
|
||||||
|
* | | +-->| SRAM | +-->| SRAM | +->| SRAM |
|
||||||
|
* | | | | [y] | | |[y+1] | ... | |[y+i] |
|
||||||
|
* | | | +------+ | +------+ | +------+
|
||||||
|
* BL | | v v v
|
||||||
|
* data_in ---->| | WL[0] WL[1] WL[i]
|
||||||
|
* +---------+
|
||||||
|
*
|
||||||
|
**********************************************************************/
|
||||||
|
static
|
||||||
|
void add_top_module_nets_cmos_memory_bank_config_bus(ModuleManager& module_manager,
|
||||||
|
DecoderLibrary& decoder_lib,
|
||||||
|
const ModuleId& top_module) {
|
||||||
|
/* 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);
|
||||||
|
|
||||||
|
/* Find data-in port from the top-level module */
|
||||||
|
ModulePortId din_port = module_manager.find_module_port(top_module, std::string(DECODER_DATA_IN_PORT_NAME));
|
||||||
|
BasicPort din_port_info = module_manager.module_port(top_module, din_port);
|
||||||
|
|
||||||
|
/* Find BL and WL address port from the top-level module */
|
||||||
|
ModulePortId bl_addr_port = module_manager.find_module_port(top_module, std::string(DECODER_BL_ADDRESS_PORT_NAME));
|
||||||
|
BasicPort bl_addr_port_info = module_manager.module_port(top_module, bl_addr_port);
|
||||||
|
|
||||||
|
ModulePortId wl_addr_port = module_manager.find_module_port(top_module, std::string(DECODER_WL_ADDRESS_PORT_NAME));
|
||||||
|
BasicPort wl_addr_port_info = module_manager.module_port(top_module, wl_addr_port);
|
||||||
|
|
||||||
|
/* Find the number of BLs and WLs required to access each memory bit */
|
||||||
|
size_t bl_addr_size = bl_addr_port_info.get_width();
|
||||||
|
size_t wl_addr_size = wl_addr_port_info.get_width();
|
||||||
|
size_t num_bls = find_memory_decoder_data_size(bl_addr_size);
|
||||||
|
size_t num_wls = find_memory_decoder_data_size(wl_addr_size);
|
||||||
|
|
||||||
|
/* Add the BL decoder module
|
||||||
|
* Search the decoder library
|
||||||
|
* If we find one, we use the module.
|
||||||
|
* Otherwise, we create one and add it to the decoder library
|
||||||
|
*/
|
||||||
|
DecoderId bl_decoder_id = decoder_lib.find_decoder(bl_addr_size, num_bls,
|
||||||
|
true, true, false);
|
||||||
|
if (DecoderId::INVALID() == bl_decoder_id) {
|
||||||
|
bl_decoder_id = decoder_lib.add_decoder(bl_addr_size, num_bls, true, true, false);
|
||||||
|
}
|
||||||
|
VTR_ASSERT(DecoderId::INVALID() != bl_decoder_id);
|
||||||
|
|
||||||
|
/* Create a module if not existed yet */
|
||||||
|
std::string bl_decoder_module_name = generate_bl_memory_decoder_subckt_name(bl_addr_size, num_bls);
|
||||||
|
ModuleId bl_decoder_module = module_manager.find_module(bl_decoder_module_name);
|
||||||
|
if (ModuleId::INVALID() == bl_decoder_module) {
|
||||||
|
/* BL decoder has the same ports as the frame-based decoders
|
||||||
|
* We reuse it here
|
||||||
|
*/
|
||||||
|
bl_decoder_module = build_bl_memory_decoder_module(module_manager,
|
||||||
|
decoder_lib,
|
||||||
|
bl_decoder_id);
|
||||||
|
}
|
||||||
|
VTR_ASSERT(ModuleId::INVALID() != bl_decoder_module);
|
||||||
|
VTR_ASSERT(0 == module_manager.num_instance(top_module, bl_decoder_module));
|
||||||
|
module_manager.add_child_module(top_module, bl_decoder_module);
|
||||||
|
|
||||||
|
/* Add the WL decoder module
|
||||||
|
* Search the decoder library
|
||||||
|
* If we find one, we use the module.
|
||||||
|
* Otherwise, we create one and add it to the decoder library
|
||||||
|
*/
|
||||||
|
DecoderId wl_decoder_id = decoder_lib.find_decoder(wl_addr_size, num_wls,
|
||||||
|
true, false, false);
|
||||||
|
if (DecoderId::INVALID() == wl_decoder_id) {
|
||||||
|
wl_decoder_id = decoder_lib.add_decoder(wl_addr_size, num_wls, true, false, false);
|
||||||
|
}
|
||||||
|
VTR_ASSERT(DecoderId::INVALID() != wl_decoder_id);
|
||||||
|
|
||||||
|
/* Create a module if not existed yet */
|
||||||
|
std::string wl_decoder_module_name = generate_bl_memory_decoder_subckt_name(wl_addr_size, num_wls);
|
||||||
|
ModuleId wl_decoder_module = module_manager.find_module(wl_decoder_module_name);
|
||||||
|
if (ModuleId::INVALID() == wl_decoder_module) {
|
||||||
|
/* BL decoder has the same ports as the frame-based decoders
|
||||||
|
* We reuse it here
|
||||||
|
*/
|
||||||
|
wl_decoder_module = build_wl_memory_decoder_module(module_manager,
|
||||||
|
decoder_lib,
|
||||||
|
wl_decoder_id);
|
||||||
|
}
|
||||||
|
VTR_ASSERT(ModuleId::INVALID() != wl_decoder_module);
|
||||||
|
VTR_ASSERT(0 == module_manager.num_instance(top_module, wl_decoder_module));
|
||||||
|
module_manager.add_child_module(top_module, wl_decoder_module);
|
||||||
|
|
||||||
|
/* Add module nets from the top module to BL decoder's inputs */
|
||||||
|
ModulePortId bl_decoder_en_port = module_manager.find_module_port(bl_decoder_module, std::string(DECODER_ENABLE_PORT_NAME));
|
||||||
|
BasicPort bl_decoder_en_port_info = module_manager.module_port(bl_decoder_module, bl_decoder_en_port);
|
||||||
|
|
||||||
|
ModulePortId bl_decoder_addr_port = module_manager.find_module_port(bl_decoder_module, std::string(DECODER_ADDRESS_PORT_NAME));
|
||||||
|
BasicPort bl_decoder_addr_port_info = module_manager.module_port(bl_decoder_module, bl_decoder_addr_port);
|
||||||
|
|
||||||
|
ModulePortId bl_decoder_din_port = module_manager.find_module_port(bl_decoder_module, std::string(DECODER_DATA_IN_PORT_NAME));
|
||||||
|
BasicPort bl_decoder_din_port_info = module_manager.module_port(bl_decoder_module, bl_decoder_din_port);
|
||||||
|
|
||||||
|
/* Top module Enable port -> BL Decoder Enable port */
|
||||||
|
add_module_bus_nets(module_manager,
|
||||||
|
top_module,
|
||||||
|
top_module, 0, en_port,
|
||||||
|
bl_decoder_module, 0, bl_decoder_en_port);
|
||||||
|
|
||||||
|
/* Top module Address port -> BL Decoder Address port */
|
||||||
|
add_module_bus_nets(module_manager,
|
||||||
|
top_module,
|
||||||
|
top_module, 0, bl_addr_port,
|
||||||
|
bl_decoder_module, 0, bl_decoder_addr_port);
|
||||||
|
|
||||||
|
/* Top module data_in port -> BL Decoder data_in port */
|
||||||
|
add_module_bus_nets(module_manager,
|
||||||
|
top_module,
|
||||||
|
top_module, 0, din_port,
|
||||||
|
bl_decoder_module, 0, bl_decoder_din_port);
|
||||||
|
|
||||||
|
/* Add module nets from the top module to WL decoder's inputs */
|
||||||
|
ModulePortId wl_decoder_en_port = module_manager.find_module_port(wl_decoder_module, std::string(DECODER_ENABLE_PORT_NAME));
|
||||||
|
BasicPort wl_decoder_en_port_info = module_manager.module_port(wl_decoder_module, wl_decoder_en_port);
|
||||||
|
|
||||||
|
ModulePortId wl_decoder_addr_port = module_manager.find_module_port(wl_decoder_module, std::string(DECODER_ADDRESS_PORT_NAME));
|
||||||
|
BasicPort wl_decoder_addr_port_info = module_manager.module_port(wl_decoder_module, bl_decoder_addr_port);
|
||||||
|
|
||||||
|
/* Top module Enable port -> WL Decoder Enable port */
|
||||||
|
add_module_bus_nets(module_manager,
|
||||||
|
top_module,
|
||||||
|
top_module, 0, en_port,
|
||||||
|
wl_decoder_module, 0, wl_decoder_en_port);
|
||||||
|
|
||||||
|
/* Top module Address port -> WL Decoder Address port */
|
||||||
|
add_module_bus_nets(module_manager,
|
||||||
|
top_module,
|
||||||
|
top_module, 0, wl_addr_port,
|
||||||
|
wl_decoder_module, 0, wl_decoder_addr_port);
|
||||||
|
|
||||||
|
/* Add nets from BL data out to each configurable child */
|
||||||
|
size_t cur_bl_index = 0;
|
||||||
|
|
||||||
|
ModulePortId bl_decoder_dout_port = module_manager.find_module_port(bl_decoder_module, std::string(DECODER_DATA_OUT_PORT_NAME));
|
||||||
|
BasicPort bl_decoder_dout_port_info = module_manager.module_port(bl_decoder_module, bl_decoder_dout_port);
|
||||||
|
|
||||||
|
for (size_t child_id = 0; child_id < module_manager.configurable_children(top_module).size(); ++child_id) {
|
||||||
|
ModuleId child_module = module_manager.configurable_children(top_module)[child_id];
|
||||||
|
size_t child_instance = module_manager.configurable_child_instances(top_module)[child_id];
|
||||||
|
|
||||||
|
/* Find the BL port */
|
||||||
|
ModulePortId child_bl_port = module_manager.find_module_port(child_module, std::string(MEMORY_BL_PORT_NAME));
|
||||||
|
BasicPort child_bl_port_info = module_manager.module_port(child_module, child_bl_port);
|
||||||
|
|
||||||
|
for (const size_t& sink_bl_pin : child_bl_port_info.pins()) {
|
||||||
|
/* Find the BL decoder data index:
|
||||||
|
* It should be the residual when divided by the number of BLs
|
||||||
|
*/
|
||||||
|
size_t bl_pin_id = cur_bl_index / num_bls;
|
||||||
|
|
||||||
|
/* Create net */
|
||||||
|
ModuleNetId net = create_module_source_pin_net(module_manager, top_module,
|
||||||
|
bl_decoder_module, 0,
|
||||||
|
bl_decoder_dout_port,
|
||||||
|
bl_decoder_dout_port_info.pins()[bl_pin_id]);
|
||||||
|
VTR_ASSERT(ModuleNetId::INVALID() != net);
|
||||||
|
|
||||||
|
/* Add net sink */
|
||||||
|
module_manager.add_module_net_sink(top_module, net,
|
||||||
|
child_module, child_instance, child_bl_port, sink_bl_pin);
|
||||||
|
|
||||||
|
/* Increment the BL index */
|
||||||
|
cur_bl_index++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add nets from WL data out to each configurable child */
|
||||||
|
size_t cur_wl_index = 0;
|
||||||
|
|
||||||
|
ModulePortId wl_decoder_dout_port = module_manager.find_module_port(wl_decoder_module, std::string(DECODER_DATA_OUT_PORT_NAME));
|
||||||
|
BasicPort wl_decoder_dout_port_info = module_manager.module_port(wl_decoder_module, wl_decoder_dout_port);
|
||||||
|
|
||||||
|
for (size_t child_id = 0; child_id < module_manager.configurable_children(top_module).size(); ++child_id) {
|
||||||
|
ModuleId child_module = module_manager.configurable_children(top_module)[child_id];
|
||||||
|
size_t child_instance = module_manager.configurable_child_instances(top_module)[child_id];
|
||||||
|
|
||||||
|
/* Find the WL port */
|
||||||
|
ModulePortId child_wl_port = module_manager.find_module_port(child_module, std::string(MEMORY_WL_PORT_NAME));
|
||||||
|
BasicPort child_wl_port_info = module_manager.module_port(child_module, child_wl_port);
|
||||||
|
|
||||||
|
for (const size_t& sink_wl_pin : child_wl_port_info.pins()) {
|
||||||
|
/* Find the BL decoder data index:
|
||||||
|
* It should be the residual when divided by the number of BLs
|
||||||
|
*/
|
||||||
|
size_t wl_pin_id = cur_wl_index % num_wls;
|
||||||
|
|
||||||
|
/* Create net */
|
||||||
|
ModuleNetId net = create_module_source_pin_net(module_manager, top_module,
|
||||||
|
wl_decoder_module, 0,
|
||||||
|
wl_decoder_dout_port,
|
||||||
|
wl_decoder_dout_port_info.pins()[wl_pin_id]);
|
||||||
|
VTR_ASSERT(ModuleNetId::INVALID() != net);
|
||||||
|
|
||||||
|
/* Add net sink */
|
||||||
|
module_manager.add_module_net_sink(top_module, net,
|
||||||
|
child_module, child_instance, child_wl_port, sink_wl_pin);
|
||||||
|
|
||||||
|
/* Increment the WL index */
|
||||||
|
cur_wl_index++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*********************************************************************
|
/*********************************************************************
|
||||||
* Add the port-to-port connection between all the memory modules
|
* Add the port-to-port connection between all the memory modules
|
||||||
|
@ -524,6 +768,7 @@ void add_top_module_nets_cmos_memory_config_bus(ModuleManager& module_manager,
|
||||||
}
|
}
|
||||||
case CONFIG_MEM_MEMORY_BANK:
|
case CONFIG_MEM_MEMORY_BANK:
|
||||||
/* TODO */
|
/* TODO */
|
||||||
|
add_top_module_nets_cmos_memory_bank_config_bus(module_manager, decoder_lib, parent_module);
|
||||||
break;
|
break;
|
||||||
case CONFIG_MEM_FRAME_BASED:
|
case CONFIG_MEM_FRAME_BASED:
|
||||||
add_module_nets_cmos_memory_frame_config_bus(module_manager, decoder_lib, parent_module);
|
add_module_nets_cmos_memory_frame_config_bus(module_manager, decoder_lib, parent_module);
|
||||||
|
|
|
@ -77,6 +77,10 @@ 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)));
|
return find_mux_local_decoder_addr_size((size_t)std::ceil(std::sqrt((float)num_mems)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t find_memory_decoder_data_size(const size_t& num_addr) {
|
||||||
|
return (size_t)std::pow(2., num_addr);
|
||||||
|
}
|
||||||
|
|
||||||
/***************************************************************************************
|
/***************************************************************************************
|
||||||
* Try to find if the decoder already exists in the library,
|
* Try to find if the decoder already exists in the library,
|
||||||
* If there is no such decoder, add it to the library
|
* If there is no such decoder, add it to the library
|
||||||
|
|
|
@ -15,6 +15,8 @@ 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);
|
size_t find_memory_decoder_addr_size(const size_t& num_mems);
|
||||||
|
|
||||||
|
size_t find_memory_decoder_data_size(const size_t& num_addr);
|
||||||
|
|
||||||
DecoderId add_mux_local_decoder_to_library(DecoderLibrary& decoder_lib,
|
DecoderId add_mux_local_decoder_to_library(DecoderLibrary& decoder_lib,
|
||||||
const size_t data_size);
|
const size_t data_size);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue