diff --git a/openfpga/src/fabric/memory_bank_shift_register_banks.cpp b/openfpga/src/fabric/memory_bank_shift_register_banks.cpp index bdd403ebc..0c5855ae8 100644 --- a/openfpga/src/fabric/memory_bank_shift_register_banks.cpp +++ b/openfpga/src/fabric/memory_bank_shift_register_banks.cpp @@ -1,5 +1,6 @@ #include #include "vtr_assert.h" +#include "openfpga_reserved_words.h" #include "memory_bank_shift_register_banks.h" /* begin namespace openfpga */ @@ -201,6 +202,62 @@ std::vector MemoryBankShiftRegisterBanks::wl_bank_data_ports(const Co return wl_bank_data_ports_[region_id][bank_id]; } +FabricBitLineBankId MemoryBankShiftRegisterBanks::find_bl_shift_register_bank_id(const ConfigRegionId& region, + const BasicPort& bl_port) const { + if (is_bl_bank_dirty_) { + build_bl_port_fast_lookup(); + } + + VTR_ASSERT(valid_region_id(region)); + const auto& result = bl_ports_to_sr_bank_ids_[region].find(bl_port); + if (result == bl_ports_to_sr_bank_ids_[region].end()) { + return FabricBitLineBankId::INVALID(); + } + return result->second; +} + +BasicPort MemoryBankShiftRegisterBanks::find_bl_shift_register_bank_data_port(const ConfigRegionId& region, + const BasicPort& bl_port) const { + if (is_bl_bank_dirty_) { + build_bl_port_fast_lookup(); + } + + VTR_ASSERT(valid_region_id(region)); + const auto& result = bl_ports_to_sr_bank_ports_[region].find(bl_port); + if (result == bl_ports_to_sr_bank_ports_[region].end()) { + return BasicPort(); + } + return result->second; +} + +FabricWordLineBankId MemoryBankShiftRegisterBanks::find_wl_shift_register_bank_id(const ConfigRegionId& region, + const BasicPort& wl_port) const { + if (is_wl_bank_dirty_) { + build_wl_port_fast_lookup(); + } + + VTR_ASSERT(valid_region_id(region)); + const auto& result = wl_ports_to_sr_bank_ids_[region].find(wl_port); + if (result == wl_ports_to_sr_bank_ids_[region].end()) { + return FabricWordLineBankId::INVALID(); + } + return result->second; +} + +BasicPort MemoryBankShiftRegisterBanks::find_wl_shift_register_bank_data_port(const ConfigRegionId& region, + const BasicPort& wl_port) const { + if (is_wl_bank_dirty_) { + build_wl_port_fast_lookup(); + } + + VTR_ASSERT(valid_region_id(region)); + const auto& result = wl_ports_to_sr_bank_ports_[region].find(wl_port); + if (result == wl_ports_to_sr_bank_ports_[region].end()) { + return BasicPort(); + } + return result->second; +} + void MemoryBankShiftRegisterBanks::resize_regions(const size_t& num_regions) { bl_bank_ids_.resize(num_regions); bl_bank_data_ports_.resize(num_regions); @@ -319,6 +376,7 @@ void MemoryBankShiftRegisterBanks::add_data_port_to_bl_shift_register_bank(const const openfpga::BasicPort& data_port) { VTR_ASSERT(valid_bl_bank_id(region_id, bank_id)); bl_bank_data_ports_[region_id][bank_id].push_back(data_port); + is_bl_bank_dirty_ = true; } FabricWordLineBankId MemoryBankShiftRegisterBanks::create_wl_shift_register_bank(const FabricRegionId& region_id) { @@ -349,6 +407,7 @@ void MemoryBankShiftRegisterBanks::add_data_port_to_wl_shift_register_bank(const const openfpga::BasicPort& data_port) { VTR_ASSERT(valid_wl_bank_id(region_id, bank_id)); wl_bank_data_ports_[region_id][bank_id].push_back(data_port); + is_wl_bank_dirty_ = true; } bool MemoryBankShiftRegisterBanks::valid_region_id(const ConfigRegionId& region) const { @@ -373,4 +432,48 @@ bool MemoryBankShiftRegisterBanks::empty() const { return bl_bank_ids_.empty() && wl_bank_ids_.empty(); } +void MemoryBankShiftRegisterBanks::build_bl_port_fast_lookup() const { + bl_ports_to_sr_bank_ids_.resize(bl_bank_data_ports_.size()); + for (const auto& region : bl_bank_data_ports_) { + size_t bl_index = 0; + for (const auto& bank : region) { + for (const auto& port : bank) { + for (const auto& pin : port.pins()) { + BasicPort bl_port(std::string(MEMORY_BL_PORT_NAME), bl_index, bl_index); + BasicPort sr_bl_port(std::string(MEMORY_BL_PORT_NAME), pin, pin); + ConfigRegionId region_id = ConfigRegionId(®ion - &bl_bank_data_ports_[ConfigRegionId(0)]); + FabricBitLineBankId bank_id = FabricBitLineBankId(&bank - ®ion[FabricBitLineBankId(0)]); + bl_ports_to_sr_bank_ids_[region_id][bl_port] = bank_id; + bl_ports_to_sr_bank_ports_[region_id][bl_port] = sr_bl_port; + bl_index++; + } + } + } + } + /* Clear the flag, now fast look-up is synchronized */ + is_bl_bank_dirty_ = false; +} + +void MemoryBankShiftRegisterBanks::build_wl_port_fast_lookup() const { + wl_ports_to_sr_bank_ids_.resize(wl_bank_data_ports_.size()); + for (const auto& region : wl_bank_data_ports_) { + size_t wl_index = 0; + for (const auto& bank : region) { + for (const auto& port : bank) { + for (const auto& pin : port.pins()) { + BasicPort wl_port(std::string(MEMORY_WL_PORT_NAME), wl_index, wl_index); + BasicPort sr_wl_port(std::string(MEMORY_WL_PORT_NAME), pin, pin); + ConfigRegionId region_id = ConfigRegionId(®ion - &wl_bank_data_ports_[ConfigRegionId(0)]); + FabricWordLineBankId bank_id = FabricWordLineBankId(&bank - ®ion[FabricWordLineBankId(0)]); + wl_ports_to_sr_bank_ids_[region_id][wl_port] = bank_id; + wl_ports_to_sr_bank_ports_[region_id][wl_port] = sr_wl_port; + wl_index++; + } + } + } + } + /* Clear the flag, now fast look-up is synchronized */ + is_wl_bank_dirty_ = false; +} + } /* end namespace openfpga */ diff --git a/openfpga/src/fabric/memory_bank_shift_register_banks.h b/openfpga/src/fabric/memory_bank_shift_register_banks.h index 0041df1ac..7a3eb2188 100644 --- a/openfpga/src/fabric/memory_bank_shift_register_banks.h +++ b/openfpga/src/fabric/memory_bank_shift_register_banks.h @@ -104,6 +104,18 @@ class MemoryBankShiftRegisterBanks { 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; + public: /* Mutators */ void resize_regions(const size_t& num_regions); @@ -179,6 +191,14 @@ class MemoryBankShiftRegisterBanks { bool valid_wl_bank_id(const ConfigRegionId& region_id, const FabricWordLineBankId& bank_id) const; bool empty() const; + private: /* Internal Mutators */ + /** @brief Build the mapping from a BL/WL port to shift register bank and assoicated pins + * @note we use const here because the caller functions, e.g., find_bl_shift_register_bank_id(), is const + * even though it does modify internal data + */ + void build_bl_port_fast_lookup() const; + void build_wl_port_fast_lookup() const; + private: /* Internal data */ /* General information about the BL shift register bank */ vtr::vector> bl_bank_ids_; @@ -198,6 +218,18 @@ class MemoryBankShiftRegisterBanks { vtr::vector, std::vector>> wl_sr_instance_sink_child_pin_ids_; vtr::vector, std::vector>> wl_sr_instance_source_blwl_ids_; + /* Fast look-up: given a BL/Wl port, e.g., bl[i], find out + * - the shift register bank id + * - the output pin id of the shift register bank + */ + mutable vtr::vector> bl_ports_to_sr_bank_ids_; + mutable vtr::vector> bl_ports_to_sr_bank_ports_; + mutable vtr::vector> wl_ports_to_sr_bank_ids_; + mutable vtr::vector> wl_ports_to_sr_bank_ports_; + + /* A flag to indicate that the general information of the shift register banks have been modified, fast look-up has to be updated */ + mutable bool is_bl_bank_dirty_ = false; + mutable bool is_wl_bank_dirty_ = false; }; } /* end namespace openfpga */