diff --git a/openfpga/src/fabric/memory_bank_shift_register_banks.cpp b/openfpga/src/fabric/memory_bank_shift_register_banks.cpp index 9dcd98cf3..9854585b9 100644 --- a/openfpga/src/fabric/memory_bank_shift_register_banks.cpp +++ b/openfpga/src/fabric/memory_bank_shift_register_banks.cpp @@ -5,6 +5,54 @@ /* begin namespace openfpga */ namespace openfpga { +std::vector MemoryBankShiftRegisterBanks::bl_bank_unique_sizes(const ConfigRegionId& region_id) 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); + } + } + return unique_sizes; +} + +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)) { + cur_bank_size += data_port.get_width(); + } + return cur_bank_size; +} + +FabricKey::fabric_bit_line_bank_range MemoryBankShiftRegisterBanks::bl_banks(const ConfigRegionId& region_id) const { + VTR_ASSERT(valid_region_id(region_id)); + 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 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); + } + } + return unique_sizes; +} + +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)) { + cur_bank_size += data_port.get_width(); + } + return cur_bank_size; +} + +FabricKey::fabric_word_line_bank_range MemoryBankShiftRegisterBanks::wl_banks(const ConfigRegionId& region_id) const { + VTR_ASSERT(valid_region_id(region_id)); + return vtr::make_range(wl_bank_ids_[region_id].begin(), wl_bank_ids_[region_id].end()); +} + std::vector MemoryBankShiftRegisterBanks::shift_register_bank_unique_modules() const { std::vector sr_bank_modules; for (const auto& region : sr_instance_sink_child_ids_) { @@ -74,6 +122,16 @@ std::vector MemoryBankShiftRegisterBanks::shift_register_bank_source_blw 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]; +} + +std::vector MemoryBankShiftRegisterBanks::wl_bank_data_ports(const ConfigRegionId& region_id, const FabricWordLineBankId& bank_id) const { + VTR_ASSERT(valid_wl_bank_id(region_id, bank_id)); + return wl_bank_data_ports_[region_id][bank_id]; +} + void MemoryBankShiftRegisterBanks::resize_regions(const size_t& num_regions) { sr_instance_sink_child_ids_.resize(num_regions); sr_instance_sink_child_pin_ids_.resize(num_regions); @@ -107,8 +165,71 @@ void MemoryBankShiftRegisterBanks::add_shift_register_source_blwls(const ConfigR sr_instance_source_blwl_ids_[region][std::make_pair(sr_module, sr_instance)].push_back(sink_blwl_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); +} + +void MemoryBankShiftRegisterBanks::reserve_wl_shift_register_banks(const ConfigRegionId& region_id, const size_t& num_banks) { + VTR_ASSERT(valid_region_id(region_id)); + wl_bank_ids_[region_id].reserve(num_banks); + wl_bank_data_ports_[region_id].reserve(num_banks); +} + +FabricBitLineBankId MemoryBankShiftRegisterBanks::create_bl_shift_register_bank(const ConfigRegionId& region_id) { + VTR_ASSERT(valid_region_id(region_id)); + + /* Create a new id */ + 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(); + + return bank; +} + +void MemoryBankShiftRegisterBanks::add_data_port_to_bl_shift_register_bank(const ConfigRegionId& region_id, + const FabricBitLineBankId& bank_id, + 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); +} + +FabricWordLineBankId MemoryBankShiftRegisterBanks::create_wl_shift_register_bank(const ConfigRegionId& region_id) { + VTR_ASSERT(valid_region_id(region_id)); + + /* Create a new id */ + 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(); + + return bank; +} + +void MemoryBankShiftRegisterBanks::add_data_port_to_wl_shift_register_bank(const ConfigRegionId& region_id, + const FabricWordLineBankId& bank_id, + 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); +} + + bool MemoryBankShiftRegisterBanks::valid_region_id(const ConfigRegionId& region) const { return size_t(region) < sr_instance_sink_child_ids_.size(); } +bool MemoryBankShiftRegisterBanks::valid_bl_bank_id(const ConfigRegionId& region_id, const FabricBitLineBankId& bank_id) const { + if (!valid_region_id(region_id)) { + return false; + } + return ( size_t(bank_id) < bl_bank_ids_[region_id].size() ) && ( bank_id == bl_bank_ids_[region_id][bank_id] ); +} + +bool MemoryBankShiftRegisterBanks::valid_wl_bank_id(const ConfigRegionId& region_id, const FabricWordLineBankId& bank_id) const { + if (!valid_region_id(region_id)) { + return false; + } + return ( size_t(bank_id) < wl_bank_ids_[region_id].size() ) && ( bank_id == wl_bank_ids_[region_id][bank_id] ); +} + } /* 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 6114f93d8..56da677b2 100644 --- a/openfpga/src/fabric/memory_bank_shift_register_banks.h +++ b/openfpga/src/fabric/memory_bank_shift_register_banks.h @@ -4,6 +4,7 @@ #include #include #include "vtr_vector.h" +#include "fabric_key.h" #include "module_manager.h" /* begin namespace openfpga */ @@ -21,7 +22,28 @@ namespace openfpga { * @note This data structure is mainly used as a database for adding connections around shift register banks in top-level module ******************************************************************************/ class MemoryBankShiftRegisterBanks { + public: /* Accessors: aggregates */ + FabricKey::fabric_bit_line_bank_range bl_banks(const ConfigRegionId& region_id) const; + 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; + + /* @brief Return the size of a BL shift register bank */ + size_t bl_bank_size(const ConfigRegionId& region_id, const FabricBitLineBankId& bank_id) const; + + /* @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 Return a list of unique sizes of shift register banks for WL protocol */ + std::vector wl_bank_unique_sizes(const ConfigRegionId& region_id) 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; + + /* @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 shift_register_bank_unique_modules() const; @@ -72,10 +94,41 @@ class MemoryBankShiftRegisterBanks { const ModuleId& sr_module, const size_t& sr_instance, const size_t& sink_blwl_id); + + /* Reserve a number of banks to be memory efficent */ + void reserve_bl_shift_register_banks(const ConfigRegionId& 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 ConfigRegionId& region_id); + + /* Add a data port to a given BL shift register bank */ + void add_data_port_to_bl_shift_register_bank(const ConfigRegionId& region_id, + const FabricBitLineBankId& bank_id, + const openfpga::BasicPort& data_port); + + /* Create a new shift register bank for WLs and return an id */ + FabricWordLineBankId create_wl_shift_register_bank(const ConfigRegionId& region_id); + + /* Add a data port to a given WL shift register bank */ + void add_data_port_to_wl_shift_register_bank(const ConfigRegionId& region_id, + const FabricWordLineBankId& bank_id, + const openfpga::BasicPort& data_port); + public: /* Validators */ bool valid_region_id(const ConfigRegionId& region) const; + bool valid_bl_bank_id(const ConfigRegionId& region_id, const FabricBitLineBankId& bank_id) const; + bool valid_wl_bank_id(const ConfigRegionId& region_id, const FabricWordLineBankId& bank_id) const; private: /* Internal data */ + /* General information about the BL shift register bank */ + vtr::vector> bl_bank_ids_; + vtr::vector>> bl_bank_data_ports_; + + /* General information about the WL shift register bank */ + vtr::vector> wl_bank_ids_; + vtr::vector>> wl_bank_data_ports_; + /* [config_region][(shift_register_module, shift_register_instance)][i] = (reconfigurable_child_id, blwl_port_pin_index)*/ vtr::vector, std::vector>> sr_instance_sink_child_ids_; vtr::vector, std::vector>> sr_instance_sink_child_pin_ids_;