[Engine] Upgrading fabric generator to support customizable shift register banks from fabric key and configuration protocols

This commit is contained in:
tangxifan 2021-10-08 17:58:06 -07:00
parent 8f5f30792f
commit 39a69e0d88
5 changed files with 189 additions and 5 deletions

View File

@ -23,6 +23,7 @@
#include "build_top_module_utils.h" #include "build_top_module_utils.h"
#include "build_top_module_connection.h" #include "build_top_module_connection.h"
#include "build_top_module_memory.h" #include "build_top_module_memory.h"
#include "build_top_module_memory_bank.h"
#include "build_top_module_directs.h" #include "build_top_module_directs.h"
#include "build_module_graph_utils.h" #include "build_module_graph_utils.h"
@ -382,6 +383,11 @@ int build_top_module(ModuleManager& module_manager,
if (CMD_EXEC_FATAL_ERROR == status) { if (CMD_EXEC_FATAL_ERROR == status) {
return status; return status;
} }
status = load_top_module_shift_register_banks_from_fabric_key(fabric_key, blwl_sr_banks);
if (CMD_EXEC_FATAL_ERROR == status) {
return status;
}
} }
/* Shuffle the configurable children in a random sequence */ /* Shuffle the configurable children in a random sequence */
@ -389,6 +395,13 @@ int build_top_module(ModuleManager& module_manager,
shuffle_top_module_configurable_children(module_manager, top_module, config_protocol); shuffle_top_module_configurable_children(module_manager, top_module, config_protocol);
} }
/* Build shift register bank detailed connections */
sync_memory_bank_shift_register_banks_with_config_protocol_settings(module_manager,
blwl_sr_banks,
config_protocol,
top_module,
circuit_lib);
/* Add shared SRAM ports from the sub-modules under this Verilog module /* Add shared SRAM ports from the sub-modules under this Verilog module
* This is a much easier job after adding sub modules (instances), * This is a much easier job after adding sub modules (instances),
* we just need to find all the I/O ports from the child modules and build a list of it * we just need to find all the I/O ports from the child modules and build a list of it

View File

@ -1728,4 +1728,119 @@ void add_top_module_ql_memory_bank_sram_ports(ModuleManager& module_manager,
} }
} }
/********************************************************************
* Load the shift register bank -related data from fabric key to
* the dedicated and unified data structure
********************************************************************/
int load_top_module_shift_register_banks_from_fabric_key(const FabricKey& fabric_key,
MemoryBankShiftRegisterBanks& blwl_sr_banks) {
blwl_sr_banks.resize_regions(fabric_key.regions().size());
/* Load Bit-Line shift register banks */
for (const auto& region : fabric_key.regions()) {
blwl_sr_banks.reserve_bl_shift_register_banks(region, fabric_key.bl_banks(region).size());
for (const auto& bank : fabric_key.bl_banks(region)) {
FabricBitLineBankId sr_bank = blwl_sr_banks.create_bl_shift_register_bank(region);
for (const auto& data_port : fabric_key.bl_bank_data_ports(region, bank)) {
blwl_sr_banks.add_data_port_to_bl_shift_register_bank(region, sr_bank, data_port);
}
}
}
/* Load Bit-Line shift register banks */
for (const auto& region : fabric_key.regions()) {
blwl_sr_banks.reserve_wl_shift_register_banks(region, fabric_key.wl_banks(region).size());
for (const auto& bank : fabric_key.wl_banks(region)) {
FabricWordLineBankId sr_bank = blwl_sr_banks.create_wl_shift_register_bank(region);
for (const auto& data_port : fabric_key.wl_bank_data_ports(region, bank)) {
blwl_sr_banks.add_data_port_to_wl_shift_register_bank(region, sr_bank, data_port);
}
}
}
}
/********************************************************************
* @brief This functions synchronize the settings in configuration protocol (from architecture description)
* and the existing information (loaded from fabric key files)
* @note This function should be called AFTER load_top_module_shift_register_banks_from_fabric_key()
********************************************************************/
void sync_memory_bank_shift_register_banks_with_config_protocol_settings(ModuleManager& module_manager,
MemoryBankShiftRegisterBanks& blwl_sr_banks,
const ConfigProtocol& config_protocol,
const ModuleId& top_module,
const CircuitLibrary& circuit_lib) {
/* ONLY synchronize when the configuration protocol is memory bank using shift registers */
if ( CONFIG_MEM_QL_MEMORY_BANK != config_protocol.type()
|| BLWL_PROTOCOL_SHIFT_REGISTER != config_protocol.bl_protocol_type()
|| BLWL_PROTOCOL_SHIFT_REGISTER != config_protocol.wl_protocol_type() ) {
return;
}
/* Fabric key has a higher priority in defining the shift register bank organization */
if (!blwl_sr_banks.empty()) {
return;
}
CircuitModelId sram_model = config_protocol.memory_model();
/* Reach here, if means we do not have any definition from fabric key files, use the settings from the configuration protocol */
blwl_sr_banks.resize_regions(module_manager.regions(top_module).size());
/* Based on the number of shift register banks, evenly distribute the BLs in each region for each shift register bank */
for (const auto& config_region : module_manager.regions(top_module)) {
size_t num_bls = compute_memory_bank_regional_num_bls(module_manager, top_module,
config_region,
circuit_lib, sram_model);
size_t num_bl_banks = config_protocol.bl_num_banks();
blwl_sr_banks.reserve_bl_shift_register_banks(config_region, num_bl_banks);
size_t regular_sr_bank_size = num_bls / num_bl_banks;
size_t cur_bl_index = 0;
for (size_t ibank = 0; ibank < num_bl_banks; ++ibank) {
/* For last bank, use all the residual sizes */
size_t cur_sr_bank_size = regular_sr_bank_size;
if (ibank == num_bl_banks - 1) {
cur_sr_bank_size = num_bls - ibank * regular_sr_bank_size;
}
/* Create a bank and assign data ports */
FabricBitLineBankId bank = blwl_sr_banks.create_bl_shift_register_bank(config_region);
BasicPort data_ports(std::string(MEMORY_BL_PORT_NAME), cur_bl_index, cur_bl_index + cur_sr_bank_size - 1);
blwl_sr_banks.add_data_port_to_bl_shift_register_bank(config_region, bank, data_ports);
/* Increment the bl index */
cur_bl_index += cur_sr_bank_size;
}
VTR_ASSERT(cur_bl_index == num_bls);
}
/* Based on the number of shift register banks, evenly distribute the WLs in each region for each shift register bank */
for (const auto& config_region : module_manager.regions(top_module)) {
size_t num_wls = compute_memory_bank_regional_num_wls(module_manager, top_module,
config_region,
circuit_lib, sram_model);
size_t num_wl_banks = config_protocol.wl_num_banks();
blwl_sr_banks.reserve_wl_shift_register_banks(config_region, num_wl_banks);
size_t regular_sr_bank_size = num_wls / num_wl_banks;
size_t cur_wl_index = 0;
for (size_t ibank = 0; ibank < num_wl_banks; ++ibank) {
/* For last bank, use all the residual sizes */
size_t cur_sr_bank_size = regular_sr_bank_size;
if (ibank == num_wl_banks - 1) {
cur_sr_bank_size = num_wls - ibank * regular_sr_bank_size;
}
/* Create a bank and assign data ports */
FabricWordLineBankId bank = blwl_sr_banks.create_wl_shift_register_bank(config_region);
BasicPort data_ports(std::string(MEMORY_WL_PORT_NAME), cur_wl_index, cur_wl_index + cur_sr_bank_size - 1);
blwl_sr_banks.add_data_port_to_wl_shift_register_bank(config_region, bank, data_ports);
/* Increment the bl index */
cur_wl_index += cur_sr_bank_size;
}
VTR_ASSERT(cur_wl_index == num_wls);
}
}
} /* end namespace openfpga */ } /* end namespace openfpga */

View File

@ -38,6 +38,14 @@ void add_top_module_ql_memory_bank_sram_ports(ModuleManager& module_manager,
const ConfigProtocol& config_protocol, const ConfigProtocol& config_protocol,
const TopModuleNumConfigBits& num_config_bits); const TopModuleNumConfigBits& num_config_bits);
int load_top_module_shift_register_banks_from_fabric_key(const FabricKey& fabric_key,
MemoryBankShiftRegisterBanks& blwl_sr_banks);
void sync_memory_bank_shift_register_banks_with_config_protocol_settings(ModuleManager& module_manager,
MemoryBankShiftRegisterBanks& blwl_sr_banks,
const ConfigProtocol& config_protocol,
const ModuleId& top_module,
const CircuitLibrary& circuit_lib);
} /* end namespace openfpga */ } /* end namespace openfpga */

View File

@ -275,12 +275,22 @@ void MemoryBankShiftRegisterBanks::reserve_bl_shift_register_banks(const ConfigR
bl_bank_data_ports_[region_id].reserve(num_banks); bl_bank_data_ports_[region_id].reserve(num_banks);
} }
void MemoryBankShiftRegisterBanks::reserve_bl_shift_register_banks(const FabricRegionId& region_id, const size_t& num_banks) {
ConfigRegionId config_region_id = ConfigRegionId(size_t(region_id));
reserve_bl_shift_register_banks(config_region_id, num_banks);
}
void MemoryBankShiftRegisterBanks::reserve_wl_shift_register_banks(const ConfigRegionId& region_id, const size_t& 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)); VTR_ASSERT(valid_region_id(region_id));
wl_bank_ids_[region_id].reserve(num_banks); wl_bank_ids_[region_id].reserve(num_banks);
wl_bank_data_ports_[region_id].reserve(num_banks); wl_bank_data_ports_[region_id].reserve(num_banks);
} }
void MemoryBankShiftRegisterBanks::reserve_wl_shift_register_banks(const FabricRegionId& region_id, const size_t& num_banks) {
ConfigRegionId config_region_id = ConfigRegionId(size_t(region_id));
reserve_wl_shift_register_banks(config_region_id, num_banks);
}
FabricBitLineBankId MemoryBankShiftRegisterBanks::create_bl_shift_register_bank(const ConfigRegionId& region_id) { FabricBitLineBankId MemoryBankShiftRegisterBanks::create_bl_shift_register_bank(const ConfigRegionId& region_id) {
VTR_ASSERT(valid_region_id(region_id)); VTR_ASSERT(valid_region_id(region_id));
@ -292,13 +302,30 @@ FabricBitLineBankId MemoryBankShiftRegisterBanks::create_bl_shift_register_bank(
return bank; return bank;
} }
FabricBitLineBankId MemoryBankShiftRegisterBanks::create_bl_shift_register_bank(const FabricRegionId& region_id) {
ConfigRegionId config_region_id = ConfigRegionId(size_t(region_id));
return create_bl_shift_register_bank(config_region_id);
}
void MemoryBankShiftRegisterBanks::add_data_port_to_bl_shift_register_bank(const FabricRegionId& region_id,
const FabricBitLineBankId& bank_id,
const openfpga::BasicPort& data_port) {
ConfigRegionId config_region_id = ConfigRegionId(size_t(region_id));
add_data_port_to_bl_shift_register_bank(config_region_id, bank_id, data_port);
}
void MemoryBankShiftRegisterBanks::add_data_port_to_bl_shift_register_bank(const ConfigRegionId& region_id, void MemoryBankShiftRegisterBanks::add_data_port_to_bl_shift_register_bank(const ConfigRegionId& region_id,
const FabricBitLineBankId& bank_id, const FabricBitLineBankId& bank_id,
const openfpga::BasicPort& data_port) { const openfpga::BasicPort& data_port) {
VTR_ASSERT(valid_bl_bank_id(region_id, bank_id)); VTR_ASSERT(valid_bl_bank_id(region_id, bank_id));
bl_bank_data_ports_[region_id][bank_id].push_back(data_port); bl_bank_data_ports_[region_id][bank_id].push_back(data_port);
} }
FabricWordLineBankId MemoryBankShiftRegisterBanks::create_wl_shift_register_bank(const FabricRegionId& region_id) {
ConfigRegionId config_region_id = ConfigRegionId(size_t(region_id));
return create_wl_shift_register_bank(config_region_id);
}
FabricWordLineBankId MemoryBankShiftRegisterBanks::create_wl_shift_register_bank(const ConfigRegionId& region_id) { FabricWordLineBankId MemoryBankShiftRegisterBanks::create_wl_shift_register_bank(const ConfigRegionId& region_id) {
VTR_ASSERT(valid_region_id(region_id)); VTR_ASSERT(valid_region_id(region_id));
@ -310,14 +337,20 @@ FabricWordLineBankId MemoryBankShiftRegisterBanks::create_wl_shift_register_bank
return bank; return bank;
} }
void MemoryBankShiftRegisterBanks::add_data_port_to_wl_shift_register_bank(const FabricRegionId& region_id,
const FabricWordLineBankId& bank_id,
const openfpga::BasicPort& data_port) {
ConfigRegionId config_region_id = ConfigRegionId(size_t(region_id));
add_data_port_to_wl_shift_register_bank(config_region_id, bank_id, data_port);
}
void MemoryBankShiftRegisterBanks::add_data_port_to_wl_shift_register_bank(const ConfigRegionId& region_id, void MemoryBankShiftRegisterBanks::add_data_port_to_wl_shift_register_bank(const ConfigRegionId& region_id,
const FabricWordLineBankId& bank_id, const FabricWordLineBankId& bank_id,
const openfpga::BasicPort& data_port) { const openfpga::BasicPort& data_port) {
VTR_ASSERT(valid_wl_bank_id(region_id, bank_id)); VTR_ASSERT(valid_wl_bank_id(region_id, bank_id));
wl_bank_data_ports_[region_id][bank_id].push_back(data_port); wl_bank_data_ports_[region_id][bank_id].push_back(data_port);
} }
bool MemoryBankShiftRegisterBanks::valid_region_id(const ConfigRegionId& region) const { 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_sr_instance_sink_child_ids_.size();
} }
@ -336,4 +369,8 @@ bool MemoryBankShiftRegisterBanks::valid_wl_bank_id(const ConfigRegionId& region
return ( size_t(bank_id) < wl_bank_ids_[region_id].size() ) && ( bank_id == wl_bank_ids_[region_id][bank_id] ); return ( size_t(bank_id) < wl_bank_ids_[region_id].size() ) && ( bank_id == wl_bank_ids_[region_id][bank_id] );
} }
bool MemoryBankShiftRegisterBanks::empty() const {
return bl_bank_ids_.empty() && wl_bank_ids_.empty();
}
} /* end namespace openfpga */ } /* end namespace openfpga */

View File

@ -108,21 +108,31 @@ class MemoryBankShiftRegisterBanks {
void resize_regions(const size_t& num_regions); void resize_regions(const size_t& num_regions);
/* Reserve a number of banks to be memory efficent */ /* 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_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); 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 */ /* Create a new shift register bank for BLs and return an id */
FabricBitLineBankId create_bl_shift_register_bank(const FabricRegionId& region_id);
FabricBitLineBankId create_bl_shift_register_bank(const ConfigRegionId& region_id); FabricBitLineBankId create_bl_shift_register_bank(const ConfigRegionId& region_id);
/* Add a data port to a given BL shift register bank */ /* Add a data port to a given BL shift register bank */
void add_data_port_to_bl_shift_register_bank(const FabricRegionId& region_id,
const FabricBitLineBankId& bank_id,
const openfpga::BasicPort& data_port);
void add_data_port_to_bl_shift_register_bank(const ConfigRegionId& region_id, void add_data_port_to_bl_shift_register_bank(const ConfigRegionId& region_id,
const FabricBitLineBankId& bank_id, const FabricBitLineBankId& bank_id,
const openfpga::BasicPort& data_port); const openfpga::BasicPort& data_port);
/* Create a new shift register bank for WLs and return an id */ /* 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); FabricWordLineBankId create_wl_shift_register_bank(const ConfigRegionId& region_id);
/* Add a data port to a given WL shift register bank */ /* Add a data port to a given WL shift register bank */
void add_data_port_to_wl_shift_register_bank(const FabricRegionId& region_id,
const FabricWordLineBankId& bank_id,
const openfpga::BasicPort& data_port);
void add_data_port_to_wl_shift_register_bank(const ConfigRegionId& region_id, void add_data_port_to_wl_shift_register_bank(const ConfigRegionId& region_id,
const FabricWordLineBankId& bank_id, const FabricWordLineBankId& bank_id,
const openfpga::BasicPort& data_port); const openfpga::BasicPort& data_port);
@ -167,6 +177,7 @@ class MemoryBankShiftRegisterBanks {
bool valid_region_id(const ConfigRegionId& region) const; bool valid_region_id(const ConfigRegionId& region) const;
bool valid_bl_bank_id(const ConfigRegionId& region_id, const FabricBitLineBankId& bank_id) 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; bool valid_wl_bank_id(const ConfigRegionId& region_id, const FabricWordLineBankId& bank_id) const;
bool empty() const;
private: /* Internal data */ private: /* Internal data */
/* General information about the BL shift register bank */ /* General information about the BL shift register bank */