[Engine] Upgrading fabric generator to support customizable shift register banks from fabric key and configuration protocols
This commit is contained in:
parent
8f5f30792f
commit
39a69e0d88
|
@ -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
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
Loading…
Reference in New Issue