[Engine] Support WLR port in OpenFPGA architecture file and fabric generator
This commit is contained in:
parent
0450d57d82
commit
36a4da863c
|
@ -101,10 +101,11 @@ enum e_circuit_model_port_type {
|
||||||
CIRCUIT_MODEL_PORT_BLB,
|
CIRCUIT_MODEL_PORT_BLB,
|
||||||
CIRCUIT_MODEL_PORT_WL,
|
CIRCUIT_MODEL_PORT_WL,
|
||||||
CIRCUIT_MODEL_PORT_WLB,
|
CIRCUIT_MODEL_PORT_WLB,
|
||||||
|
CIRCUIT_MODEL_PORT_WLR,
|
||||||
NUM_CIRCUIT_MODEL_PORT_TYPES
|
NUM_CIRCUIT_MODEL_PORT_TYPES
|
||||||
};
|
};
|
||||||
/* Strings correspond to each port type */
|
/* Strings correspond to each port type */
|
||||||
constexpr std::array<const char*, NUM_CIRCUIT_MODEL_PORT_TYPES> CIRCUIT_MODEL_PORT_TYPE_STRING = {{"input", "output", "inout", "clock", "sram", "bl", "blb", "wl", "wlb"}};
|
constexpr std::array<const char*, NUM_CIRCUIT_MODEL_PORT_TYPES> CIRCUIT_MODEL_PORT_TYPE_STRING = {{"input", "output", "inout", "clock", "sram", "bl", "blb", "wl", "wlb", "wlr"}};
|
||||||
|
|
||||||
enum e_circuit_model_delay_type {
|
enum e_circuit_model_delay_type {
|
||||||
CIRCUIT_MODEL_DELAY_RISE,
|
CIRCUIT_MODEL_DELAY_RISE,
|
||||||
|
|
|
@ -33,6 +33,7 @@ constexpr char* CONNECTION_BLOCK_MEM_INSTANCE_PREFIX = "mem_";
|
||||||
constexpr char* MEMORY_MODULE_POSTFIX = "_mem";
|
constexpr char* MEMORY_MODULE_POSTFIX = "_mem";
|
||||||
constexpr char* MEMORY_BL_PORT_NAME = "bl";
|
constexpr char* MEMORY_BL_PORT_NAME = "bl";
|
||||||
constexpr char* MEMORY_WL_PORT_NAME = "wl";
|
constexpr char* MEMORY_WL_PORT_NAME = "wl";
|
||||||
|
constexpr char* MEMORY_WLR_PORT_NAME = "wlr";
|
||||||
|
|
||||||
/* Multiplexer naming constant strings */
|
/* Multiplexer naming constant strings */
|
||||||
constexpr char* MUX_BASIS_MODULE_POSTFIX = "_basis";
|
constexpr char* MUX_BASIS_MODULE_POSTFIX = "_basis";
|
||||||
|
@ -48,6 +49,8 @@ constexpr char* DECODER_DATA_OUT_PORT_NAME = "data_out";
|
||||||
constexpr char* DECODER_DATA_OUT_INV_PORT_NAME = "data_out_inv";
|
constexpr char* DECODER_DATA_OUT_INV_PORT_NAME = "data_out_inv";
|
||||||
constexpr char* DECODER_BL_ADDRESS_PORT_NAME = "bl_address";
|
constexpr char* DECODER_BL_ADDRESS_PORT_NAME = "bl_address";
|
||||||
constexpr char* DECODER_WL_ADDRESS_PORT_NAME = "wl_address";
|
constexpr char* DECODER_WL_ADDRESS_PORT_NAME = "wl_address";
|
||||||
|
constexpr char* DECODER_READBACK_PORT_NAME = "readback";
|
||||||
|
constexpr char* DECODER_DATA_READ_ENABLE_PORT_NAME = "data_out_ren";
|
||||||
|
|
||||||
/* Inverted port naming */
|
/* Inverted port naming */
|
||||||
constexpr char* INV_PORT_POSTFIX = "_inv";
|
constexpr char* INV_PORT_POSTFIX = "_inv";
|
||||||
|
|
|
@ -719,9 +719,11 @@ std::string generate_sram_port_name(const e_config_protocol_type& sram_orgz_type
|
||||||
*/
|
*/
|
||||||
if (CIRCUIT_MODEL_PORT_BL == port_type) {
|
if (CIRCUIT_MODEL_PORT_BL == port_type) {
|
||||||
port_name = std::string(MEMORY_BL_PORT_NAME);
|
port_name = std::string(MEMORY_BL_PORT_NAME);
|
||||||
} else {
|
} else if (CIRCUIT_MODEL_PORT_WL == port_type) {
|
||||||
VTR_ASSERT( CIRCUIT_MODEL_PORT_WL == port_type );
|
|
||||||
port_name = std::string(MEMORY_WL_PORT_NAME);
|
port_name = std::string(MEMORY_WL_PORT_NAME);
|
||||||
|
} else {
|
||||||
|
VTR_ASSERT( CIRCUIT_MODEL_PORT_WLR == port_type );
|
||||||
|
port_name = std::string(MEMORY_WLR_PORT_NAME);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case CONFIG_MEM_FRAME_BASED:
|
case CONFIG_MEM_FRAME_BASED:
|
||||||
|
|
|
@ -184,6 +184,18 @@ ModuleId build_wl_memory_decoder_module(ModuleManager& module_manager,
|
||||||
module_manager.add_port(module_id, data_inv_port, ModuleManager::MODULE_OUTPUT_PORT);
|
module_manager.add_port(module_id, data_inv_port, ModuleManager::MODULE_OUTPUT_PORT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Add readback port */
|
||||||
|
if (true == decoder_lib.use_readback(decoder)) {
|
||||||
|
BasicPort readback_port(std::string(DECODER_READBACK_PORT_NAME), 1);
|
||||||
|
module_manager.add_port(module_id, readback_port, ModuleManager::MODULE_INPUT_PORT);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add data read-enable port */
|
||||||
|
if (true == decoder_lib.use_readback(decoder)) {
|
||||||
|
BasicPort data_ren_port(std::string(DECODER_DATA_READ_ENABLE_PORT_NAME), data_size);
|
||||||
|
module_manager.add_port(module_id, data_ren_port, ModuleManager::MODULE_OUTPUT_PORT);
|
||||||
|
}
|
||||||
|
|
||||||
return module_id;
|
return module_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -366,12 +366,15 @@ void build_memory_flatten_module(ModuleManager& module_manager,
|
||||||
/* Get the BL/WL ports from the SRAM */
|
/* Get the BL/WL ports from the SRAM */
|
||||||
std::vector<CircuitPortId> sram_bl_ports = circuit_lib.model_ports_by_type(sram_model, CIRCUIT_MODEL_PORT_BL, true);
|
std::vector<CircuitPortId> sram_bl_ports = circuit_lib.model_ports_by_type(sram_model, CIRCUIT_MODEL_PORT_BL, true);
|
||||||
std::vector<CircuitPortId> sram_wl_ports = circuit_lib.model_ports_by_type(sram_model, CIRCUIT_MODEL_PORT_WL, true);
|
std::vector<CircuitPortId> sram_wl_ports = circuit_lib.model_ports_by_type(sram_model, CIRCUIT_MODEL_PORT_WL, true);
|
||||||
|
/* Optional: Get the WLR ports from the SRAM */
|
||||||
|
std::vector<CircuitPortId> sram_wlr_ports = circuit_lib.model_ports_by_type(sram_model, CIRCUIT_MODEL_PORT_WLR, true);
|
||||||
/* Get the output ports from the SRAM */
|
/* Get the output ports from the SRAM */
|
||||||
std::vector<CircuitPortId> sram_output_ports = circuit_lib.model_ports_by_type(sram_model, CIRCUIT_MODEL_PORT_OUTPUT, true);
|
std::vector<CircuitPortId> sram_output_ports = circuit_lib.model_ports_by_type(sram_model, CIRCUIT_MODEL_PORT_OUTPUT, true);
|
||||||
|
|
||||||
/* Ensure that we have only 1 BL, 1 WL and 2 output ports*/
|
/* Ensure that we have only 1 BL, 1 WL and 2 output ports, as well as an optional WLR*/
|
||||||
VTR_ASSERT(1 == sram_bl_ports.size());
|
VTR_ASSERT(1 == sram_bl_ports.size());
|
||||||
VTR_ASSERT(1 == sram_wl_ports.size());
|
VTR_ASSERT(1 == sram_wl_ports.size());
|
||||||
|
VTR_ASSERT(2 > sram_wlr_ports.size());
|
||||||
VTR_ASSERT(2 == sram_output_ports.size());
|
VTR_ASSERT(2 == sram_output_ports.size());
|
||||||
|
|
||||||
/* Create a module and add to the module manager */
|
/* Create a module and add to the module manager */
|
||||||
|
@ -389,6 +392,12 @@ void build_memory_flatten_module(ModuleManager& module_manager,
|
||||||
BasicPort wl_port(std::string(MEMORY_WL_PORT_NAME), num_mems);
|
BasicPort wl_port(std::string(MEMORY_WL_PORT_NAME), num_mems);
|
||||||
ModulePortId mem_wl_port = module_manager.add_port(mem_module, wl_port, ModuleManager::MODULE_INPUT_PORT);
|
ModulePortId mem_wl_port = module_manager.add_port(mem_module, wl_port, ModuleManager::MODULE_INPUT_PORT);
|
||||||
|
|
||||||
|
BasicPort wlr_port(std::string(MEMORY_WLR_PORT_NAME), num_mems);
|
||||||
|
ModulePortId mem_wlr_port = ModulePortId::INVALID();
|
||||||
|
if (!sram_wlr_ports.empty()) {
|
||||||
|
mem_wlr_port = module_manager.add_port(mem_module, wlr_port, ModuleManager::MODULE_INPUT_PORT);
|
||||||
|
}
|
||||||
|
|
||||||
/* Add each output port: port width should match the number of memories */
|
/* Add each output port: port width should match the number of memories */
|
||||||
for (size_t iport = 0; iport < sram_output_ports.size(); ++iport) {
|
for (size_t iport = 0; iport < sram_output_ports.size(); ++iport) {
|
||||||
std::string port_name;
|
std::string port_name;
|
||||||
|
@ -419,6 +428,9 @@ void build_memory_flatten_module(ModuleManager& module_manager,
|
||||||
for (const CircuitPortId& port : sram_wl_ports) {
|
for (const CircuitPortId& port : sram_wl_ports) {
|
||||||
add_module_input_nets_to_mem_modules(module_manager, mem_module, mem_wl_port, circuit_lib, port, sram_mem_module, i, sram_mem_instance);
|
add_module_input_nets_to_mem_modules(module_manager, mem_module, mem_wl_port, circuit_lib, port, sram_mem_module, i, sram_mem_instance);
|
||||||
}
|
}
|
||||||
|
for (const CircuitPortId& port : sram_wlr_ports) {
|
||||||
|
add_module_input_nets_to_mem_modules(module_manager, mem_module, mem_wlr_port, circuit_lib, port, sram_mem_module, i, sram_mem_instance);
|
||||||
|
}
|
||||||
/* Wire outputs of child module to outputs of parent module */
|
/* Wire outputs of child module to outputs of parent module */
|
||||||
add_module_output_nets_to_mem_modules(module_manager, mem_module, circuit_lib, sram_output_ports, sram_mem_module, i, sram_mem_instance);
|
add_module_output_nets_to_mem_modules(module_manager, mem_module, circuit_lib, sram_output_ports, sram_mem_module, i, sram_mem_instance);
|
||||||
}
|
}
|
||||||
|
@ -644,9 +656,9 @@ void build_frame_memory_module(ModuleManager& module_manager,
|
||||||
* If we find one, we use the module.
|
* If we find one, we use the module.
|
||||||
* Otherwise, we create one and add it to the decoder library
|
* Otherwise, we create one and add it to the decoder library
|
||||||
*/
|
*/
|
||||||
DecoderId decoder_id = frame_decoder_lib.find_decoder(addr_size, data_size, true, false, use_data_inv);
|
DecoderId decoder_id = frame_decoder_lib.find_decoder(addr_size, data_size, true, false, use_data_inv, false);
|
||||||
if (DecoderId::INVALID() == decoder_id) {
|
if (DecoderId::INVALID() == decoder_id) {
|
||||||
decoder_id = frame_decoder_lib.add_decoder(addr_size, data_size, true, false, use_data_inv);
|
decoder_id = frame_decoder_lib.add_decoder(addr_size, data_size, true, false, use_data_inv, false);
|
||||||
}
|
}
|
||||||
VTR_ASSERT(DecoderId::INVALID() != decoder_id);
|
VTR_ASSERT(DecoderId::INVALID() != decoder_id);
|
||||||
|
|
||||||
|
|
|
@ -870,6 +870,12 @@ void add_top_module_sram_ports(ModuleManager& module_manager,
|
||||||
BasicPort wl_addr_port(std::string(DECODER_WL_ADDRESS_PORT_NAME), wl_addr_size);
|
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);
|
module_manager.add_port(module_id, wl_addr_port, ModuleManager::MODULE_INPUT_PORT);
|
||||||
|
|
||||||
|
/* Optional: If we have WLR port, we should add a read-back port */
|
||||||
|
if (!circuit_lib.model_ports_by_type(sram_model, CIRCUIT_MODEL_PORT_WLR).empty()) {
|
||||||
|
BasicPort readback_port(std::string(DECODER_READBACK_PORT_NAME), config_protocol.num_regions());
|
||||||
|
module_manager.add_port(module_id, readback_port, ModuleManager::MODULE_INPUT_PORT);
|
||||||
|
}
|
||||||
|
|
||||||
/* Data input should be dependent on the number of configuration regions*/
|
/* Data input should be dependent on the number of configuration regions*/
|
||||||
BasicPort din_port(std::string(DECODER_DATA_IN_PORT_NAME), config_protocol.num_regions());
|
BasicPort din_port(std::string(DECODER_DATA_IN_PORT_NAME), config_protocol.num_regions());
|
||||||
module_manager.add_port(module_id, din_port, ModuleManager::MODULE_INPUT_PORT);
|
module_manager.add_port(module_id, din_port, ModuleManager::MODULE_INPUT_PORT);
|
||||||
|
@ -1056,9 +1062,9 @@ void add_top_module_nets_cmos_memory_bank_config_bus(ModuleManager& module_manag
|
||||||
* Otherwise, we create one and add it to the decoder library
|
* Otherwise, we create one and add it to the decoder library
|
||||||
*/
|
*/
|
||||||
DecoderId bl_decoder_id = decoder_lib.find_decoder(bl_addr_size, num_bls,
|
DecoderId bl_decoder_id = decoder_lib.find_decoder(bl_addr_size, num_bls,
|
||||||
true, true, false);
|
true, true, false, false);
|
||||||
if (DecoderId::INVALID() == bl_decoder_id) {
|
if (DecoderId::INVALID() == bl_decoder_id) {
|
||||||
bl_decoder_id = decoder_lib.add_decoder(bl_addr_size, num_bls, true, true, false);
|
bl_decoder_id = decoder_lib.add_decoder(bl_addr_size, num_bls, true, true, false, false);
|
||||||
}
|
}
|
||||||
VTR_ASSERT(DecoderId::INVALID() != bl_decoder_id);
|
VTR_ASSERT(DecoderId::INVALID() != bl_decoder_id);
|
||||||
|
|
||||||
|
@ -1084,9 +1090,9 @@ void add_top_module_nets_cmos_memory_bank_config_bus(ModuleManager& module_manag
|
||||||
* Otherwise, we create one and add it to the decoder library
|
* Otherwise, we create one and add it to the decoder library
|
||||||
*/
|
*/
|
||||||
DecoderId wl_decoder_id = decoder_lib.find_decoder(wl_addr_size, num_wls,
|
DecoderId wl_decoder_id = decoder_lib.find_decoder(wl_addr_size, num_wls,
|
||||||
true, false, false);
|
true, false, false, false);
|
||||||
if (DecoderId::INVALID() == wl_decoder_id) {
|
if (DecoderId::INVALID() == wl_decoder_id) {
|
||||||
wl_decoder_id = decoder_lib.add_decoder(wl_addr_size, num_wls, true, false, false);
|
wl_decoder_id = decoder_lib.add_decoder(wl_addr_size, num_wls, true, false, false, false);
|
||||||
}
|
}
|
||||||
VTR_ASSERT(DecoderId::INVALID() != wl_decoder_id);
|
VTR_ASSERT(DecoderId::INVALID() != wl_decoder_id);
|
||||||
|
|
||||||
|
@ -1533,9 +1539,9 @@ void add_top_module_nets_cmos_memory_frame_decoder_config_bus(ModuleManager& mod
|
||||||
/* Search the decoder library and try to find one
|
/* Search the decoder library and try to find one
|
||||||
* If not found, create a new module and add it to the module manager
|
* If not found, create a new module and add it to the module manager
|
||||||
*/
|
*/
|
||||||
DecoderId decoder_id = decoder_lib.find_decoder(addr_size, data_size, true, false, false);
|
DecoderId decoder_id = decoder_lib.find_decoder(addr_size, data_size, true, false, false, false);
|
||||||
if (DecoderId::INVALID() == decoder_id) {
|
if (DecoderId::INVALID() == decoder_id) {
|
||||||
decoder_id = decoder_lib.add_decoder(addr_size, data_size, true, false, false);
|
decoder_id = decoder_lib.add_decoder(addr_size, data_size, true, false, false, false);
|
||||||
}
|
}
|
||||||
VTR_ASSERT(DecoderId::INVALID() != decoder_id);
|
VTR_ASSERT(DecoderId::INVALID() != decoder_id);
|
||||||
|
|
||||||
|
|
|
@ -137,6 +137,16 @@ void add_top_module_nets_cmos_ql_memory_bank_config_bus(ModuleManager& module_ma
|
||||||
/* Data in port should match the number of configuration regions */
|
/* Data in port should match the number of configuration regions */
|
||||||
VTR_ASSERT(din_port_info.get_width() == module_manager.regions(top_module).size());
|
VTR_ASSERT(din_port_info.get_width() == module_manager.regions(top_module).size());
|
||||||
|
|
||||||
|
/* Find readback port from the top-level module */
|
||||||
|
ModulePortId readback_port = module_manager.find_module_port(top_module, std::string(DECODER_READBACK_PORT_NAME));
|
||||||
|
BasicPort readback_port_info;
|
||||||
|
|
||||||
|
/* Readback port if available, should be a 1-bit port */
|
||||||
|
if (readback_port) {
|
||||||
|
readback_port_info = module_manager.module_port(top_module, readback_port);
|
||||||
|
VTR_ASSERT(readback_port_info.get_width() == 1);
|
||||||
|
}
|
||||||
|
|
||||||
/* Find BL and WL address port from the top-level module */
|
/* 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));
|
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);
|
BasicPort bl_addr_port_info = module_manager.module_port(top_module, bl_addr_port);
|
||||||
|
@ -168,9 +178,9 @@ void add_top_module_nets_cmos_ql_memory_bank_config_bus(ModuleManager& module_ma
|
||||||
* Otherwise, we create one and add it to the decoder library
|
* Otherwise, we create one and add it to the decoder library
|
||||||
*/
|
*/
|
||||||
DecoderId bl_decoder_id = decoder_lib.find_decoder(bl_addr_size, num_bls,
|
DecoderId bl_decoder_id = decoder_lib.find_decoder(bl_addr_size, num_bls,
|
||||||
true, true, false);
|
true, true, false, false);
|
||||||
if (DecoderId::INVALID() == bl_decoder_id) {
|
if (DecoderId::INVALID() == bl_decoder_id) {
|
||||||
bl_decoder_id = decoder_lib.add_decoder(bl_addr_size, num_bls, true, true, false);
|
bl_decoder_id = decoder_lib.add_decoder(bl_addr_size, num_bls, true, true, false, false);
|
||||||
}
|
}
|
||||||
VTR_ASSERT(DecoderId::INVALID() != bl_decoder_id);
|
VTR_ASSERT(DecoderId::INVALID() != bl_decoder_id);
|
||||||
|
|
||||||
|
@ -196,9 +206,9 @@ void add_top_module_nets_cmos_ql_memory_bank_config_bus(ModuleManager& module_ma
|
||||||
* Otherwise, we create one and add it to the decoder library
|
* Otherwise, we create one and add it to the decoder library
|
||||||
*/
|
*/
|
||||||
DecoderId wl_decoder_id = decoder_lib.find_decoder(wl_addr_size, num_wls,
|
DecoderId wl_decoder_id = decoder_lib.find_decoder(wl_addr_size, num_wls,
|
||||||
true, false, false);
|
true, false, false, readback_port != ModulePortId::INVALID());
|
||||||
if (DecoderId::INVALID() == wl_decoder_id) {
|
if (DecoderId::INVALID() == wl_decoder_id) {
|
||||||
wl_decoder_id = decoder_lib.add_decoder(wl_addr_size, num_wls, true, false, false);
|
wl_decoder_id = decoder_lib.add_decoder(wl_addr_size, num_wls, true, false, false, readback_port != ModulePortId::INVALID());
|
||||||
}
|
}
|
||||||
VTR_ASSERT(DecoderId::INVALID() != wl_decoder_id);
|
VTR_ASSERT(DecoderId::INVALID() != wl_decoder_id);
|
||||||
|
|
||||||
|
@ -264,7 +274,13 @@ void add_top_module_nets_cmos_ql_memory_bank_config_bus(ModuleManager& module_ma
|
||||||
BasicPort wl_decoder_en_port_info = module_manager.module_port(wl_decoder_module, wl_decoder_en_port);
|
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));
|
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);
|
BasicPort wl_decoder_addr_port_info = module_manager.module_port(wl_decoder_module, wl_decoder_addr_port);
|
||||||
|
|
||||||
|
ModulePortId wl_decoder_readback_port = module_manager.find_module_port(wl_decoder_module, std::string(DECODER_READBACK_PORT_NAME));
|
||||||
|
BasicPort wl_decoder_readback_port_info;
|
||||||
|
if (wl_decoder_readback_port) {
|
||||||
|
wl_decoder_readback_port_info = module_manager.module_port(wl_decoder_module, wl_decoder_readback_port);
|
||||||
|
}
|
||||||
|
|
||||||
/* Top module Enable port -> WL Decoder Enable port */
|
/* Top module Enable port -> WL Decoder Enable port */
|
||||||
add_module_bus_nets(module_manager,
|
add_module_bus_nets(module_manager,
|
||||||
|
@ -278,6 +294,14 @@ void add_top_module_nets_cmos_ql_memory_bank_config_bus(ModuleManager& module_ma
|
||||||
top_module, 0, wl_addr_port,
|
top_module, 0, wl_addr_port,
|
||||||
wl_decoder_module, curr_wl_decoder_instance_id, wl_decoder_addr_port);
|
wl_decoder_module, curr_wl_decoder_instance_id, wl_decoder_addr_port);
|
||||||
|
|
||||||
|
/* Top module readback port -> WL Decoder readback port */
|
||||||
|
if (wl_decoder_readback_port) {
|
||||||
|
add_module_bus_nets(module_manager,
|
||||||
|
top_module,
|
||||||
|
top_module, 0, readback_port,
|
||||||
|
wl_decoder_module, curr_wl_decoder_instance_id, wl_decoder_readback_port);
|
||||||
|
}
|
||||||
|
|
||||||
/**************************************************************
|
/**************************************************************
|
||||||
* Precompute the BLs and WLs distribution across the FPGA fabric
|
* Precompute the BLs and WLs distribution across the FPGA fabric
|
||||||
* The distribution is a matrix which contains the starting index of BL/WL for each column or row
|
* The distribution is a matrix which contains the starting index of BL/WL for each column or row
|
||||||
|
@ -391,6 +415,45 @@ void add_top_module_nets_cmos_ql_memory_bank_config_bus(ModuleManager& module_ma
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**************************************************************
|
||||||
|
* Optional: Add nets from WLR data out to each configurable child
|
||||||
|
*/
|
||||||
|
ModulePortId wl_decoder_data_ren_port = module_manager.find_module_port(wl_decoder_module, std::string(DECODER_DATA_READ_ENABLE_PORT_NAME));
|
||||||
|
BasicPort wl_decoder_data_ren_port_info;
|
||||||
|
if (wl_decoder_data_ren_port) {
|
||||||
|
wl_decoder_data_ren_port_info = module_manager.module_port(wl_decoder_module, wl_decoder_data_ren_port);
|
||||||
|
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];
|
||||||
|
|
||||||
|
size_t child_instance = module_manager.region_configurable_child_instances(top_module, config_region)[child_id];
|
||||||
|
|
||||||
|
/* Find the WL port */
|
||||||
|
ModulePortId child_wlr_port = module_manager.find_module_port(child_module, std::string(MEMORY_WLR_PORT_NAME));
|
||||||
|
BasicPort child_wlr_port_info = module_manager.module_port(child_module, child_wlr_port);
|
||||||
|
|
||||||
|
size_t cur_wlr_index = 0;
|
||||||
|
|
||||||
|
for (const size_t& sink_wlr_pin : child_wlr_port_info.pins()) {
|
||||||
|
size_t wlr_pin_id = wl_start_index_per_tile[coord.y()] + cur_wlr_index;
|
||||||
|
VTR_ASSERT(wlr_pin_id < wl_decoder_data_ren_port_info.pins().size());
|
||||||
|
|
||||||
|
/* Create net */
|
||||||
|
ModuleNetId net = create_module_source_pin_net(module_manager, top_module,
|
||||||
|
wl_decoder_module, curr_wl_decoder_instance_id,
|
||||||
|
wl_decoder_data_ren_port,
|
||||||
|
wl_decoder_data_ren_port_info.pins()[wlr_pin_id]);
|
||||||
|
VTR_ASSERT(ModuleNetId::INVALID() != net);
|
||||||
|
|
||||||
|
/* Add net sink */
|
||||||
|
module_manager.add_module_net_sink(top_module, net,
|
||||||
|
child_module, child_instance, child_wlr_port, sink_wlr_pin);
|
||||||
|
|
||||||
|
cur_wlr_index++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**************************************************************
|
/**************************************************************
|
||||||
* Add the BL and WL decoders to the end of configurable children list
|
* Add the BL and WL decoders to the end of configurable children list
|
||||||
* Note: this MUST be done after adding all the module nets to other regular configurable children
|
* Note: this MUST be done after adding all the module nets to other regular configurable children
|
||||||
|
|
|
@ -47,6 +47,11 @@ bool DecoderLibrary::use_data_inv_port(const DecoderId& decoder) const {
|
||||||
return use_data_inv_port_[decoder];
|
return use_data_inv_port_[decoder];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool DecoderLibrary::use_readback(const DecoderId& decoder) const {
|
||||||
|
VTR_ASSERT_SAFE(valid_decoder_id(decoder));
|
||||||
|
return use_readback_[decoder];
|
||||||
|
}
|
||||||
|
|
||||||
/* Find a decoder to the library, with the specification.
|
/* Find a decoder to the library, with the specification.
|
||||||
* If found, return the id of decoder.
|
* If found, return the id of decoder.
|
||||||
* If not found, return an invalid id of decoder
|
* If not found, return an invalid id of decoder
|
||||||
|
@ -61,13 +66,15 @@ DecoderId DecoderLibrary::find_decoder(const size_t& addr_size,
|
||||||
const size_t& data_size,
|
const size_t& data_size,
|
||||||
const bool& use_enable,
|
const bool& use_enable,
|
||||||
const bool& use_data_in,
|
const bool& use_data_in,
|
||||||
const bool& use_data_inv_port) const {
|
const bool& use_data_inv_port,
|
||||||
|
const bool& use_readback) const {
|
||||||
for (auto decoder : decoders()) {
|
for (auto decoder : decoders()) {
|
||||||
if ( (addr_size == addr_sizes_[decoder])
|
if ( (addr_size == addr_sizes_[decoder])
|
||||||
&& (data_size == data_sizes_[decoder])
|
&& (data_size == data_sizes_[decoder])
|
||||||
&& (use_enable == use_enable_[decoder])
|
&& (use_enable == use_enable_[decoder])
|
||||||
&& (use_data_in == use_data_in_[decoder])
|
&& (use_data_in == use_data_in_[decoder])
|
||||||
&& (use_data_inv_port == use_data_inv_port_[decoder]) ) {
|
&& (use_data_inv_port == use_data_inv_port_[decoder])
|
||||||
|
&& (use_readback == use_readback_[decoder]) ) {
|
||||||
return decoder;
|
return decoder;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -92,7 +99,8 @@ DecoderId DecoderLibrary::add_decoder(const size_t& addr_size,
|
||||||
const size_t& data_size,
|
const size_t& data_size,
|
||||||
const bool& use_enable,
|
const bool& use_enable,
|
||||||
const bool& use_data_in,
|
const bool& use_data_in,
|
||||||
const bool& use_data_inv_port) {
|
const bool& use_data_inv_port,
|
||||||
|
const bool& use_readback) {
|
||||||
DecoderId decoder = DecoderId(decoder_ids_.size());
|
DecoderId decoder = DecoderId(decoder_ids_.size());
|
||||||
/* Push to the decoder list */
|
/* Push to the decoder list */
|
||||||
decoder_ids_.push_back(decoder);
|
decoder_ids_.push_back(decoder);
|
||||||
|
@ -102,6 +110,7 @@ DecoderId DecoderLibrary::add_decoder(const size_t& addr_size,
|
||||||
use_enable_.push_back(use_enable);
|
use_enable_.push_back(use_enable);
|
||||||
use_data_in_.push_back(use_data_in);
|
use_data_in_.push_back(use_data_in);
|
||||||
use_data_inv_port_.push_back(use_data_inv_port);
|
use_data_inv_port_.push_back(use_data_inv_port);
|
||||||
|
use_readback_.push_back(use_readback);
|
||||||
|
|
||||||
return decoder;
|
return decoder;
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,6 +50,8 @@ class DecoderLibrary {
|
||||||
bool use_data_in(const DecoderId& decoder) const;
|
bool use_data_in(const DecoderId& decoder) const;
|
||||||
/* Get the flag if a decoder includes a data_inv port which is an inversion of the regular data output port */
|
/* Get the flag if a decoder includes a data_inv port which is an inversion of the regular data output port */
|
||||||
bool use_data_inv_port(const DecoderId& decoder) const;
|
bool use_data_inv_port(const DecoderId& decoder) const;
|
||||||
|
/* Get the flag if a decoder includes a readback port which enables readback from configurable memories */
|
||||||
|
bool use_readback(const DecoderId& decoder) const;
|
||||||
/* Find a decoder to the library, with the specification.
|
/* Find a decoder to the library, with the specification.
|
||||||
* If found, return the id of decoder.
|
* If found, return the id of decoder.
|
||||||
* If not found, return an invalid id of decoder
|
* If not found, return an invalid id of decoder
|
||||||
|
@ -64,7 +66,8 @@ class DecoderLibrary {
|
||||||
const size_t& data_size,
|
const size_t& data_size,
|
||||||
const bool& use_enable,
|
const bool& use_enable,
|
||||||
const bool& use_data_in,
|
const bool& use_data_in,
|
||||||
const bool& use_data_inv_port) const;
|
const bool& use_data_inv_port,
|
||||||
|
const bool& use_readback) const;
|
||||||
|
|
||||||
public: /* Public validators */
|
public: /* Public validators */
|
||||||
/* valid ids */
|
/* valid ids */
|
||||||
|
@ -76,7 +79,8 @@ class DecoderLibrary {
|
||||||
const size_t& data_size,
|
const size_t& data_size,
|
||||||
const bool& use_enable,
|
const bool& use_enable,
|
||||||
const bool& use_data_in,
|
const bool& use_data_in,
|
||||||
const bool& use_data_inv_port);
|
const bool& use_data_inv_port,
|
||||||
|
const bool& use_readback);
|
||||||
|
|
||||||
private: /* Internal Data */
|
private: /* Internal Data */
|
||||||
vtr::vector<DecoderId, DecoderId> decoder_ids_;
|
vtr::vector<DecoderId, DecoderId> decoder_ids_;
|
||||||
|
@ -85,6 +89,7 @@ class DecoderLibrary {
|
||||||
vtr::vector<DecoderId, bool> use_enable_;
|
vtr::vector<DecoderId, bool> use_enable_;
|
||||||
vtr::vector<DecoderId, bool> use_data_in_;
|
vtr::vector<DecoderId, bool> use_data_in_;
|
||||||
vtr::vector<DecoderId, bool> use_data_inv_port_;
|
vtr::vector<DecoderId, bool> use_data_inv_port_;
|
||||||
|
vtr::vector<DecoderId, bool> use_readback_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} /* End namespace openfpga*/
|
} /* End namespace openfpga*/
|
||||||
|
|
|
@ -112,11 +112,11 @@ DecoderId add_mux_local_decoder_to_library(DecoderLibrary& decoder_lib,
|
||||||
const size_t data_size) {
|
const size_t data_size) {
|
||||||
size_t addr_size = find_mux_local_decoder_addr_size(data_size);
|
size_t addr_size = find_mux_local_decoder_addr_size(data_size);
|
||||||
|
|
||||||
DecoderId decoder_id = decoder_lib.find_decoder(addr_size, data_size, false, false, true);
|
DecoderId decoder_id = decoder_lib.find_decoder(addr_size, data_size, false, false, true, false);
|
||||||
|
|
||||||
if (DecoderId::INVALID() == decoder_id) {
|
if (DecoderId::INVALID() == decoder_id) {
|
||||||
/* Add the decoder */
|
/* Add the decoder */
|
||||||
return decoder_lib.add_decoder(addr_size, data_size, false, false, true);
|
return decoder_lib.add_decoder(addr_size, data_size, false, false, true, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* There is already a decoder in the library, return the decoder id */
|
/* There is already a decoder in the library, return the decoder id */
|
||||||
|
|
|
@ -330,7 +330,8 @@ std::vector<std::string> generate_sram_port_names(const CircuitLibrary& circuit_
|
||||||
std::vector<e_circuit_model_port_type> ports_to_search;
|
std::vector<e_circuit_model_port_type> ports_to_search;
|
||||||
ports_to_search.push_back(CIRCUIT_MODEL_PORT_BL);
|
ports_to_search.push_back(CIRCUIT_MODEL_PORT_BL);
|
||||||
ports_to_search.push_back(CIRCUIT_MODEL_PORT_WL);
|
ports_to_search.push_back(CIRCUIT_MODEL_PORT_WL);
|
||||||
/* Try to find a BL/WL/BLB/WLB port and update the port types/module port types to be added */
|
ports_to_search.push_back(CIRCUIT_MODEL_PORT_WLR);
|
||||||
|
/* Try to find a BL/WL/WLR port and update the port types/module port types to be added */
|
||||||
for (const auto& port_to_search : ports_to_search) {
|
for (const auto& port_to_search : ports_to_search) {
|
||||||
std::vector<CircuitPortId> found_port = circuit_lib.model_ports_by_type(sram_model, port_to_search);
|
std::vector<CircuitPortId> found_port = circuit_lib.model_ports_by_type(sram_model, port_to_search);
|
||||||
if (0 == found_port.size()) {
|
if (0 == found_port.size()) {
|
||||||
|
|
|
@ -195,6 +195,7 @@ ModuleId add_circuit_model_to_module_manager(ModuleManager& module_manager,
|
||||||
port_type2type_map[CIRCUIT_MODEL_PORT_BLB] = ModuleManager::MODULE_INPUT_PORT;
|
port_type2type_map[CIRCUIT_MODEL_PORT_BLB] = ModuleManager::MODULE_INPUT_PORT;
|
||||||
port_type2type_map[CIRCUIT_MODEL_PORT_WL] = ModuleManager::MODULE_INPUT_PORT;
|
port_type2type_map[CIRCUIT_MODEL_PORT_WL] = ModuleManager::MODULE_INPUT_PORT;
|
||||||
port_type2type_map[CIRCUIT_MODEL_PORT_WLB] = ModuleManager::MODULE_INPUT_PORT;
|
port_type2type_map[CIRCUIT_MODEL_PORT_WLB] = ModuleManager::MODULE_INPUT_PORT;
|
||||||
|
port_type2type_map[CIRCUIT_MODEL_PORT_WLR] = ModuleManager::MODULE_INPUT_PORT;
|
||||||
port_type2type_map[CIRCUIT_MODEL_PORT_OUTPUT] = ModuleManager::MODULE_OUTPUT_PORT;
|
port_type2type_map[CIRCUIT_MODEL_PORT_OUTPUT] = ModuleManager::MODULE_OUTPUT_PORT;
|
||||||
|
|
||||||
/* Input ports (ignore all the global ports when searching the circuit_lib */
|
/* Input ports (ignore all the global ports when searching the circuit_lib */
|
||||||
|
@ -390,8 +391,9 @@ void add_pb_sram_ports_to_module_manager(ModuleManager& module_manager,
|
||||||
for (const std::string& sram_port_name : sram_port_names) {
|
for (const std::string& sram_port_name : sram_port_names) {
|
||||||
/* Add generated ports to the ModuleManager */
|
/* Add generated ports to the ModuleManager */
|
||||||
BasicPort sram_port(sram_port_name, sram_port_size);
|
BasicPort sram_port(sram_port_name, sram_port_size);
|
||||||
/* For WL ports, we need to fine-tune it */
|
/* For WL and WLR 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))) {
|
if ( (CIRCUIT_MODEL_PORT_WL == circuit_lib.port_type(circuit_lib.model_port(sram_model, sram_port_name)))
|
||||||
|
|| (CIRCUIT_MODEL_PORT_WLR == 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));
|
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);
|
module_manager.add_port(module_id, sram_port, ModuleManager::MODULE_INPUT_PORT);
|
||||||
|
@ -885,7 +887,7 @@ void add_module_nets_between_logic_and_memory_sram_bus(ModuleManager& module_man
|
||||||
* | | |
|
* | | |
|
||||||
* +------------+----------------------+
|
* +------------+----------------------+
|
||||||
* |
|
* |
|
||||||
* WL
|
* WL/WLR
|
||||||
*
|
*
|
||||||
* Note:
|
* Note:
|
||||||
* - This function will do the connection for only one type of the port,
|
* - This function will do the connection for only one type of the port,
|
||||||
|
@ -900,15 +902,16 @@ void add_module_nets_cmos_flatten_memory_config_bus(ModuleManager& module_manage
|
||||||
/* A counter for the current pin id for the source port of parent module */
|
/* A counter for the current pin id for the source port of parent module */
|
||||||
size_t cur_src_pin_id = 0;
|
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 */
|
/* Find the port name of parent module */
|
||||||
std::string src_port_name = generate_sram_port_name(sram_orgz_type, config_port_type);
|
std::string src_port_name = generate_sram_port_name(sram_orgz_type, config_port_type);
|
||||||
net_src_module_id = parent_module;
|
ModuleId net_src_module_id = parent_module;
|
||||||
net_src_instance_id = 0;
|
size_t net_src_instance_id = 0;
|
||||||
net_src_port_id = module_manager.find_module_port(net_src_module_id, src_port_name);
|
ModulePortId net_src_port_id = module_manager.find_module_port(net_src_module_id, src_port_name);
|
||||||
|
|
||||||
|
/* We may not be able to find WLR port, return now */
|
||||||
|
if (!net_src_port_id) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* Get the pin id for source port */
|
/* Get the pin id for source port */
|
||||||
BasicPort net_src_port = module_manager.module_port(net_src_module_id, net_src_port_id);
|
BasicPort net_src_port = module_manager.module_port(net_src_module_id, net_src_port_id);
|
||||||
|
@ -1025,7 +1028,7 @@ void add_module_nets_cmos_memory_bank_bl_config_bus(ModuleManager& module_manage
|
||||||
* | | |
|
* | | |
|
||||||
* +------------+----------------------+
|
* +------------+----------------------+
|
||||||
* |
|
* |
|
||||||
* WL<0>
|
* WL<0>/WLR<0>
|
||||||
*
|
*
|
||||||
* +--------+ +--------+ +--------+
|
* +--------+ +--------+ +--------+
|
||||||
* | Memory | | Memory | ... | Memory |
|
* | Memory | | Memory | ... | Memory |
|
||||||
|
@ -1036,7 +1039,7 @@ void add_module_nets_cmos_memory_bank_bl_config_bus(ModuleManager& module_manage
|
||||||
* | | |
|
* | | |
|
||||||
* +------------+----------------------+
|
* +------------+----------------------+
|
||||||
* |
|
* |
|
||||||
* WL<1>
|
* WL<1>/WLR<1>
|
||||||
*
|
*
|
||||||
*********************************************************************/
|
*********************************************************************/
|
||||||
void add_module_nets_cmos_memory_bank_wl_config_bus(ModuleManager& module_manager,
|
void add_module_nets_cmos_memory_bank_wl_config_bus(ModuleManager& module_manager,
|
||||||
|
@ -1055,6 +1058,11 @@ void add_module_nets_cmos_memory_bank_wl_config_bus(ModuleManager& module_manage
|
||||||
ModulePortId net_src_port_id = module_manager.find_module_port(net_src_module_id, src_port_name);
|
ModulePortId net_src_port_id = module_manager.find_module_port(net_src_module_id, src_port_name);
|
||||||
ModulePortId net_bl_port_id = module_manager.find_module_port(net_src_module_id, bl_port_name);
|
ModulePortId net_bl_port_id = module_manager.find_module_port(net_src_module_id, bl_port_name);
|
||||||
|
|
||||||
|
/* We may not be able to find WLR port, return now */
|
||||||
|
if (!net_src_port_id) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* Get the pin id for source port */
|
/* Get the pin id for source port */
|
||||||
BasicPort net_src_port = module_manager.module_port(net_src_module_id, net_src_port_id);
|
BasicPort net_src_port = module_manager.module_port(net_src_module_id, net_src_port_id);
|
||||||
BasicPort net_bl_port = module_manager.module_port(net_src_module_id, net_bl_port_id);
|
BasicPort net_bl_port = module_manager.module_port(net_src_module_id, net_bl_port_id);
|
||||||
|
@ -1300,9 +1308,9 @@ void add_module_nets_cmos_memory_frame_decoder_config_bus(ModuleManager& module_
|
||||||
/* Search the decoder library and try to find one
|
/* Search the decoder library and try to find one
|
||||||
* If not found, create a new module and add it to the module manager
|
* If not found, create a new module and add it to the module manager
|
||||||
*/
|
*/
|
||||||
DecoderId decoder_id = decoder_lib.find_decoder(addr_size, data_size, true, false, false);
|
DecoderId decoder_id = decoder_lib.find_decoder(addr_size, data_size, true, false, false, false);
|
||||||
if (DecoderId::INVALID() == decoder_id) {
|
if (DecoderId::INVALID() == decoder_id) {
|
||||||
decoder_id = decoder_lib.add_decoder(addr_size, data_size, true, false, false);
|
decoder_id = decoder_lib.add_decoder(addr_size, data_size, true, false, false, false);
|
||||||
}
|
}
|
||||||
VTR_ASSERT(DecoderId::INVALID() != decoder_id);
|
VTR_ASSERT(DecoderId::INVALID() != decoder_id);
|
||||||
|
|
||||||
|
@ -1519,6 +1527,8 @@ void add_module_nets_cmos_memory_config_bus(ModuleManager& module_manager,
|
||||||
sram_orgz_type, CIRCUIT_MODEL_PORT_BL);
|
sram_orgz_type, CIRCUIT_MODEL_PORT_BL);
|
||||||
add_module_nets_cmos_flatten_memory_config_bus(module_manager, parent_module,
|
add_module_nets_cmos_flatten_memory_config_bus(module_manager, parent_module,
|
||||||
sram_orgz_type, CIRCUIT_MODEL_PORT_WL);
|
sram_orgz_type, CIRCUIT_MODEL_PORT_WL);
|
||||||
|
add_module_nets_cmos_flatten_memory_config_bus(module_manager, parent_module,
|
||||||
|
sram_orgz_type, CIRCUIT_MODEL_PORT_WLR);
|
||||||
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);
|
||||||
|
@ -1580,6 +1590,8 @@ void add_pb_module_nets_cmos_memory_config_bus(ModuleManager& module_manager,
|
||||||
sram_orgz_type, CIRCUIT_MODEL_PORT_BL);
|
sram_orgz_type, CIRCUIT_MODEL_PORT_BL);
|
||||||
add_module_nets_cmos_memory_bank_wl_config_bus(module_manager, parent_module,
|
add_module_nets_cmos_memory_bank_wl_config_bus(module_manager, parent_module,
|
||||||
sram_orgz_type, CIRCUIT_MODEL_PORT_WL);
|
sram_orgz_type, CIRCUIT_MODEL_PORT_WL);
|
||||||
|
add_module_nets_cmos_memory_bank_wl_config_bus(module_manager, parent_module,
|
||||||
|
sram_orgz_type, CIRCUIT_MODEL_PORT_WLR);
|
||||||
break;
|
break;
|
||||||
case CONFIG_MEM_MEMORY_BANK:
|
case CONFIG_MEM_MEMORY_BANK:
|
||||||
add_module_nets_cmos_flatten_memory_config_bus(module_manager, parent_module,
|
add_module_nets_cmos_flatten_memory_config_bus(module_manager, parent_module,
|
||||||
|
|
Loading…
Reference in New Issue