From 19a551e6416c4f3bcb9bcf19265700ea8c42d692 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Sat, 9 Oct 2021 16:44:04 -0700 Subject: [PATCH] [Engine] Upgrade fabric generator to support multiple shift register banks in a configuration region --- openfpga/src/fabric/build_top_module.cpp | 1 + .../src/fabric/build_top_module_memory.cpp | 3 +- openfpga/src/fabric/build_top_module_memory.h | 1 + .../fabric/build_top_module_memory_bank.cpp | 435 +++++++++++------- .../src/fabric/build_top_module_memory_bank.h | 1 + .../memory_bank_shift_register_banks.cpp | 402 ++++++++-------- .../fabric/memory_bank_shift_register_banks.h | 216 +++++---- .../verilog_shift_register_banks.cpp | 4 +- 8 files changed, 574 insertions(+), 489 deletions(-) diff --git a/openfpga/src/fabric/build_top_module.cpp b/openfpga/src/fabric/build_top_module.cpp index b0ab747a8..2aad3f1f4 100644 --- a/openfpga/src/fabric/build_top_module.cpp +++ b/openfpga/src/fabric/build_top_module.cpp @@ -421,6 +421,7 @@ int build_top_module(ModuleManager& module_manager, add_top_module_sram_ports(module_manager, top_module, circuit_lib, sram_model, config_protocol, + const_cast(blwl_sr_banks), top_module_num_config_bits); } diff --git a/openfpga/src/fabric/build_top_module_memory.cpp b/openfpga/src/fabric/build_top_module_memory.cpp index 9da2a3641..aee05c61c 100644 --- a/openfpga/src/fabric/build_top_module_memory.cpp +++ b/openfpga/src/fabric/build_top_module_memory.cpp @@ -807,6 +807,7 @@ void add_top_module_sram_ports(ModuleManager& module_manager, const CircuitLibrary& circuit_lib, const CircuitModelId& sram_model, const ConfigProtocol& config_protocol, + const MemoryBankShiftRegisterBanks& blwl_sr_banks, const TopModuleNumConfigBits& num_config_bits) { std::vector sram_port_names = generate_sram_port_names(circuit_lib, sram_model, config_protocol.type()); size_t total_num_config_bits = 0; @@ -852,7 +853,7 @@ void add_top_module_sram_ports(ModuleManager& module_manager, break; } case CONFIG_MEM_QL_MEMORY_BANK: { - add_top_module_ql_memory_bank_sram_ports(module_manager, module_id, circuit_lib, config_protocol, num_config_bits); + add_top_module_ql_memory_bank_sram_ports(module_manager, module_id, circuit_lib, config_protocol, blwl_sr_banks, num_config_bits); break; } case CONFIG_MEM_SCAN_CHAIN: { diff --git a/openfpga/src/fabric/build_top_module_memory.h b/openfpga/src/fabric/build_top_module_memory.h index be4589490..244f6bfee 100644 --- a/openfpga/src/fabric/build_top_module_memory.h +++ b/openfpga/src/fabric/build_top_module_memory.h @@ -61,6 +61,7 @@ void add_top_module_sram_ports(ModuleManager& module_manager, const CircuitLibrary& circuit_lib, const CircuitModelId& sram_model, const ConfigProtocol& config_protocol, + const MemoryBankShiftRegisterBanks& blwl_sr_banks, const TopModuleNumConfigBits& num_config_bits); void add_top_module_nets_memory_config_bus(ModuleManager& module_manager, diff --git a/openfpga/src/fabric/build_top_module_memory_bank.cpp b/openfpga/src/fabric/build_top_module_memory_bank.cpp index 0a3186453..900eb8bb3 100644 --- a/openfpga/src/fabric/build_top_module_memory_bank.cpp +++ b/openfpga/src/fabric/build_top_module_memory_bank.cpp @@ -1073,49 +1073,36 @@ void add_top_module_nets_cmos_ql_memory_bank_wl_flatten_config_bus(ModuleManager /********************************************************************* * This function to add nets for QuickLogic memory bank - * We build the net connects between the head ports of shift register banks + * We build the net connects between the head ports of BL shift register banks * and the head ports of top-level module - * @note This function is applicable to both BL and WL shift registers **********************************************************************/ static -void add_top_module_nets_cmos_ql_memory_bank_shift_register_bank_heads(ModuleManager& module_manager, - const ModuleId& top_module, - const MemoryBankShiftRegisterBanks& sr_banks, - const std::string& head_port_name) { - for (const ConfigRegionId& config_region : module_manager.regions(top_module)) { - ModulePortId blsr_head_port = module_manager.find_module_port(top_module, generate_regional_blwl_port_name(head_port_name, config_region)); - BasicPort blsr_head_port_info = module_manager.module_port(top_module, blsr_head_port); +void add_top_module_nets_cmos_ql_memory_bank_bl_shift_register_bank_heads(ModuleManager& module_manager, + const ModuleId& top_module, + const MemoryBankShiftRegisterBanks& sr_banks) { + std::string head_port_name(BL_SHIFT_REGISTER_CHAIN_HEAD_NAME); - size_t num_sr_bank_modules; - if (std::string(BL_SHIFT_REGISTER_CHAIN_HEAD_NAME) == head_port_name) { - num_sr_bank_modules = sr_banks.bl_shift_register_bank_modules(config_region).size(); - } else { - VTR_ASSERT(std::string(WL_SHIFT_REGISTER_CHAIN_HEAD_NAME) == head_port_name); - num_sr_bank_modules = sr_banks.wl_shift_register_bank_modules(config_region).size(); - } - for (size_t iinst = 0; iinst < num_sr_bank_modules; ++iinst) { - ModuleId sr_bank_module; - size_t sr_bank_instance; - if (std::string(BL_SHIFT_REGISTER_CHAIN_HEAD_NAME) == head_port_name) { - sr_bank_module = sr_banks.bl_shift_register_bank_modules(config_region)[iinst]; - sr_bank_instance = sr_banks.bl_shift_register_bank_instances(config_region)[iinst]; - } else { - VTR_ASSERT(std::string(WL_SHIFT_REGISTER_CHAIN_HEAD_NAME) == head_port_name); - sr_bank_module = sr_banks.wl_shift_register_bank_modules(config_region)[iinst]; - sr_bank_instance = sr_banks.wl_shift_register_bank_instances(config_region)[iinst]; - } + for (const ConfigRegionId& config_region : module_manager.regions(top_module)) { + ModulePortId sr_head_port = module_manager.find_module_port(top_module, generate_regional_blwl_port_name(head_port_name, config_region)); + BasicPort sr_head_port_info = module_manager.module_port(top_module, sr_head_port); + + /* Iterate over each shift register banks */ + for (const auto& bank : sr_banks.bl_banks(config_region)) { + /* Get the module and instance ids */ + ModuleId sr_bank_module = sr_banks.bl_shift_register_bank_module(config_region, bank); + size_t sr_bank_instance = sr_banks.bl_shift_register_bank_instance(config_region, bank); VTR_ASSERT(sr_bank_module); ModulePortId sr_module_head_port = module_manager.find_module_port(sr_bank_module, head_port_name); BasicPort sr_module_head_port_info = module_manager.module_port(sr_bank_module, sr_module_head_port); - VTR_ASSERT(sr_module_head_port_info.get_width() == blsr_head_port_info.get_width()); + VTR_ASSERT(sr_module_head_port_info.get_width() == 1); for (size_t ipin = 0; ipin < sr_module_head_port_info.pins().size(); ++ipin) { /* Create net */ ModuleNetId net = create_module_source_pin_net(module_manager, top_module, top_module, 0, - blsr_head_port, - blsr_head_port_info.pins()[ipin]); + sr_head_port, + sr_head_port_info.pins()[size_t(bank)]); VTR_ASSERT(ModuleNetId::INVALID() != net); /* Add net sink */ @@ -1128,41 +1115,70 @@ void add_top_module_nets_cmos_ql_memory_bank_shift_register_bank_heads(ModuleMan /********************************************************************* * This function to add nets for QuickLogic memory bank - * We build the net connects between the head ports of shift register banks + * We build the net connects between the head ports of BL shift register banks * and the head ports of top-level module - * @note This function is applicable to both BL and WL shift registers **********************************************************************/ static -void add_top_module_nets_cmos_ql_memory_bank_shift_register_bank_tails(ModuleManager& module_manager, - const ModuleId& top_module, - const MemoryBankShiftRegisterBanks& sr_banks, - const std::string& tail_port_name) { - for (const ConfigRegionId& config_region : module_manager.regions(top_module)) { - ModulePortId blsr_tail_port = module_manager.find_module_port(top_module, generate_regional_blwl_port_name(tail_port_name, config_region)); - BasicPort blsr_tail_port_info = module_manager.module_port(top_module, blsr_tail_port); +void add_top_module_nets_cmos_ql_memory_bank_wl_shift_register_bank_heads(ModuleManager& module_manager, + const ModuleId& top_module, + const MemoryBankShiftRegisterBanks& sr_banks) { + std::string head_port_name(WL_SHIFT_REGISTER_CHAIN_HEAD_NAME); - size_t num_sr_bank_modules; - if (std::string(BL_SHIFT_REGISTER_CHAIN_TAIL_NAME) == tail_port_name) { - num_sr_bank_modules = sr_banks.bl_shift_register_bank_modules(config_region).size(); - } else { - VTR_ASSERT(std::string(WL_SHIFT_REGISTER_CHAIN_TAIL_NAME) == tail_port_name); - num_sr_bank_modules = sr_banks.wl_shift_register_bank_modules(config_region).size(); - } - for (size_t iinst = 0; iinst < num_sr_bank_modules; ++iinst) { - ModuleId sr_bank_module; - size_t sr_bank_instance; - if (std::string(BL_SHIFT_REGISTER_CHAIN_TAIL_NAME) == tail_port_name) { - sr_bank_module = sr_banks.bl_shift_register_bank_modules(config_region)[iinst]; - sr_bank_instance = sr_banks.bl_shift_register_bank_instances(config_region)[iinst]; - } else { - VTR_ASSERT(std::string(WL_SHIFT_REGISTER_CHAIN_TAIL_NAME) == tail_port_name); - sr_bank_module = sr_banks.wl_shift_register_bank_modules(config_region)[iinst]; - sr_bank_instance = sr_banks.wl_shift_register_bank_instances(config_region)[iinst]; + for (const ConfigRegionId& config_region : module_manager.regions(top_module)) { + ModulePortId sr_head_port = module_manager.find_module_port(top_module, generate_regional_blwl_port_name(head_port_name, config_region)); + BasicPort sr_head_port_info = module_manager.module_port(top_module, sr_head_port); + + /* Iterate over each shift register banks */ + for (const auto& bank : sr_banks.wl_banks(config_region)) { + /* Get the module and instance ids */ + ModuleId sr_bank_module = sr_banks.wl_shift_register_bank_module(config_region, bank); + size_t sr_bank_instance = sr_banks.wl_shift_register_bank_instance(config_region, bank); + + VTR_ASSERT(sr_bank_module); + + ModulePortId sr_module_head_port = module_manager.find_module_port(sr_bank_module, head_port_name); + BasicPort sr_module_head_port_info = module_manager.module_port(sr_bank_module, sr_module_head_port); + VTR_ASSERT(sr_module_head_port_info.get_width() == 1); + for (size_t ipin = 0; ipin < sr_module_head_port_info.pins().size(); ++ipin) { + /* Create net */ + ModuleNetId net = create_module_source_pin_net(module_manager, top_module, + top_module, 0, + sr_head_port, + sr_head_port_info.pins()[size_t(bank)]); + VTR_ASSERT(ModuleNetId::INVALID() != net); + + /* Add net sink */ + module_manager.add_module_net_sink(top_module, net, + sr_bank_module, sr_bank_instance, sr_module_head_port, sr_module_head_port_info.pins()[ipin]); } + } + } +} + +/********************************************************************* + * This function to add nets for QuickLogic memory bank + * We build the net connects between the tail ports of BL shift register banks + * and the tail ports of top-level module + **********************************************************************/ +static +void add_top_module_nets_cmos_ql_memory_bank_bl_shift_register_bank_tails(ModuleManager& module_manager, + const ModuleId& top_module, + const MemoryBankShiftRegisterBanks& sr_banks) { + std::string tail_port_name(BL_SHIFT_REGISTER_CHAIN_TAIL_NAME); + for (const ConfigRegionId& config_region : module_manager.regions(top_module)) { + ModulePortId sr_tail_port = module_manager.find_module_port(top_module, generate_regional_blwl_port_name(tail_port_name, config_region)); + BasicPort sr_tail_port_info = module_manager.module_port(top_module, sr_tail_port); + + /* Iterate over each shift register banks */ + for (const auto& bank : sr_banks.bl_banks(config_region)) { + /* Get the module and instance ids */ + ModuleId sr_bank_module = sr_banks.bl_shift_register_bank_module(config_region, bank); + size_t sr_bank_instance = sr_banks.bl_shift_register_bank_instance(config_region, bank); + VTR_ASSERT(sr_bank_module); ModulePortId sr_module_tail_port = module_manager.find_module_port(sr_bank_module, tail_port_name); BasicPort sr_module_tail_port_info = module_manager.module_port(sr_bank_module, sr_module_tail_port); - VTR_ASSERT(sr_module_tail_port_info.get_width() == blsr_tail_port_info.get_width()); + VTR_ASSERT(sr_module_tail_port_info.get_width() == 1); for (size_t ipin = 0; ipin < sr_module_tail_port_info.pins().size(); ++ipin) { /* Create net */ ModuleNetId net = create_module_source_pin_net(module_manager, top_module, @@ -1173,7 +1189,47 @@ void add_top_module_nets_cmos_ql_memory_bank_shift_register_bank_tails(ModuleMan /* Add net sink */ module_manager.add_module_net_sink(top_module, net, top_module, 0, - blsr_tail_port, blsr_tail_port_info.pins()[ipin]); + sr_tail_port, sr_tail_port_info.pins()[size_t(bank)]); + } + } + } +} + +/********************************************************************* + * This function to add nets for QuickLogic memory bank + * We build the net connects between the tail ports of WL shift register banks + * and the tail ports of top-level module + **********************************************************************/ +static +void add_top_module_nets_cmos_ql_memory_bank_wl_shift_register_bank_tails(ModuleManager& module_manager, + const ModuleId& top_module, + const MemoryBankShiftRegisterBanks& sr_banks) { + std::string tail_port_name(WL_SHIFT_REGISTER_CHAIN_TAIL_NAME); + for (const ConfigRegionId& config_region : module_manager.regions(top_module)) { + ModulePortId sr_tail_port = module_manager.find_module_port(top_module, generate_regional_blwl_port_name(tail_port_name, config_region)); + BasicPort sr_tail_port_info = module_manager.module_port(top_module, sr_tail_port); + + /* Iterate over each shift register banks */ + for (const auto& bank : sr_banks.wl_banks(config_region)) { + /* Get the module and instance ids */ + ModuleId sr_bank_module = sr_banks.wl_shift_register_bank_module(config_region, bank); + size_t sr_bank_instance = sr_banks.wl_shift_register_bank_instance(config_region, bank); + VTR_ASSERT(sr_bank_module); + + ModulePortId sr_module_tail_port = module_manager.find_module_port(sr_bank_module, tail_port_name); + BasicPort sr_module_tail_port_info = module_manager.module_port(sr_bank_module, sr_module_tail_port); + VTR_ASSERT(sr_module_tail_port_info.get_width() == 1); + for (size_t ipin = 0; ipin < sr_module_tail_port_info.pins().size(); ++ipin) { + /* Create net */ + ModuleNetId net = create_module_source_pin_net(module_manager, top_module, + sr_bank_module, sr_bank_instance, + sr_module_tail_port, sr_module_tail_port_info.pins()[ipin]); + VTR_ASSERT(ModuleNetId::INVALID() != net); + + /* Add net sink */ + module_manager.add_module_net_sink(top_module, net, + top_module, 0, + sr_tail_port, sr_tail_port_info.pins()[size_t(bank)]); } } } @@ -1206,32 +1262,18 @@ void add_top_module_nets_cmos_ql_memory_bank_shift_register_bank_tails(ModuleMan * @note optional BL/WL is applicable to WLR, which may not always exist */ static -void add_top_module_nets_cmos_ql_memory_bank_shift_register_bank_blwls(ModuleManager& module_manager, - const ModuleId& top_module, - const MemoryBankShiftRegisterBanks& sr_banks, - const std::string& sr_blwl_port_name, - const std::string& child_blwl_port_name, - const bool& optional_blwl = false) { +void add_top_module_nets_cmos_ql_memory_bank_bl_shift_register_bank_bls(ModuleManager& module_manager, + const ModuleId& top_module, + const MemoryBankShiftRegisterBanks& sr_banks, + const std::string sr_blwl_port_name, + const std::string& child_blwl_port_name, + const bool& optional_blwl = false) { for (const ConfigRegionId& config_region : module_manager.regions(top_module)) { - size_t num_sr_bank_modules; - if (std::string(BL_SHIFT_REGISTER_CHAIN_BL_OUT_NAME) == sr_blwl_port_name) { - num_sr_bank_modules = sr_banks.bl_shift_register_bank_modules(config_region).size(); - } else { - VTR_ASSERT(std::string(WL_SHIFT_REGISTER_CHAIN_WL_OUT_NAME) == sr_blwl_port_name); - num_sr_bank_modules = sr_banks.wl_shift_register_bank_modules(config_region).size(); - } - for (size_t iinst = 0; iinst < num_sr_bank_modules; ++iinst) { - ModuleId sr_bank_module; - size_t sr_bank_instance; - if (std::string(BL_SHIFT_REGISTER_CHAIN_BL_OUT_NAME) == sr_blwl_port_name) { - sr_bank_module = sr_banks.bl_shift_register_bank_modules(config_region)[iinst]; - sr_bank_instance = sr_banks.bl_shift_register_bank_instances(config_region)[iinst]; - } else { - VTR_ASSERT(std::string(WL_SHIFT_REGISTER_CHAIN_WL_OUT_NAME) == sr_blwl_port_name); - sr_bank_module = sr_banks.wl_shift_register_bank_modules(config_region)[iinst]; - sr_bank_instance = sr_banks.wl_shift_register_bank_instances(config_region)[iinst]; - } - + /* Iterate over each shift register banks */ + for (const auto& bank : sr_banks.bl_banks(config_region)) { + /* Get the module and instance ids */ + ModuleId sr_bank_module = sr_banks.bl_shift_register_bank_module(config_region, bank); + size_t sr_bank_instance = sr_banks.bl_shift_register_bank_instance(config_region, bank); VTR_ASSERT(sr_bank_module); ModulePortId sr_module_blwl_port = module_manager.find_module_port(sr_bank_module, sr_blwl_port_name); @@ -1241,23 +1283,8 @@ void add_top_module_nets_cmos_ql_memory_bank_shift_register_bank_blwls(ModuleMan VTR_ASSERT(sr_module_blwl_port); BasicPort sr_module_blwl_port_info = module_manager.module_port(sr_bank_module, sr_module_blwl_port); - size_t num_sink_child_ids; - if (std::string(BL_SHIFT_REGISTER_CHAIN_BL_OUT_NAME) == sr_blwl_port_name) { - num_sink_child_ids = sr_banks.bl_shift_register_bank_sink_child_ids(config_region, sr_bank_module, sr_bank_instance).size(); - } else { - VTR_ASSERT(std::string(WL_SHIFT_REGISTER_CHAIN_WL_OUT_NAME) == sr_blwl_port_name); - num_sink_child_ids = sr_banks.wl_shift_register_bank_sink_child_ids(config_region, sr_bank_module, sr_bank_instance).size(); - } - - for (size_t sink_id = 0; sink_id < num_sink_child_ids; ++sink_id) { - size_t child_id; - if (std::string(BL_SHIFT_REGISTER_CHAIN_BL_OUT_NAME) == sr_blwl_port_name) { - child_id = sr_banks.bl_shift_register_bank_sink_child_ids(config_region, sr_bank_module, sr_bank_instance)[sink_id]; - } else { - VTR_ASSERT(std::string(WL_SHIFT_REGISTER_CHAIN_WL_OUT_NAME) == sr_blwl_port_name); - child_id = sr_banks.wl_shift_register_bank_sink_child_ids(config_region, sr_bank_module, sr_bank_instance)[sink_id]; - } - + for (const BasicPort& src_port : sr_banks.bl_shift_register_bank_source_ports(config_region, bank)) { + size_t child_id = sr_banks.bl_shift_register_bank_sink_child_id(config_region, bank, src_port); ModuleId child_module = module_manager.region_configurable_children(top_module, config_region)[child_id]; size_t child_instance = module_manager.region_configurable_child_instances(top_module, config_region)[child_id]; @@ -1265,32 +1292,93 @@ void add_top_module_nets_cmos_ql_memory_bank_shift_register_bank_blwls(ModuleMan ModulePortId child_blwl_port = module_manager.find_module_port(child_module, child_blwl_port_name); BasicPort child_blwl_port_info = module_manager.module_port(child_module, child_blwl_port); - size_t cur_sr_module_blwl_pin_id; - if (std::string(BL_SHIFT_REGISTER_CHAIN_BL_OUT_NAME) == sr_blwl_port_name) { - cur_sr_module_blwl_pin_id = sr_banks.bl_shift_register_bank_source_blwl_ids(config_region, sr_bank_module, sr_bank_instance)[sink_id]; - } else { - VTR_ASSERT(std::string(WL_SHIFT_REGISTER_CHAIN_WL_OUT_NAME) == sr_blwl_port_name); - cur_sr_module_blwl_pin_id = sr_banks.wl_shift_register_bank_source_blwl_ids(config_region, sr_bank_module, sr_bank_instance)[sink_id]; - } - + VTR_ASSERT(1 == src_port.get_width()); /* Create net */ ModuleNetId net = create_module_source_pin_net(module_manager, top_module, sr_bank_module, sr_bank_instance, sr_module_blwl_port, - sr_module_blwl_port_info.pins()[cur_sr_module_blwl_pin_id]); + src_port.pins()[0]); VTR_ASSERT(ModuleNetId::INVALID() != net); /* Add net sink */ - size_t sink_pin_id; - if (std::string(BL_SHIFT_REGISTER_CHAIN_BL_OUT_NAME) == sr_blwl_port_name) { - sink_pin_id = sr_banks.bl_shift_register_bank_sink_pin_ids(config_region, sr_bank_module, sr_bank_instance)[sink_id]; - } else { - VTR_ASSERT(std::string(WL_SHIFT_REGISTER_CHAIN_WL_OUT_NAME) == sr_blwl_port_name); - sink_pin_id = sr_banks.wl_shift_register_bank_sink_pin_ids(config_region, sr_bank_module, sr_bank_instance)[sink_id]; - } - + size_t sink_child_pin_id = sr_banks.bl_shift_register_bank_sink_child_pin_id(config_region, bank, src_port); module_manager.add_module_net_sink(top_module, net, - child_module, child_instance, child_blwl_port, sink_pin_id); + child_module, child_instance, child_blwl_port, sink_child_pin_id); + } + } + } +} + + +/************************************************************** + * Add BL/WL nets from shift register module to each configurable child + * BL pins of shift register module are connected to the BL input pins of each PB/CB/SB + * For all the PB/CB/SB in the same column, they share the same set of BLs + * A quick example + * + * +-----------------------+ + * | Shift register chain | + * +-----------------------+ + * BL[i .. i + sqrt(N)] + * | + * | CLB[1][H] + * | +---------+ + * | | SRAM | + * +-->| [0..N] | + * | +---------+ + * | + * ... + * | CLB[1][1] + * | +---------+ + * | | SRAM | + * +-->| [0..N] | + * | +---------+ + * | + * @note optional BL/WL is applicable to WLR, which may not always exist + */ +static +void add_top_module_nets_cmos_ql_memory_bank_wl_shift_register_bank_wls(ModuleManager& module_manager, + const ModuleId& top_module, + const MemoryBankShiftRegisterBanks& sr_banks, + const std::string sr_blwl_port_name, + const std::string& child_blwl_port_name, + const bool& optional_blwl = false) { + for (const ConfigRegionId& config_region : module_manager.regions(top_module)) { + /* Iterate over each shift register banks */ + for (const auto& bank : sr_banks.wl_banks(config_region)) { + /* Get the module and instance ids */ + ModuleId sr_bank_module = sr_banks.wl_shift_register_bank_module(config_region, bank); + size_t sr_bank_instance = sr_banks.wl_shift_register_bank_instance(config_region, bank); + VTR_ASSERT(sr_bank_module); + + ModulePortId sr_module_blwl_port = module_manager.find_module_port(sr_bank_module, sr_blwl_port_name); + if (!sr_module_blwl_port && optional_blwl) { + continue; + } + VTR_ASSERT(sr_module_blwl_port); + BasicPort sr_module_blwl_port_info = module_manager.module_port(sr_bank_module, sr_module_blwl_port); + + for (const BasicPort& src_port : sr_banks.wl_shift_register_bank_source_ports(config_region, bank)) { + size_t child_id = sr_banks.wl_shift_register_bank_sink_child_id(config_region, bank, src_port); + ModuleId child_module = module_manager.region_configurable_children(top_module, config_region)[child_id]; + size_t child_instance = module_manager.region_configurable_child_instances(top_module, config_region)[child_id]; + + /* Find the BL port */ + ModulePortId child_blwl_port = module_manager.find_module_port(child_module, child_blwl_port_name); + BasicPort child_blwl_port_info = module_manager.module_port(child_module, child_blwl_port); + + VTR_ASSERT(1 == src_port.get_width()); + /* Create net */ + ModuleNetId net = create_module_source_pin_net(module_manager, top_module, + sr_bank_module, sr_bank_instance, + sr_module_blwl_port, + src_port.pins()[0]); + VTR_ASSERT(ModuleNetId::INVALID() != net); + + /* Add net sink */ + size_t sink_child_pin_id = sr_banks.wl_shift_register_bank_sink_child_pin_id(config_region, bank, src_port); + module_manager.add_module_net_sink(top_module, net, + child_module, child_instance, child_blwl_port, sink_child_pin_id); } } } @@ -1358,15 +1446,7 @@ void add_top_module_nets_cmos_ql_memory_bank_bl_shift_register_config_bus(Module CircuitModelId sram_model = config_protocol.memory_model(); CircuitModelId bl_memory_model = config_protocol.bl_memory_model(); /* Find out the unique shift register chain sizes */ - vtr::vector unique_sr_sizes; - unique_sr_sizes.resize(module_manager.regions(top_module).size()); - for (const ConfigRegionId& config_region : module_manager.regions(top_module)) { - /* TODO: Need to find how to cut the BLs when there are multiple banks for shift registers in a region */ - size_t num_bls = compute_memory_bank_regional_num_bls(module_manager, top_module, - config_region, - circuit_lib, sram_model); - unique_sr_sizes[config_region] = num_bls; - } + std::vector unique_sr_sizes = sr_banks.bl_bank_unique_sizes(); /* Build submodules for shift register chains */ for (const size_t& sr_size : unique_sr_sizes) { @@ -1379,17 +1459,22 @@ void add_top_module_nets_cmos_ql_memory_bank_bl_shift_register_config_bus(Module } /* Instanciate the shift register chains in the top-level module */ - sr_banks.resize_regions(module_manager.regions(top_module).size()); for (const ConfigRegionId& config_region : module_manager.regions(top_module)) { - std::string sr_module_name = generate_bl_shift_register_module_name(circuit_lib.model_name(bl_memory_model), unique_sr_sizes[config_region]); - ModuleId sr_bank_module = module_manager.find_module(sr_module_name); - VTR_ASSERT(sr_bank_module); + for (const FabricBitLineBankId& sr_bank : sr_banks.bl_banks(config_region)) { + size_t bl_bank_size = sr_banks.bl_bank_size(config_region, sr_bank); + std::string sr_module_name = generate_bl_shift_register_module_name(circuit_lib.model_name(bl_memory_model), bl_bank_size); + ModuleId sr_bank_module = module_manager.find_module(sr_module_name); + VTR_ASSERT(sr_bank_module); - size_t cur_inst = module_manager.num_instance(top_module, sr_bank_module); - module_manager.add_child_module(top_module, sr_bank_module); + size_t cur_inst = module_manager.num_instance(top_module, sr_bank_module); + module_manager.add_child_module(top_module, sr_bank_module); - sr_banks.add_bl_shift_register_instance(config_region, sr_bank_module, cur_inst); + sr_banks.link_bl_shift_register_bank_to_module(config_region, sr_bank, sr_bank_module); + sr_banks.link_bl_shift_register_bank_to_instance(config_region, sr_bank, cur_inst); + } + } + for (const ConfigRegionId& config_region : module_manager.regions(top_module)) { /************************************************************** * 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 @@ -1411,10 +1496,13 @@ void add_top_module_nets_cmos_ql_memory_bank_bl_shift_register_config_bus(Module size_t cur_bl_index = 0; for (const size_t& sink_bl_pin : child_bl_port_info.pins()) { + /* Find the shift register bank id for the driving BL port */ size_t bl_pin_id = bl_start_index_per_tile[coord.x()] + cur_bl_index; + BasicPort src_bl_port(std::string(MEMORY_BL_PORT_NAME), bl_pin_id, bl_pin_id); + FabricBitLineBankId sr_bank = sr_banks.find_bl_shift_register_bank_id(config_region, src_bl_port); + BasicPort sr_bank_port = sr_banks.find_bl_shift_register_bank_data_port(config_region, src_bl_port); - sr_banks.add_bl_shift_register_sink_nodes(config_region, sr_bank_module, cur_inst, child_id, sink_bl_pin); - sr_banks.add_bl_shift_register_source_blwls(config_region, sr_bank_module, cur_inst, bl_pin_id); + sr_banks.add_bl_shift_register_bank_sink_node(config_region, sr_bank, sr_bank_port, child_id, sink_bl_pin); cur_bl_index++; } @@ -1425,16 +1513,14 @@ void add_top_module_nets_cmos_ql_memory_bank_bl_shift_register_config_bus(Module * - Connect the head port from top-level module to each shift register bank * - Connect the tail port from each shift register bank to top-level module */ - add_top_module_nets_cmos_ql_memory_bank_shift_register_bank_heads(module_manager, top_module, sr_banks, - std::string(BL_SHIFT_REGISTER_CHAIN_HEAD_NAME)); + add_top_module_nets_cmos_ql_memory_bank_bl_shift_register_bank_heads(module_manager, top_module, sr_banks); - add_top_module_nets_cmos_ql_memory_bank_shift_register_bank_tails(module_manager, top_module, sr_banks, - std::string(BL_SHIFT_REGISTER_CHAIN_TAIL_NAME)); + add_top_module_nets_cmos_ql_memory_bank_bl_shift_register_bank_tails(module_manager, top_module, sr_banks); /* Create connections between BLs of top-level module and BLs of child modules for each region */ - add_top_module_nets_cmos_ql_memory_bank_shift_register_bank_blwls(module_manager, top_module, sr_banks, - std::string(BL_SHIFT_REGISTER_CHAIN_BL_OUT_NAME), - std::string(MEMORY_BL_PORT_NAME)); + add_top_module_nets_cmos_ql_memory_bank_bl_shift_register_bank_bls(module_manager, top_module, sr_banks, + std::string(BL_SHIFT_REGISTER_CHAIN_BL_OUT_NAME), + std::string(MEMORY_BL_PORT_NAME)); } /********************************************************************* @@ -1453,16 +1539,9 @@ void add_top_module_nets_cmos_ql_memory_bank_wl_shift_register_config_bus(Module CircuitModelId sram_model = config_protocol.memory_model(); CircuitModelId wl_memory_model = config_protocol.wl_memory_model(); /* Find out the unique shift register chain sizes */ - vtr::vector unique_sr_sizes; - for (const ConfigRegionId& config_region : module_manager.regions(top_module)) { - /* TODO: Need to find how to cut the BLs when there are multiple banks for shift registers in a region */ - size_t num_wls = compute_memory_bank_regional_num_wls(module_manager, top_module, - config_region, - circuit_lib, sram_model); - unique_sr_sizes.push_back(num_wls); - } + std::vector unique_sr_sizes = sr_banks.wl_bank_unique_sizes(); - /* TODO: Build submodules for shift register chains */ + /* Build submodules for shift register chains */ for (const size_t& sr_size : unique_sr_sizes) { std::string sr_module_name = generate_wl_shift_register_module_name(circuit_lib.model_name(wl_memory_model), sr_size); build_wl_shift_register_chain_module(module_manager, @@ -1473,17 +1552,22 @@ void add_top_module_nets_cmos_ql_memory_bank_wl_shift_register_config_bus(Module } /* Instanciate the shift register chains in the top-level module */ - sr_banks.resize_regions(module_manager.regions(top_module).size()); for (const ConfigRegionId& config_region : module_manager.regions(top_module)) { - std::string sr_module_name = generate_wl_shift_register_module_name(circuit_lib.model_name(wl_memory_model), unique_sr_sizes[config_region]); - ModuleId sr_bank_module = module_manager.find_module(sr_module_name); - VTR_ASSERT(sr_bank_module); + for (const FabricWordLineBankId& sr_bank : sr_banks.wl_banks(config_region)) { + size_t wl_bank_size = sr_banks.wl_bank_size(config_region, sr_bank); + std::string sr_module_name = generate_bl_shift_register_module_name(circuit_lib.model_name(wl_memory_model), wl_bank_size); + ModuleId sr_bank_module = module_manager.find_module(sr_module_name); + VTR_ASSERT(sr_bank_module); - size_t cur_inst = module_manager.num_instance(top_module, sr_bank_module); - module_manager.add_child_module(top_module, sr_bank_module); + size_t cur_inst = module_manager.num_instance(top_module, sr_bank_module); + module_manager.add_child_module(top_module, sr_bank_module); - sr_banks.add_wl_shift_register_instance(config_region, sr_bank_module, cur_inst); + sr_banks.link_wl_shift_register_bank_to_module(config_region, sr_bank, sr_bank_module); + sr_banks.link_wl_shift_register_bank_to_instance(config_region, sr_bank, cur_inst); + } + } + for (const ConfigRegionId& config_region : module_manager.regions(top_module)) { /************************************************************** * 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 @@ -1506,8 +1590,12 @@ void add_top_module_nets_cmos_ql_memory_bank_wl_shift_register_config_bus(Module for (const size_t& sink_wl_pin : child_wl_port_info.pins()) { size_t wl_pin_id = wl_start_index_per_tile[coord.y()] + cur_wl_index; - sr_banks.add_wl_shift_register_sink_nodes(config_region, sr_bank_module, cur_inst, child_id, sink_wl_pin); - sr_banks.add_wl_shift_register_source_blwls(config_region, sr_bank_module, cur_inst, wl_pin_id); + BasicPort src_wl_port(std::string(MEMORY_WL_PORT_NAME), wl_pin_id, wl_pin_id); + + FabricWordLineBankId sr_bank = sr_banks.find_wl_shift_register_bank_id(config_region, src_wl_port); + BasicPort sr_bank_port = sr_banks.find_wl_shift_register_bank_data_port(config_region, src_wl_port); + + sr_banks.add_wl_shift_register_bank_sink_node(config_region, sr_bank, sr_bank_port, child_id, sink_wl_pin); cur_wl_index++; } @@ -1518,20 +1606,18 @@ void add_top_module_nets_cmos_ql_memory_bank_wl_shift_register_config_bus(Module * - Connect the head port from top-level module to each shift register bank * - Connect the tail port from each shift register bank to top-level module */ - add_top_module_nets_cmos_ql_memory_bank_shift_register_bank_heads(module_manager, top_module, sr_banks, - std::string(WL_SHIFT_REGISTER_CHAIN_HEAD_NAME)); + add_top_module_nets_cmos_ql_memory_bank_wl_shift_register_bank_heads(module_manager, top_module, sr_banks); - add_top_module_nets_cmos_ql_memory_bank_shift_register_bank_tails(module_manager, top_module, sr_banks, - std::string(WL_SHIFT_REGISTER_CHAIN_TAIL_NAME)); + add_top_module_nets_cmos_ql_memory_bank_wl_shift_register_bank_tails(module_manager, top_module, sr_banks); /* Create connections between BLs of top-level module and BLs of child modules for each region */ - add_top_module_nets_cmos_ql_memory_bank_shift_register_bank_blwls(module_manager, top_module, sr_banks, - std::string(WL_SHIFT_REGISTER_CHAIN_WL_OUT_NAME), - std::string(MEMORY_WL_PORT_NAME)); - add_top_module_nets_cmos_ql_memory_bank_shift_register_bank_blwls(module_manager, top_module, sr_banks, - std::string(WL_SHIFT_REGISTER_CHAIN_WLR_OUT_NAME), - std::string(MEMORY_WLR_PORT_NAME), - true); + add_top_module_nets_cmos_ql_memory_bank_wl_shift_register_bank_wls(module_manager, top_module, sr_banks, + std::string(WL_SHIFT_REGISTER_CHAIN_WL_OUT_NAME), + std::string(MEMORY_WL_PORT_NAME)); + add_top_module_nets_cmos_ql_memory_bank_wl_shift_register_bank_wls(module_manager, top_module, sr_banks, + std::string(WL_SHIFT_REGISTER_CHAIN_WLR_OUT_NAME), + std::string(MEMORY_WLR_PORT_NAME), + true); } /********************************************************************* @@ -1629,6 +1715,7 @@ void add_top_module_ql_memory_bank_sram_ports(ModuleManager& module_manager, const ModuleId& module_id, const CircuitLibrary& circuit_lib, const ConfigProtocol& config_protocol, + const MemoryBankShiftRegisterBanks& blwl_sr_banks, const TopModuleNumConfigBits& num_config_bits) { VTR_ASSERT_SAFE(CONFIG_MEM_QL_MEMORY_BANK == config_protocol.type()); CircuitModelId sram_model = config_protocol.memory_model(); @@ -1664,7 +1751,7 @@ void add_top_module_ql_memory_bank_sram_ports(ModuleManager& module_manager, case BLWL_PROTOCOL_SHIFT_REGISTER: { /* Each region will have independent shift register banks */ for (const ConfigRegionId& config_region : module_manager.regions(module_id)) { - size_t num_heads = config_protocol.bl_num_banks(); + size_t num_heads = blwl_sr_banks.bl_banks(config_region).size(); BasicPort blsr_head_port(generate_regional_blwl_port_name(std::string(BL_SHIFT_REGISTER_CHAIN_HEAD_NAME), config_region), num_heads); module_manager.add_port(module_id, blsr_head_port, ModuleManager::MODULE_INPUT_PORT); BasicPort blsr_tail_port(generate_regional_blwl_port_name(std::string(BL_SHIFT_REGISTER_CHAIN_TAIL_NAME), config_region), num_heads); @@ -1713,7 +1800,7 @@ void add_top_module_ql_memory_bank_sram_ports(ModuleManager& module_manager, case BLWL_PROTOCOL_SHIFT_REGISTER: { /* Each region will have independent shift register banks */ for (const ConfigRegionId& config_region : module_manager.regions(module_id)) { - size_t num_heads = config_protocol.wl_num_banks(); + size_t num_heads = blwl_sr_banks.wl_banks(config_region).size(); BasicPort wlsr_head_port(generate_regional_blwl_port_name(std::string(WL_SHIFT_REGISTER_CHAIN_HEAD_NAME), config_region), num_heads); module_manager.add_port(module_id, wlsr_head_port, ModuleManager::MODULE_INPUT_PORT); BasicPort wlsr_tail_port(generate_regional_blwl_port_name(std::string(WL_SHIFT_REGISTER_CHAIN_TAIL_NAME), config_region), num_heads); diff --git a/openfpga/src/fabric/build_top_module_memory_bank.h b/openfpga/src/fabric/build_top_module_memory_bank.h index 74bcdcc7a..3d76ec3f4 100644 --- a/openfpga/src/fabric/build_top_module_memory_bank.h +++ b/openfpga/src/fabric/build_top_module_memory_bank.h @@ -36,6 +36,7 @@ void add_top_module_ql_memory_bank_sram_ports(ModuleManager& module_manager, const ModuleId& module_id, const CircuitLibrary& circuit_lib, const ConfigProtocol& config_protocol, + const MemoryBankShiftRegisterBanks& blwl_sr_banks, const TopModuleNumConfigBits& num_config_bits); int load_top_module_shift_register_banks_from_fabric_key(const FabricKey& fabric_key, diff --git a/openfpga/src/fabric/memory_bank_shift_register_banks.cpp b/openfpga/src/fabric/memory_bank_shift_register_banks.cpp index 0c5855ae8..048655533 100644 --- a/openfpga/src/fabric/memory_bank_shift_register_banks.cpp +++ b/openfpga/src/fabric/memory_bank_shift_register_banks.cpp @@ -6,17 +6,33 @@ /* begin namespace openfpga */ namespace openfpga { -std::vector MemoryBankShiftRegisterBanks::bl_bank_unique_sizes(const ConfigRegionId& region_id) const { +std::vector MemoryBankShiftRegisterBanks::bl_bank_unique_sizes() const { std::vector unique_sizes; - for (const auto& bank_id : bl_banks(region_id)) { - size_t cur_bank_size = bl_bank_size(region_id, bank_id); - if (unique_sizes.end() == std::find(unique_sizes.begin(), unique_sizes.end(), cur_bank_size)) { - unique_sizes.push_back(cur_bank_size); + for (const auto& region : bl_bank_data_ports_) { + for (const auto& bank : region) { + ConfigRegionId region_id = ConfigRegionId(®ion - &bl_bank_data_ports_[ConfigRegionId(0)]); + FabricBitLineBankId bank_id = FabricBitLineBankId(&bank - ®ion[FabricBitLineBankId(0)]); + size_t cur_bank_size = bl_bank_size(region_id, bank_id); + if (unique_sizes.end() == std::find(unique_sizes.begin(), unique_sizes.end(), cur_bank_size)) { + unique_sizes.push_back(cur_bank_size); + } } } return unique_sizes; } +std::vector MemoryBankShiftRegisterBanks::bl_bank_unique_modules() const { + std::vector unique_modules; + for (const auto& region : bl_bank_modules_) { + for (const auto& bank : region) { + if (unique_modules.end() == std::find(unique_modules.begin(), unique_modules.end(), bank)) { + unique_modules.push_back(bank); + } + } + } + return unique_modules; +} + size_t MemoryBankShiftRegisterBanks::bl_bank_size(const ConfigRegionId& region_id, const FabricBitLineBankId& bank_id) const { size_t cur_bank_size = 0; for (const auto& data_port : bl_bank_data_ports(region_id, bank_id)) { @@ -30,17 +46,33 @@ FabricKey::fabric_bit_line_bank_range MemoryBankShiftRegisterBanks::bl_banks(con return vtr::make_range(bl_bank_ids_[region_id].begin(), bl_bank_ids_[region_id].end()); } -std::vector MemoryBankShiftRegisterBanks::wl_bank_unique_sizes(const ConfigRegionId& region_id) const { +std::vector MemoryBankShiftRegisterBanks::wl_bank_unique_sizes() const { std::vector unique_sizes; - for (const auto& bank_id : wl_banks(region_id)) { - size_t cur_bank_size = wl_bank_size(region_id, bank_id); - if (unique_sizes.end() == std::find(unique_sizes.begin(), unique_sizes.end(), cur_bank_size)) { - unique_sizes.push_back(cur_bank_size); + for (const auto& region : wl_bank_data_ports_) { + for (const auto& bank : region) { + ConfigRegionId region_id = ConfigRegionId(®ion - &wl_bank_data_ports_[ConfigRegionId(0)]); + FabricWordLineBankId bank_id = FabricWordLineBankId(&bank - ®ion[FabricWordLineBankId(0)]); + size_t cur_bank_size = wl_bank_size(region_id, bank_id); + if (unique_sizes.end() == std::find(unique_sizes.begin(), unique_sizes.end(), cur_bank_size)) { + unique_sizes.push_back(cur_bank_size); + } } } return unique_sizes; } +std::vector MemoryBankShiftRegisterBanks::wl_bank_unique_modules() const { + std::vector unique_modules; + for (const auto& region : wl_bank_modules_) { + for (const auto& bank : region) { + if (unique_modules.end() == std::find(unique_modules.begin(), unique_modules.end(), bank)) { + unique_modules.push_back(bank); + } + } + } + return unique_modules; +} + size_t MemoryBankShiftRegisterBanks::wl_bank_size(const ConfigRegionId& region_id, const FabricWordLineBankId& bank_id) const { size_t cur_bank_size = 0; for (const auto& data_port : wl_bank_data_ports(region_id, bank_id)) { @@ -54,144 +86,6 @@ FabricKey::fabric_word_line_bank_range MemoryBankShiftRegisterBanks::wl_banks(co return vtr::make_range(wl_bank_ids_[region_id].begin(), wl_bank_ids_[region_id].end()); } -std::vector MemoryBankShiftRegisterBanks::bl_shift_register_bank_unique_modules() const { - std::vector sr_bank_modules; - for (const auto& region : bl_sr_instance_sink_child_ids_) { - for (const auto& pair : region) { - if (sr_bank_modules.end() == std::find(sr_bank_modules.begin(), sr_bank_modules.end(), pair.first.first)) { - sr_bank_modules.push_back(pair.first.first); - } - } - } - return sr_bank_modules; -} - -std::vector MemoryBankShiftRegisterBanks::bl_shift_register_bank_modules(const ConfigRegionId& region) const { - std::vector sr_bank_modules; - VTR_ASSERT(valid_region_id(region)); - for (const auto& pair : bl_sr_instance_sink_child_ids_[region]) { - sr_bank_modules.push_back(pair.first.first); - } - return sr_bank_modules; -} - -std::vector MemoryBankShiftRegisterBanks::bl_shift_register_bank_instances(const ConfigRegionId& region) const { - std::vector sr_bank_instances; - VTR_ASSERT(valid_region_id(region)); - for (const auto& pair : bl_sr_instance_sink_child_ids_[region]) { - sr_bank_instances.push_back(pair.first.second); - } - return sr_bank_instances; -} - -std::vector MemoryBankShiftRegisterBanks::bl_shift_register_bank_sink_child_ids(const ConfigRegionId& region, - const ModuleId& sr_module, - const size_t& sr_instance) const { - VTR_ASSERT(valid_region_id(region)); - - auto result = bl_sr_instance_sink_child_ids_[region].find(std::make_pair(sr_module, sr_instance)); - /* Return an empty vector if not found */ - if (result != bl_sr_instance_sink_child_ids_[region].end()) { - return result->second; - } - return std::vector(); -} - -std::vector MemoryBankShiftRegisterBanks::bl_shift_register_bank_sink_pin_ids(const ConfigRegionId& region, - const ModuleId& sr_module, - const size_t& sr_instance) const { - VTR_ASSERT(valid_region_id(region)); - - auto result = bl_sr_instance_sink_child_pin_ids_[region].find(std::make_pair(sr_module, sr_instance)); - /* Return an empty vector if not found */ - if (result != bl_sr_instance_sink_child_pin_ids_[region].end()) { - return result->second; - } - return std::vector(); -} - -std::vector MemoryBankShiftRegisterBanks::bl_shift_register_bank_source_blwl_ids(const ConfigRegionId& region, - const ModuleId& sr_module, - const size_t& sr_instance) const { - VTR_ASSERT(valid_region_id(region)); - - auto result = bl_sr_instance_source_blwl_ids_[region].find(std::make_pair(sr_module, sr_instance)); - /* Return an empty vector if not found */ - if (result != bl_sr_instance_source_blwl_ids_[region].end()) { - return result->second; - } - return std::vector(); -} - -std::vector MemoryBankShiftRegisterBanks::wl_shift_register_bank_unique_modules() const { - std::vector sr_bank_modules; - for (const auto& region : wl_sr_instance_sink_child_ids_) { - for (const auto& pair : region) { - if (sr_bank_modules.end() == std::find(sr_bank_modules.begin(), sr_bank_modules.end(), pair.first.first)) { - sr_bank_modules.push_back(pair.first.first); - } - } - } - return sr_bank_modules; -} - -std::vector MemoryBankShiftRegisterBanks::wl_shift_register_bank_modules(const ConfigRegionId& region) const { - std::vector sr_bank_modules; - VTR_ASSERT(valid_region_id(region)); - for (const auto& pair : wl_sr_instance_sink_child_ids_[region]) { - sr_bank_modules.push_back(pair.first.first); - } - return sr_bank_modules; -} - -std::vector MemoryBankShiftRegisterBanks::wl_shift_register_bank_instances(const ConfigRegionId& region) const { - std::vector sr_bank_instances; - VTR_ASSERT(valid_region_id(region)); - for (const auto& pair : wl_sr_instance_sink_child_ids_[region]) { - sr_bank_instances.push_back(pair.first.second); - } - return sr_bank_instances; -} - -std::vector MemoryBankShiftRegisterBanks::wl_shift_register_bank_sink_child_ids(const ConfigRegionId& region, - const ModuleId& sr_module, - const size_t& sr_instance) const { - VTR_ASSERT(valid_region_id(region)); - - auto result = wl_sr_instance_sink_child_ids_[region].find(std::make_pair(sr_module, sr_instance)); - /* Return an empty vector if not found */ - if (result != wl_sr_instance_sink_child_ids_[region].end()) { - return result->second; - } - return std::vector(); -} - -std::vector MemoryBankShiftRegisterBanks::wl_shift_register_bank_sink_pin_ids(const ConfigRegionId& region, - const ModuleId& sr_module, - const size_t& sr_instance) const { - VTR_ASSERT(valid_region_id(region)); - - auto result = wl_sr_instance_sink_child_pin_ids_[region].find(std::make_pair(sr_module, sr_instance)); - /* Return an empty vector if not found */ - if (result != wl_sr_instance_sink_child_pin_ids_[region].end()) { - return result->second; - } - return std::vector(); -} - -std::vector MemoryBankShiftRegisterBanks::wl_shift_register_bank_source_blwl_ids(const ConfigRegionId& region, - const ModuleId& sr_module, - const size_t& sr_instance) const { - VTR_ASSERT(valid_region_id(region)); - - auto result = wl_sr_instance_source_blwl_ids_[region].find(std::make_pair(sr_module, sr_instance)); - /* Return an empty vector if not found */ - if (result != wl_sr_instance_source_blwl_ids_[region].end()) { - return result->second; - } - return std::vector(); -} - std::vector MemoryBankShiftRegisterBanks::bl_bank_data_ports(const ConfigRegionId& region_id, const FabricBitLineBankId& bank_id) const { VTR_ASSERT(valid_bl_bank_id(region_id, bank_id)); return bl_bank_data_ports_[region_id][bank_id]; @@ -230,6 +124,54 @@ BasicPort MemoryBankShiftRegisterBanks::find_bl_shift_register_bank_data_port(co return result->second; } +size_t MemoryBankShiftRegisterBanks::bl_shift_register_bank_sink_child_id(const ConfigRegionId& region_id, + const FabricBitLineBankId& bank_id, + const BasicPort& src_port) const { + VTR_ASSERT(valid_bl_bank_id(region_id, bank_id)); + auto result = bl_bank_sink_child_ids_[region_id][bank_id].find(src_port); + if (result == bl_bank_sink_child_ids_[region_id][bank_id].end()) { + return -1; /* Not found, return an invalid value */ + } + return result->second; +} + +size_t MemoryBankShiftRegisterBanks::bl_shift_register_bank_sink_child_pin_id(const ConfigRegionId& region_id, + const FabricBitLineBankId& bank_id, + const BasicPort& src_port) const { + VTR_ASSERT(valid_bl_bank_id(region_id, bank_id)); + auto result = bl_bank_sink_child_pin_ids_[region_id][bank_id].find(src_port); + if (result == bl_bank_sink_child_pin_ids_[region_id][bank_id].end()) { + return -1; /* Not found, return an invalid value */ + } + return result->second; +} + +std::vector MemoryBankShiftRegisterBanks::bl_shift_register_bank_source_ports(const ConfigRegionId& region_id, + const FabricBitLineBankId& bank_id) const { + VTR_ASSERT(valid_bl_bank_id(region_id, bank_id)); + std::vector src_ports; + + for (const BasicPort& wide_port : bl_bank_data_ports(region_id, bank_id)) { + for (const size_t& pin : wide_port.pins()) { + src_ports.push_back(BasicPort(wide_port.get_name(), pin, pin)); + } + } + + return src_ports; +} + +ModuleId MemoryBankShiftRegisterBanks::bl_shift_register_bank_module(const ConfigRegionId& region_id, + const FabricBitLineBankId& bank_id) const { + VTR_ASSERT(valid_bl_bank_id(region_id, bank_id)); + return bl_bank_modules_[region_id][bank_id]; +} + +size_t MemoryBankShiftRegisterBanks::bl_shift_register_bank_instance(const ConfigRegionId& region_id, + const FabricBitLineBankId& bank_id) const { + VTR_ASSERT(valid_bl_bank_id(region_id, bank_id)); + return bl_bank_instances_[region_id][bank_id]; +} + FabricWordLineBankId MemoryBankShiftRegisterBanks::find_wl_shift_register_bank_id(const ConfigRegionId& region, const BasicPort& wl_port) const { if (is_wl_bank_dirty_) { @@ -261,75 +203,75 @@ BasicPort MemoryBankShiftRegisterBanks::find_wl_shift_register_bank_data_port(co void MemoryBankShiftRegisterBanks::resize_regions(const size_t& num_regions) { bl_bank_ids_.resize(num_regions); bl_bank_data_ports_.resize(num_regions); - bl_sr_instance_sink_child_ids_.resize(num_regions); - bl_sr_instance_sink_child_pin_ids_.resize(num_regions); - bl_sr_instance_source_blwl_ids_.resize(num_regions); + bl_bank_modules_.resize(num_regions); + bl_bank_instances_.resize(num_regions); + bl_bank_sink_child_ids_.resize(num_regions); + bl_bank_sink_child_pin_ids_.resize(num_regions); wl_bank_ids_.resize(num_regions); wl_bank_data_ports_.resize(num_regions); - wl_sr_instance_sink_child_ids_.resize(num_regions); - wl_sr_instance_sink_child_pin_ids_.resize(num_regions); - wl_sr_instance_source_blwl_ids_.resize(num_regions); + wl_bank_modules_.resize(num_regions); + wl_bank_instances_.resize(num_regions); + wl_bank_sink_child_ids_.resize(num_regions); + wl_bank_sink_child_pin_ids_.resize(num_regions); } -void MemoryBankShiftRegisterBanks::add_bl_shift_register_instance(const ConfigRegionId& region, - const ModuleId& sr_module, - const size_t& sr_instance) { - VTR_ASSERT(valid_region_id(region)); - bl_sr_instance_sink_child_ids_[region][std::make_pair(sr_module, sr_instance)]; - bl_sr_instance_sink_child_pin_ids_[region][std::make_pair(sr_module, sr_instance)]; - bl_sr_instance_source_blwl_ids_[region][std::make_pair(sr_module, sr_instance)]; +void MemoryBankShiftRegisterBanks::link_bl_shift_register_bank_to_module(const ConfigRegionId& region_id, + const FabricBitLineBankId& bank_id, + const ModuleId& module_id) { + VTR_ASSERT(valid_bl_bank_id(region_id, bank_id)); + bl_bank_modules_[region_id][bank_id] = module_id; } -void MemoryBankShiftRegisterBanks::add_bl_shift_register_sink_nodes(const ConfigRegionId& region, - const ModuleId& sr_module, - const size_t& sr_instance, - const size_t& sink_child_id, - const size_t& sink_child_pin_id) { - VTR_ASSERT(valid_region_id(region)); - bl_sr_instance_sink_child_ids_[region][std::make_pair(sr_module, sr_instance)].push_back(sink_child_id); - bl_sr_instance_sink_child_pin_ids_[region][std::make_pair(sr_module, sr_instance)].push_back(sink_child_pin_id); +void MemoryBankShiftRegisterBanks::link_bl_shift_register_bank_to_instance(const ConfigRegionId& region_id, + const FabricBitLineBankId& bank_id, + const size_t& instance_id) { + VTR_ASSERT(valid_bl_bank_id(region_id, bank_id)); + bl_bank_instances_[region_id][bank_id] = instance_id; } -void MemoryBankShiftRegisterBanks::add_bl_shift_register_source_blwls(const ConfigRegionId& region, - const ModuleId& sr_module, - const size_t& sr_instance, - const size_t& sink_blwl_id) { - VTR_ASSERT(valid_region_id(region)); - bl_sr_instance_source_blwl_ids_[region][std::make_pair(sr_module, sr_instance)].push_back(sink_blwl_id); -} - -void MemoryBankShiftRegisterBanks::add_wl_shift_register_instance(const ConfigRegionId& region, - const ModuleId& sr_module, - const size_t& sr_instance) { - VTR_ASSERT(valid_region_id(region)); - wl_sr_instance_sink_child_ids_[region][std::make_pair(sr_module, sr_instance)]; - wl_sr_instance_sink_child_pin_ids_[region][std::make_pair(sr_module, sr_instance)]; - wl_sr_instance_source_blwl_ids_[region][std::make_pair(sr_module, sr_instance)]; +void MemoryBankShiftRegisterBanks::link_wl_shift_register_bank_to_module(const ConfigRegionId& region_id, + const FabricWordLineBankId& bank_id, + const ModuleId& module_id) { + VTR_ASSERT(valid_wl_bank_id(region_id, bank_id)); + wl_bank_modules_[region_id][bank_id] = module_id; } -void MemoryBankShiftRegisterBanks::add_wl_shift_register_sink_nodes(const ConfigRegionId& region, - const ModuleId& sr_module, - const size_t& sr_instance, - const size_t& sink_child_id, - const size_t& sink_child_pin_id) { - VTR_ASSERT(valid_region_id(region)); - wl_sr_instance_sink_child_ids_[region][std::make_pair(sr_module, sr_instance)].push_back(sink_child_id); - wl_sr_instance_sink_child_pin_ids_[region][std::make_pair(sr_module, sr_instance)].push_back(sink_child_pin_id); +void MemoryBankShiftRegisterBanks::link_wl_shift_register_bank_to_instance(const ConfigRegionId& region_id, + const FabricWordLineBankId& bank_id, + const size_t& instance_id) { + VTR_ASSERT(valid_wl_bank_id(region_id, bank_id)); + wl_bank_instances_[region_id][bank_id] = instance_id; } -void MemoryBankShiftRegisterBanks::add_wl_shift_register_source_blwls(const ConfigRegionId& region, - const ModuleId& sr_module, - const size_t& sr_instance, - const size_t& sink_blwl_id) { - VTR_ASSERT(valid_region_id(region)); - wl_sr_instance_source_blwl_ids_[region][std::make_pair(sr_module, sr_instance)].push_back(sink_blwl_id); -} +void MemoryBankShiftRegisterBanks::add_bl_shift_register_bank_sink_node(const ConfigRegionId& region, + const FabricBitLineBankId& bank, + const BasicPort& src_port, + const size_t& sink_child_id, + const size_t& sink_child_pin_id) { + VTR_ASSERT(valid_bl_bank_id(region, bank)); + bl_bank_sink_child_ids_[region][bank][src_port] = sink_child_id; + bl_bank_sink_child_pin_ids_[region][bank][src_port] = sink_child_pin_id; +} + +void MemoryBankShiftRegisterBanks::add_wl_shift_register_bank_sink_node(const ConfigRegionId& region, + const FabricWordLineBankId& bank, + const BasicPort& src_port, + const size_t& sink_child_id, + const size_t& sink_child_pin_id) { + VTR_ASSERT(valid_wl_bank_id(region, bank)); + wl_bank_sink_child_ids_[region][bank][src_port] = sink_child_id; + wl_bank_sink_child_pin_ids_[region][bank][src_port] = sink_child_pin_id; +} void MemoryBankShiftRegisterBanks::reserve_bl_shift_register_banks(const ConfigRegionId& region_id, const size_t& num_banks) { VTR_ASSERT(valid_region_id(region_id)); bl_bank_ids_[region_id].reserve(num_banks); bl_bank_data_ports_[region_id].reserve(num_banks); + bl_bank_modules_[region_id].reserve(num_banks); + bl_bank_instances_[region_id].reserve(num_banks); + bl_bank_sink_child_ids_[region_id].reserve(num_banks); + bl_bank_sink_child_pin_ids_[region_id].reserve(num_banks); } void MemoryBankShiftRegisterBanks::reserve_bl_shift_register_banks(const FabricRegionId& region_id, const size_t& num_banks) { @@ -341,6 +283,10 @@ void MemoryBankShiftRegisterBanks::reserve_wl_shift_register_banks(const ConfigR VTR_ASSERT(valid_region_id(region_id)); wl_bank_ids_[region_id].reserve(num_banks); wl_bank_data_ports_[region_id].reserve(num_banks); + wl_bank_modules_[region_id].reserve(num_banks); + wl_bank_instances_[region_id].reserve(num_banks); + wl_bank_sink_child_ids_[region_id].reserve(num_banks); + wl_bank_sink_child_pin_ids_[region_id].reserve(num_banks); } void MemoryBankShiftRegisterBanks::reserve_wl_shift_register_banks(const FabricRegionId& region_id, const size_t& num_banks) { @@ -355,6 +301,10 @@ FabricBitLineBankId MemoryBankShiftRegisterBanks::create_bl_shift_register_bank( FabricBitLineBankId bank = FabricBitLineBankId(bl_bank_ids_[region_id].size()); bl_bank_ids_[region_id].push_back(bank); bl_bank_data_ports_[region_id].emplace_back(); + bl_bank_modules_[region_id].push_back(ModuleId::INVALID()); + bl_bank_instances_[region_id].emplace_back(); + bl_bank_sink_child_ids_[region_id].emplace_back(); + bl_bank_sink_child_pin_ids_[region_id].emplace_back(); return bank; } @@ -391,6 +341,10 @@ FabricWordLineBankId MemoryBankShiftRegisterBanks::create_wl_shift_register_bank FabricWordLineBankId bank = FabricWordLineBankId(wl_bank_ids_[region_id].size()); wl_bank_ids_[region_id].push_back(bank); wl_bank_data_ports_[region_id].emplace_back(); + wl_bank_modules_[region_id].push_back(ModuleId::INVALID()); + wl_bank_instances_[region_id].emplace_back(); + wl_bank_sink_child_ids_[region_id].emplace_back(); + wl_bank_sink_child_pin_ids_[region_id].emplace_back(); return bank; } @@ -410,8 +364,56 @@ void MemoryBankShiftRegisterBanks::add_data_port_to_wl_shift_register_bank(const is_wl_bank_dirty_ = true; } +size_t MemoryBankShiftRegisterBanks::wl_shift_register_bank_sink_child_id(const ConfigRegionId& region_id, + const FabricWordLineBankId& bank_id, + const BasicPort& src_port) const { + VTR_ASSERT(valid_wl_bank_id(region_id, bank_id)); + auto result = wl_bank_sink_child_ids_[region_id][bank_id].find(src_port); + if (result == wl_bank_sink_child_ids_[region_id][bank_id].end()) { + return -1; /* Not found, return an invalid value */ + } + return result->second; +} + +ModuleId MemoryBankShiftRegisterBanks::wl_shift_register_bank_module(const ConfigRegionId& region_id, + const FabricWordLineBankId& bank_id) const { + VTR_ASSERT(valid_wl_bank_id(region_id, bank_id)); + return wl_bank_modules_[region_id][bank_id]; +} + +size_t MemoryBankShiftRegisterBanks::wl_shift_register_bank_instance(const ConfigRegionId& region_id, + const FabricWordLineBankId& bank_id) const { + VTR_ASSERT(valid_wl_bank_id(region_id, bank_id)); + return wl_bank_instances_[region_id][bank_id]; +} + +size_t MemoryBankShiftRegisterBanks::wl_shift_register_bank_sink_child_pin_id(const ConfigRegionId& region_id, + const FabricWordLineBankId& bank_id, + const BasicPort& src_port) const { + VTR_ASSERT(valid_wl_bank_id(region_id, bank_id)); + auto result = wl_bank_sink_child_pin_ids_[region_id][bank_id].find(src_port); + if (result == wl_bank_sink_child_pin_ids_[region_id][bank_id].end()) { + return -1; /* Not found, return an invalid value */ + } + return result->second; +} + +std::vector MemoryBankShiftRegisterBanks::wl_shift_register_bank_source_ports(const ConfigRegionId& region_id, + const FabricWordLineBankId& bank_id) const { + VTR_ASSERT(valid_wl_bank_id(region_id, bank_id)); + std::vector src_ports; + + for (const BasicPort& wide_port : wl_bank_data_ports(region_id, bank_id)) { + for (const size_t& pin : wide_port.pins()) { + src_ports.push_back(BasicPort(wide_port.get_name(), pin, pin)); + } + } + + return src_ports; +} + bool MemoryBankShiftRegisterBanks::valid_region_id(const ConfigRegionId& region) const { - return size_t(region) < bl_sr_instance_sink_child_ids_.size(); + return size_t(region) < bl_bank_ids_.size(); } bool MemoryBankShiftRegisterBanks::valid_bl_bank_id(const ConfigRegionId& region_id, const FabricBitLineBankId& bank_id) const { diff --git a/openfpga/src/fabric/memory_bank_shift_register_banks.h b/openfpga/src/fabric/memory_bank_shift_register_banks.h index 7a3eb2188..9de627b58 100644 --- a/openfpga/src/fabric/memory_bank_shift_register_banks.h +++ b/openfpga/src/fabric/memory_bank_shift_register_banks.h @@ -27,7 +27,10 @@ class MemoryBankShiftRegisterBanks { FabricKey::fabric_word_line_bank_range wl_banks(const ConfigRegionId& region_id) const; public: /* Accessors */ /* @brief Return a list of unique sizes of shift register banks for BL protocol */ - std::vector bl_bank_unique_sizes(const ConfigRegionId& region_id) const; + std::vector bl_bank_unique_sizes() const; + + /* @brief Return a list of unique modules of shift register banks for BL protocol */ + std::vector bl_bank_unique_modules() const; /* @brief Return the size of a BL shift register bank */ size_t bl_bank_size(const ConfigRegionId& region_id, const FabricBitLineBankId& bank_id) const; @@ -35,8 +38,41 @@ class MemoryBankShiftRegisterBanks { /* @brief Return a list of data ports which will be driven by a BL shift register bank */ std::vector bl_bank_data_ports(const ConfigRegionId& region_id, const FabricBitLineBankId& bank_id) const; + /** @brief find the BL shift register bank id to which a BL port is connected to */ + FabricBitLineBankId find_bl_shift_register_bank_id(const ConfigRegionId& region, const BasicPort& bl_port) const; + + /** @brief find the data port of a BL shift register bank id to which a BL port is connected to */ + BasicPort find_bl_shift_register_bank_data_port(const ConfigRegionId& region, const BasicPort& bl_port) const; + + /** @brief Return the module id of a BL shift register bank */ + ModuleId bl_shift_register_bank_module(const ConfigRegionId& region_id, + const FabricBitLineBankId& bank_id) const; + + /** @brief Return the instance id of a BL shift register bank */ + size_t bl_shift_register_bank_instance(const ConfigRegionId& region_id, + const FabricBitLineBankId& bank_id) const; + + /** @brief return the child id at top-level module to which a data port (1-bit) of a BL shift register bank is connected to */ + size_t bl_shift_register_bank_sink_child_id(const ConfigRegionId& region_id, + const FabricBitLineBankId& bank_id, + const BasicPort& src_port) const; + + /** @brief return the child pin id of the child module at top-level module + * to which a data port (1-bit) of a BL shift register bank is connected to + */ + size_t bl_shift_register_bank_sink_child_pin_id(const ConfigRegionId& region_id, + const FabricBitLineBankId& bank_id, + const BasicPort& src_port) const; + + /** @brief Return a list of single-bit ports which are the data ports of a BL shift register bank */ + std::vector bl_shift_register_bank_source_ports(const ConfigRegionId& region_id, + const FabricBitLineBankId& bank_id) const; + /* @brief Return a list of unique sizes of shift register banks for WL protocol */ - std::vector wl_bank_unique_sizes(const ConfigRegionId& region_id) const; + std::vector wl_bank_unique_sizes() const; + + /* @brief Return a list of unique modules of shift register banks for WL protocol */ + std::vector wl_bank_unique_modules() const; /* @brief Return the size of a WL shift register bank */ size_t wl_bank_size(const ConfigRegionId& region_id, const FabricWordLineBankId& bank_id) const; @@ -44,86 +80,42 @@ class MemoryBankShiftRegisterBanks { /* @brief Return a list of data ports which will be driven by a WL shift register bank */ std::vector wl_bank_data_ports(const ConfigRegionId& region_id, const FabricWordLineBankId& bank_id) const; - /* @brief Return a list of modules of unique shift register banks across all the regions */ - std::vector bl_shift_register_bank_unique_modules() const; - - /* @brief Return a list of modules of shift register banks under a specific configuration region of top-level module */ - std::vector bl_shift_register_bank_modules(const ConfigRegionId& region) const; - - /* @brief Return a list of instances of shift register banks under a specific configuration region of top-level module */ - std::vector bl_shift_register_bank_instances(const ConfigRegionId& region) const; - - /* @brief Return a list of ids of reconfigurable children for a given instance of shift register bank - * under a specific configuration region of top-level module - */ - std::vector bl_shift_register_bank_sink_child_ids(const ConfigRegionId& region, - const ModuleId& sr_module, - const size_t& sr_instance) const; - - /* @brief Return a list of BL ids of reconfigurable children for a given instance of shift register bank - * under a specific configuration region of top-level module - */ - std::vector bl_shift_register_bank_sink_pin_ids(const ConfigRegionId& region, - const ModuleId& sr_module, - const size_t& sr_instance) const; - - /* @brief Return a list of BL ids of a given instance of shift register bank - * under a specific configuration region of top-level module - */ - std::vector bl_shift_register_bank_source_blwl_ids(const ConfigRegionId& region, - const ModuleId& sr_module, - const size_t& sr_instance) const; - - /* @brief Return a list of modules of unique shift register banks across all the regions */ - std::vector wl_shift_register_bank_unique_modules() const; - - /* @brief Return a list of modules of shift register banks under a specific configuration region of top-level module */ - std::vector wl_shift_register_bank_modules(const ConfigRegionId& region) const; - - /* @brief Return a list of instances of shift register banks under a specific configuration region of top-level module */ - std::vector wl_shift_register_bank_instances(const ConfigRegionId& region) const; - - /* @brief Return a list of ids of reconfigurable children for a given instance of shift register bank - * under a specific configuration region of top-level module - */ - std::vector wl_shift_register_bank_sink_child_ids(const ConfigRegionId& region, - const ModuleId& sr_module, - const size_t& sr_instance) const; - - /* @brief Return a list of WL ids of reconfigurable children for a given instance of shift register bank - * under a specific configuration region of top-level module - */ - std::vector wl_shift_register_bank_sink_pin_ids(const ConfigRegionId& region, - const ModuleId& sr_module, - const size_t& sr_instance) const; - - /* @brief Return a list of WL ids of a given instance of shift register bank - * under a specific configuration region of top-level module - */ - std::vector wl_shift_register_bank_source_blwl_ids(const ConfigRegionId& region, - const ModuleId& sr_module, - const size_t& sr_instance) const; - - /** @brief find the BL shift register bank id to which a BL port is connected to */ - FabricBitLineBankId find_bl_shift_register_bank_id(const ConfigRegionId& region, const BasicPort& bl_port) const; - - /** @brief find the data port of a BL shift register bank id to which a BL port is connected to */ - BasicPort find_bl_shift_register_bank_data_port(const ConfigRegionId& region, const BasicPort& bl_port) const; - /** @brief find the WL shift register bank id to which a BL port is connected to */ FabricWordLineBankId find_wl_shift_register_bank_id(const ConfigRegionId& region, const BasicPort& wl_port) const; /** @brief find the data port of a WL shift register bank id to which a BL port is connected to */ BasicPort find_wl_shift_register_bank_data_port(const ConfigRegionId& region, const BasicPort& wl_port) const; + /** @brief Return the module id of a WL shift register bank */ + ModuleId wl_shift_register_bank_module(const ConfigRegionId& region_id, + const FabricWordLineBankId& bank_id) const; + + /** @brief Return the instance id of a WL shift register bank */ + size_t wl_shift_register_bank_instance(const ConfigRegionId& region_id, + const FabricWordLineBankId& bank_id) const; + + /** @brief return the child id at top-level module to which a data port (1-bit) of a WL shift register bank is connected to */ + size_t wl_shift_register_bank_sink_child_id(const ConfigRegionId& region, + const FabricWordLineBankId& bank_id, + const BasicPort& src_port) const; + + /** @brief return the child pin id of the child module at top-level module + * to which a data port (1-bit) of a WL shift register bank is connected to + */ + size_t wl_shift_register_bank_sink_child_pin_id(const ConfigRegionId& region, + const FabricWordLineBankId& bank_id, + const BasicPort& src_port) const; + + /** @brief Return a list of single-bit ports which are the data ports of a WL shift register bank */ + std::vector wl_shift_register_bank_source_ports(const ConfigRegionId& region_id, + const FabricWordLineBankId& bank_id) const; + public: /* Mutators */ void resize_regions(const size_t& num_regions); /* Reserve a number of banks to be memory efficent */ void reserve_bl_shift_register_banks(const FabricRegionId& region_id, const size_t& num_banks); void reserve_bl_shift_register_banks(const ConfigRegionId& region_id, const size_t& num_banks); - void reserve_wl_shift_register_banks(const FabricRegionId& region_id, const size_t& num_banks); - void reserve_wl_shift_register_banks(const ConfigRegionId& region_id, const size_t& num_banks); /* Create a new shift register bank for BLs and return an id */ FabricBitLineBankId create_bl_shift_register_bank(const FabricRegionId& region_id); @@ -137,6 +129,27 @@ class MemoryBankShiftRegisterBanks { const FabricBitLineBankId& bank_id, const openfpga::BasicPort& data_port); + /* Link a BL shift register bank to a module id */ + void link_bl_shift_register_bank_to_module(const ConfigRegionId& region_id, + const FabricBitLineBankId& bank_id, + const ModuleId& module_id); + + /* Link a BL shift register bank to a instance id */ + void link_bl_shift_register_bank_to_instance(const ConfigRegionId& region_id, + const FabricBitLineBankId& bank_id, + const size_t& instance_id); + + /* @brief Add the child id and pin id of BL to which a shift register is connected to under a specific configuration region of top-level module */ + void add_bl_shift_register_bank_sink_node(const ConfigRegionId& region, + const FabricBitLineBankId& bank, + const BasicPort& src_port, + const size_t& sink_child_id, + const size_t& sink_child_pin_id); + + /* Reserve a number of banks to be memory efficent */ + void reserve_wl_shift_register_banks(const FabricRegionId& region_id, const size_t& num_banks); + void reserve_wl_shift_register_banks(const ConfigRegionId& region_id, const size_t& num_banks); + /* Create a new shift register bank for WLs and return an id */ FabricWordLineBankId create_wl_shift_register_bank(const FabricRegionId& region_id); FabricWordLineBankId create_wl_shift_register_bank(const ConfigRegionId& region_id); @@ -149,41 +162,22 @@ class MemoryBankShiftRegisterBanks { const FabricWordLineBankId& bank_id, const openfpga::BasicPort& data_port); - /* @brief Add the module id and instance id of a shift register under a specific configuration region of top-level module */ - void add_bl_shift_register_instance(const ConfigRegionId& region, - const ModuleId& sr_module, - const size_t& sr_instance); + /* Link a WL shift register bank to a module id */ + void link_wl_shift_register_bank_to_module(const ConfigRegionId& region_id, + const FabricWordLineBankId& bank_id, + const ModuleId& module_id); - /* @brief Add the child id and pin id of BL to which a shift register is connected to under a specific configuration region of top-level module */ - void add_bl_shift_register_sink_nodes(const ConfigRegionId& region, - const ModuleId& sr_module, - const size_t& sr_instance, - const size_t& sink_child_id, - const size_t& sink_child_pin_id); - - /* @brief Add the BL id under a specific configuration region of top-level module to which a shift register is connected to */ - void add_bl_shift_register_source_blwls(const ConfigRegionId& region, - const ModuleId& sr_module, - const size_t& sr_instance, - const size_t& sink_blwl_id); - - /* @brief Add the module id and instance id of a shift register under a specific configuration region of top-level module */ - void add_wl_shift_register_instance(const ConfigRegionId& region, - const ModuleId& sr_module, - const size_t& sr_instance); + /* Link a WL shift register bank to a instance id */ + void link_wl_shift_register_bank_to_instance(const ConfigRegionId& region_id, + const FabricWordLineBankId& bank_id, + const size_t& instance_id); /* @brief Add the child id and pin id of WL to which a shift register is connected to under a specific configuration region of top-level module */ - void add_wl_shift_register_sink_nodes(const ConfigRegionId& region, - const ModuleId& sr_module, - const size_t& sr_instance, - const size_t& sink_child_id, - const size_t& sink_child_pin_id); - - /* @brief Add the BL/WL id under a specific configuration region of top-level module to which a shift register is connected to */ - void add_wl_shift_register_source_blwls(const ConfigRegionId& region, - const ModuleId& sr_module, - const size_t& sr_instance, - const size_t& sink_blwl_id); + void add_wl_shift_register_bank_sink_node(const ConfigRegionId& region, + const FabricWordLineBankId& bank, + const BasicPort& src_port, + const size_t& sink_child_id, + const size_t& sink_child_pin_id); public: /* Validators */ bool valid_region_id(const ConfigRegionId& region) const; @@ -203,20 +197,18 @@ class MemoryBankShiftRegisterBanks { /* General information about the BL shift register bank */ vtr::vector> bl_bank_ids_; vtr::vector>> bl_bank_data_ports_; - - /* BL: [config_region][(shift_register_module, shift_register_instance)][i] = (reconfigurable_child_id, blwl_port_pin_index)*/ - vtr::vector, std::vector>> bl_sr_instance_sink_child_ids_; - vtr::vector, std::vector>> bl_sr_instance_sink_child_pin_ids_; - vtr::vector, std::vector>> bl_sr_instance_source_blwl_ids_; + vtr::vector> bl_bank_modules_; + vtr::vector> bl_bank_instances_; + vtr::vector>> bl_bank_sink_child_ids_; + vtr::vector>> bl_bank_sink_child_pin_ids_; /* General information about the WL shift register bank */ vtr::vector> wl_bank_ids_; vtr::vector>> wl_bank_data_ports_; - - /* WL: [config_region][(shift_register_module, shift_register_instance)][i] = (reconfigurable_child_id, blwl_port_pin_index)*/ - vtr::vector, std::vector>> wl_sr_instance_sink_child_ids_; - vtr::vector, std::vector>> wl_sr_instance_sink_child_pin_ids_; - vtr::vector, std::vector>> wl_sr_instance_source_blwl_ids_; + vtr::vector> wl_bank_modules_; + vtr::vector> wl_bank_instances_; + vtr::vector>> wl_bank_sink_child_ids_; + vtr::vector>> wl_bank_sink_child_pin_ids_; /* Fast look-up: given a BL/Wl port, e.g., bl[i], find out * - the shift register bank id diff --git a/openfpga/src/fpga_verilog/verilog_shift_register_banks.cpp b/openfpga/src/fpga_verilog/verilog_shift_register_banks.cpp index d950094ab..3b482a752 100644 --- a/openfpga/src/fpga_verilog/verilog_shift_register_banks.cpp +++ b/openfpga/src/fpga_verilog/verilog_shift_register_banks.cpp @@ -54,7 +54,7 @@ void print_verilog_submodule_shift_register_banks(const ModuleManager& module_ma print_verilog_file_header(fp, "Shift register banks used in FPGA"); /* Create the memory circuits for the multiplexer */ - for (const ModuleId& sr_module : blwl_sr_banks.bl_shift_register_bank_unique_modules()) { + for (const ModuleId& sr_module : blwl_sr_banks.bl_bank_unique_modules()) { VTR_ASSERT(true == module_manager.valid_module_id(sr_module)); /* Write the module content in Verilog format */ write_verilog_module_to_file(fp, module_manager, sr_module, @@ -65,7 +65,7 @@ void print_verilog_submodule_shift_register_banks(const ModuleManager& module_ma fp << std::endl; } - for (const ModuleId& sr_module : blwl_sr_banks.wl_shift_register_bank_unique_modules()) { + for (const ModuleId& sr_module : blwl_sr_banks.wl_bank_unique_modules()) { VTR_ASSERT(true == module_manager.valid_module_id(sr_module)); /* Write the module content in Verilog format */ write_verilog_module_to_file(fp, module_manager, sr_module,