[FPGA-Bitstream] Upgrade bitstream generator to support multiple shift register banks in a configuration region for QuickLogic memory bank

This commit is contained in:
tangxifan 2021-10-09 20:39:45 -07:00
parent aac74d9163
commit 34575f7222
15 changed files with 158 additions and 16 deletions

View File

@ -122,6 +122,7 @@ int write_fabric_bitstream(const OpenfpgaContext& openfpga_ctx,
/* By default, output in plain text format */ /* By default, output in plain text format */
status = write_fabric_bitstream_to_text_file(openfpga_ctx.bitstream_manager(), status = write_fabric_bitstream_to_text_file(openfpga_ctx.bitstream_manager(),
openfpga_ctx.fabric_bitstream(), openfpga_ctx.fabric_bitstream(),
openfpga_ctx.blwl_shift_register_banks(),
openfpga_ctx.arch().config_protocol, openfpga_ctx.arch().config_protocol,
openfpga_ctx.fabric_global_port_info(), openfpga_ctx.fabric_global_port_info(),
cmd_context.option_value(cmd, opt_file), cmd_context.option_value(cmd, opt_file),

View File

@ -66,7 +66,7 @@ class OpenfpgaContext : public Context {
const openfpga::DeviceRRGSB& device_rr_gsb() const { return device_rr_gsb_; } const openfpga::DeviceRRGSB& device_rr_gsb() const { return device_rr_gsb_; }
const openfpga::MuxLibrary& mux_lib() const { return mux_lib_; } const openfpga::MuxLibrary& mux_lib() const { return mux_lib_; }
const openfpga::DecoderLibrary& decoder_lib() const { return decoder_lib_; } const openfpga::DecoderLibrary& decoder_lib() const { return decoder_lib_; }
const openfpga::MemoryBankShiftRegisterBanks& blwl_shift_register_banks() { return blwl_sr_banks_; } const openfpga::MemoryBankShiftRegisterBanks& blwl_shift_register_banks() const { return blwl_sr_banks_; }
const openfpga::TileDirect& tile_direct() const { return tile_direct_; } const openfpga::TileDirect& tile_direct() const { return tile_direct_; }
const openfpga::ModuleManager& module_graph() const { return module_graph_; } const openfpga::ModuleManager& module_graph() const { return module_graph_; }
const openfpga::FlowManager& flow_manager() const { return flow_manager_; } const openfpga::FlowManager& flow_manager() const { return flow_manager_; }

View File

@ -107,6 +107,7 @@ int write_full_testbench(const OpenfpgaContext& openfpga_ctx,
return fpga_verilog_full_testbench(openfpga_ctx.module_graph(), return fpga_verilog_full_testbench(openfpga_ctx.module_graph(),
openfpga_ctx.bitstream_manager(), openfpga_ctx.bitstream_manager(),
openfpga_ctx.fabric_bitstream(), openfpga_ctx.fabric_bitstream(),
openfpga_ctx.blwl_shift_register_banks(),
g_vpr_ctx.atom(), g_vpr_ctx.atom(),
g_vpr_ctx.placement(), g_vpr_ctx.placement(),
pin_constraints, pin_constraints,

View File

@ -6,6 +6,10 @@
/* begin namespace openfpga */ /* begin namespace openfpga */
namespace openfpga { namespace openfpga {
ModuleManager::region_range MemoryBankShiftRegisterBanks::regions() const {
return vtr::make_range(config_region_ids_.begin(), config_region_ids_.end());
}
std::vector<size_t> MemoryBankShiftRegisterBanks::bl_bank_unique_sizes() const { std::vector<size_t> MemoryBankShiftRegisterBanks::bl_bank_unique_sizes() const {
std::vector<size_t> unique_sizes; std::vector<size_t> unique_sizes;
for (const auto& region : bl_bank_data_ports_) { for (const auto& region : bl_bank_data_ports_) {
@ -203,6 +207,10 @@ BasicPort MemoryBankShiftRegisterBanks::find_wl_shift_register_bank_data_port(co
} }
void MemoryBankShiftRegisterBanks::resize_regions(const size_t& num_regions) { void MemoryBankShiftRegisterBanks::resize_regions(const size_t& num_regions) {
config_region_ids_.resize(num_regions);
for (size_t iregion = 0; iregion < num_regions; ++iregion) {
config_region_ids_[ConfigRegionId(iregion)] = ConfigRegionId(iregion);
}
bl_bank_ids_.resize(num_regions); bl_bank_ids_.resize(num_regions);
bl_bank_data_ports_.resize(num_regions); bl_bank_data_ports_.resize(num_regions);
bl_bank_modules_.resize(num_regions); bl_bank_modules_.resize(num_regions);

View File

@ -23,6 +23,7 @@ namespace openfpga {
******************************************************************************/ ******************************************************************************/
class MemoryBankShiftRegisterBanks { class MemoryBankShiftRegisterBanks {
public: /* Accessors: aggregates */ public: /* Accessors: aggregates */
ModuleManager::region_range regions() const;
FabricKey::fabric_bit_line_bank_range bl_banks(const ConfigRegionId& region_id) const; 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; FabricKey::fabric_word_line_bank_range wl_banks(const ConfigRegionId& region_id) const;
public: /* Accessors */ public: /* Accessors */
@ -200,6 +201,8 @@ class MemoryBankShiftRegisterBanks {
void build_wl_port_fast_lookup() const; void build_wl_port_fast_lookup() const;
private: /* Internal data */ private: /* Internal data */
vtr::vector<ConfigRegionId, ConfigRegionId> config_region_ids_;
/* General information about the BL shift register bank */ /* General information about the BL shift register bank */
vtr::vector<ConfigRegionId, vtr::vector<FabricBitLineBankId, FabricBitLineBankId>> bl_bank_ids_; vtr::vector<ConfigRegionId, vtr::vector<FabricBitLineBankId, FabricBitLineBankId>> bl_bank_ids_;
vtr::vector<ConfigRegionId, vtr::vector<FabricBitLineBankId, std::vector<BasicPort>>> bl_bank_data_ports_; vtr::vector<ConfigRegionId, vtr::vector<FabricBitLineBankId, std::vector<BasicPort>>> bl_bank_data_ports_;

View File

@ -244,6 +244,7 @@ int write_memory_bank_shift_register_fabric_bitstream_to_text_file(std::fstream&
const bool& fast_configuration, const bool& fast_configuration,
const bool& bit_value_to_skip, const bool& bit_value_to_skip,
const FabricBitstream& fabric_bitstream, const FabricBitstream& fabric_bitstream,
const MemoryBankShiftRegisterBanks& blwl_sr_banks,
const bool& keep_dont_care_bits) { const bool& keep_dont_care_bits) {
int status = 0; int status = 0;
@ -251,7 +252,7 @@ int write_memory_bank_shift_register_fabric_bitstream_to_text_file(std::fstream&
if (keep_dont_care_bits) { if (keep_dont_care_bits) {
dont_care_bit = DONT_CARE_CHAR; dont_care_bit = DONT_CARE_CHAR;
} }
MemoryBankShiftRegisterFabricBitstream fabric_bits = build_memory_bank_shift_register_fabric_bitstream(fabric_bitstream, fast_configuration, bit_value_to_skip, dont_care_bit); MemoryBankShiftRegisterFabricBitstream fabric_bits = build_memory_bank_shift_register_fabric_bitstream(fabric_bitstream, blwl_sr_banks, fast_configuration, bit_value_to_skip, dont_care_bit);
/* Output information about how to intepret the bitstream */ /* Output information about how to intepret the bitstream */
fp << "// Bitstream word count: " << fabric_bits.num_words() << std::endl; fp << "// Bitstream word count: " << fabric_bits.num_words() << std::endl;
@ -363,6 +364,7 @@ int write_frame_based_fabric_bitstream_to_text_file(std::fstream& fp,
*******************************************************************/ *******************************************************************/
int write_fabric_bitstream_to_text_file(const BitstreamManager& bitstream_manager, int write_fabric_bitstream_to_text_file(const BitstreamManager& bitstream_manager,
const FabricBitstream& fabric_bitstream, const FabricBitstream& fabric_bitstream,
const MemoryBankShiftRegisterBanks& blwl_sr_banks,
const ConfigProtocol& config_protocol, const ConfigProtocol& config_protocol,
const FabricGlobalPortInfo& global_ports, const FabricGlobalPortInfo& global_ports,
const std::string& fname, const std::string& fname,
@ -439,6 +441,7 @@ int write_fabric_bitstream_to_text_file(const BitstreamManager& bitstream_manage
apply_fast_configuration, apply_fast_configuration,
bit_value_to_skip, bit_value_to_skip,
fabric_bitstream, fabric_bitstream,
blwl_sr_banks,
keep_dont_care_bits); keep_dont_care_bits);
} }
break; break;

View File

@ -9,6 +9,7 @@
#include "bitstream_manager.h" #include "bitstream_manager.h"
#include "fabric_bitstream.h" #include "fabric_bitstream.h"
#include "config_protocol.h" #include "config_protocol.h"
#include "memory_bank_shift_register_banks.h"
#include "fabric_global_port_info.h" #include "fabric_global_port_info.h"
/******************************************************************** /********************************************************************
@ -20,6 +21,7 @@ namespace openfpga {
int write_fabric_bitstream_to_text_file(const BitstreamManager& bitstream_manager, int write_fabric_bitstream_to_text_file(const BitstreamManager& bitstream_manager,
const FabricBitstream& fabric_bitstream, const FabricBitstream& fabric_bitstream,
const MemoryBankShiftRegisterBanks& blwl_sr_banks,
const ConfigProtocol& config_protocol, const ConfigProtocol& config_protocol,
const FabricGlobalPortInfo& global_ports, const FabricGlobalPortInfo& global_ports,
const std::string& fname, const std::string& fname,

View File

@ -149,6 +149,7 @@ void fpga_fabric_verilog(ModuleManager &module_manager,
int fpga_verilog_full_testbench(const ModuleManager &module_manager, int fpga_verilog_full_testbench(const ModuleManager &module_manager,
const BitstreamManager &bitstream_manager, const BitstreamManager &bitstream_manager,
const FabricBitstream &fabric_bitstream, const FabricBitstream &fabric_bitstream,
const MemoryBankShiftRegisterBanks& blwl_sr_banks,
const AtomContext &atom_ctx, const AtomContext &atom_ctx,
const PlacementContext &place_ctx, const PlacementContext &place_ctx,
const PinConstraints& pin_constraints, const PinConstraints& pin_constraints,
@ -175,7 +176,7 @@ int fpga_verilog_full_testbench(const ModuleManager &module_manager,
/* Generate full testbench for verification, including configuration phase and operating phase */ /* Generate full testbench for verification, including configuration phase and operating phase */
std::string top_testbench_file_path = src_dir_path + netlist_name + std::string(AUTOCHECK_TOP_TESTBENCH_VERILOG_FILE_POSTFIX); std::string top_testbench_file_path = src_dir_path + netlist_name + std::string(AUTOCHECK_TOP_TESTBENCH_VERILOG_FILE_POSTFIX);
print_verilog_full_testbench(module_manager, print_verilog_full_testbench(module_manager,
bitstream_manager, fabric_bitstream, bitstream_manager, fabric_bitstream, blwl_sr_banks,
circuit_lib, circuit_lib,
config_protocol, config_protocol,
fabric_global_port_info, fabric_global_port_info,

View File

@ -48,6 +48,7 @@ void fpga_fabric_verilog(ModuleManager& module_manager,
int fpga_verilog_full_testbench(const ModuleManager& module_manager, int fpga_verilog_full_testbench(const ModuleManager& module_manager,
const BitstreamManager& bitstream_manager, const BitstreamManager& bitstream_manager,
const FabricBitstream& fabric_bitstream, const FabricBitstream& fabric_bitstream,
const MemoryBankShiftRegisterBanks& blwl_sr_banks,
const AtomContext& atom_ctx, const AtomContext& atom_ctx,
const PlacementContext& place_ctx, const PlacementContext& place_ctx,
const PinConstraints& pin_constraints, const PinConstraints& pin_constraints,

View File

@ -1132,6 +1132,7 @@ int print_verilog_top_testbench_configuration_protocol_stimulus(std::fstream& fp
const bool& fast_configuration, const bool& fast_configuration,
const bool& bit_value_to_skip, const bool& bit_value_to_skip,
const FabricBitstream& fabric_bitstream, const FabricBitstream& fabric_bitstream,
const MemoryBankShiftRegisterBanks& blwl_sr_banks,
const float& prog_clock_period, const float& prog_clock_period,
const float& timescale) { const float& timescale) {
/* Validate the file stream */ /* Validate the file stream */
@ -1147,7 +1148,8 @@ int print_verilog_top_testbench_configuration_protocol_stimulus(std::fstream& fp
return print_verilog_top_testbench_configuration_protocol_ql_memory_bank_stimulus(fp, return print_verilog_top_testbench_configuration_protocol_ql_memory_bank_stimulus(fp,
config_protocol, sim_settings, config_protocol, sim_settings,
module_manager, top_module, module_manager, top_module,
fast_configuration, bit_value_to_skip, fabric_bitstream, fast_configuration, bit_value_to_skip,
fabric_bitstream, blwl_sr_banks,
prog_clock_period, timescale); prog_clock_period, timescale);
break; break;
case CONFIG_MEM_MEMORY_BANK: case CONFIG_MEM_MEMORY_BANK:
@ -1738,7 +1740,8 @@ void print_verilog_full_testbench_bitstream(std::fstream& fp,
const ModuleManager& module_manager, const ModuleManager& module_manager,
const ModuleId& top_module, const ModuleId& top_module,
const BitstreamManager& bitstream_manager, const BitstreamManager& bitstream_manager,
const FabricBitstream& fabric_bitstream) { const FabricBitstream& fabric_bitstream,
const MemoryBankShiftRegisterBanks& blwl_sr_banks) {
/* Branch on the type of configuration protocol */ /* Branch on the type of configuration protocol */
switch (config_protocol.type()) { switch (config_protocol.type()) {
@ -1771,7 +1774,7 @@ void print_verilog_full_testbench_bitstream(std::fstream& fp,
fast_configuration, fast_configuration,
bit_value_to_skip, bit_value_to_skip,
module_manager, top_module, module_manager, top_module,
fabric_bitstream); fabric_bitstream, blwl_sr_banks);
break; break;
case CONFIG_MEM_FRAME_BASED: case CONFIG_MEM_FRAME_BASED:
print_verilog_full_testbench_frame_decoder_bitstream(fp, bitstream_file, print_verilog_full_testbench_frame_decoder_bitstream(fp, bitstream_file,
@ -1893,6 +1896,7 @@ void print_verilog_top_testbench_check(std::fstream& fp,
int print_verilog_full_testbench(const ModuleManager& module_manager, int print_verilog_full_testbench(const ModuleManager& module_manager,
const BitstreamManager& bitstream_manager, const BitstreamManager& bitstream_manager,
const FabricBitstream& fabric_bitstream, const FabricBitstream& fabric_bitstream,
const MemoryBankShiftRegisterBanks& blwl_sr_banks,
const CircuitLibrary& circuit_lib, const CircuitLibrary& circuit_lib,
const ConfigProtocol& config_protocol, const ConfigProtocol& config_protocol,
const FabricGlobalPortInfo& global_ports, const FabricGlobalPortInfo& global_ports,
@ -1984,7 +1988,8 @@ int print_verilog_full_testbench(const ModuleManager& module_manager,
status = print_verilog_top_testbench_configuration_protocol_stimulus(fp, status = print_verilog_top_testbench_configuration_protocol_stimulus(fp,
config_protocol, simulation_parameters, config_protocol, simulation_parameters,
module_manager, top_module, module_manager, top_module,
fast_configuration, bit_value_to_skip, fabric_bitstream, fast_configuration, bit_value_to_skip,
fabric_bitstream, blwl_sr_banks,
prog_clock_period, prog_clock_period,
VERILOG_SIM_TIMESCALE); VERILOG_SIM_TIMESCALE);
@ -2057,7 +2062,7 @@ int print_verilog_full_testbench(const ModuleManager& module_manager,
apply_fast_configuration, apply_fast_configuration,
bit_value_to_skip, bit_value_to_skip,
module_manager, top_module, module_manager, top_module,
bitstream_manager, fabric_bitstream); bitstream_manager, fabric_bitstream, blwl_sr_banks);
/* Add signal initialization: /* Add signal initialization:
* Bypass writing codes to files due to the autogenerated codes are very large. * Bypass writing codes to files due to the autogenerated codes are very large.

View File

@ -17,6 +17,7 @@
#include "fabric_global_port_info.h" #include "fabric_global_port_info.h"
#include "vpr_netlist_annotation.h" #include "vpr_netlist_annotation.h"
#include "simulation_setting.h" #include "simulation_setting.h"
#include "memory_bank_shift_register_banks.h"
#include "verilog_testbench_options.h" #include "verilog_testbench_options.h"
/******************************************************************** /********************************************************************
@ -29,6 +30,7 @@ namespace openfpga {
int print_verilog_full_testbench(const ModuleManager& module_manager, int print_verilog_full_testbench(const ModuleManager& module_manager,
const BitstreamManager& bitstream_manager, const BitstreamManager& bitstream_manager,
const FabricBitstream& fabric_bitstream, const FabricBitstream& fabric_bitstream,
const MemoryBankShiftRegisterBanks& blwl_sr_banks,
const CircuitLibrary& circuit_lib, const CircuitLibrary& circuit_lib,
const ConfigProtocol& config_protocol, const ConfigProtocol& config_protocol,
const FabricGlobalPortInfo& global_ports, const FabricGlobalPortInfo& global_ports,

View File

@ -326,6 +326,7 @@ int print_verilog_top_testbench_configuration_protocol_ql_memory_bank_stimulus(s
const bool& fast_configuration, const bool& fast_configuration,
const bool& bit_value_to_skip, const bool& bit_value_to_skip,
const FabricBitstream& fabric_bitstream, const FabricBitstream& fabric_bitstream,
const MemoryBankShiftRegisterBanks& blwl_sr_banks,
const float& prog_clock_period, const float& prog_clock_period,
const float& timescale) { const float& timescale) {
ModulePortId en_port_id = module_manager.find_module_port(top_module, ModulePortId en_port_id = module_manager.find_module_port(top_module,
@ -350,6 +351,7 @@ int print_verilog_top_testbench_configuration_protocol_ql_memory_bank_stimulus(s
/* Reorganize the fabric bitstream by the same address across regions */ /* Reorganize the fabric bitstream by the same address across regions */
if (CONFIG_MEM_QL_MEMORY_BANK == config_protocol.type()) { if (CONFIG_MEM_QL_MEMORY_BANK == config_protocol.type()) {
MemoryBankShiftRegisterFabricBitstream fabric_bits_by_addr = build_memory_bank_shift_register_fabric_bitstream(fabric_bitstream, MemoryBankShiftRegisterFabricBitstream fabric_bits_by_addr = build_memory_bank_shift_register_fabric_bitstream(fabric_bitstream,
blwl_sr_banks,
fast_configuration, fast_configuration,
bit_value_to_skip); bit_value_to_skip);
@ -541,12 +543,14 @@ void print_verilog_full_testbench_ql_memory_bank_shift_register_bitstream(std::f
const bool& bit_value_to_skip, const bool& bit_value_to_skip,
const ModuleManager& module_manager, const ModuleManager& module_manager,
const ModuleId& top_module, const ModuleId& top_module,
const FabricBitstream& fabric_bitstream) { const FabricBitstream& fabric_bitstream,
const MemoryBankShiftRegisterBanks& blwl_sr_banks) {
/* Validate the file stream */ /* Validate the file stream */
valid_file_stream(fp); valid_file_stream(fp);
/* Reorganize the fabric bitstream by the same address across regions */ /* Reorganize the fabric bitstream by the same address across regions */
MemoryBankShiftRegisterFabricBitstream fabric_bits_by_addr = build_memory_bank_shift_register_fabric_bitstream(fabric_bitstream, MemoryBankShiftRegisterFabricBitstream fabric_bits_by_addr = build_memory_bank_shift_register_fabric_bitstream(fabric_bitstream,
blwl_sr_banks,
fast_configuration, fast_configuration,
bit_value_to_skip); bit_value_to_skip);
@ -940,7 +944,8 @@ void print_verilog_full_testbench_ql_memory_bank_bitstream(std::fstream& fp,
const bool& bit_value_to_skip, const bool& bit_value_to_skip,
const ModuleManager& module_manager, const ModuleManager& module_manager,
const ModuleId& top_module, const ModuleId& top_module,
const FabricBitstream& fabric_bitstream) { const FabricBitstream& fabric_bitstream,
const MemoryBankShiftRegisterBanks& blwl_sr_banks) {
if ( (BLWL_PROTOCOL_DECODER == config_protocol.bl_protocol_type()) if ( (BLWL_PROTOCOL_DECODER == config_protocol.bl_protocol_type())
&& (BLWL_PROTOCOL_DECODER == config_protocol.wl_protocol_type()) ) { && (BLWL_PROTOCOL_DECODER == config_protocol.wl_protocol_type()) ) {
print_verilog_full_testbench_ql_memory_bank_decoder_bitstream(fp, bitstream_file, print_verilog_full_testbench_ql_memory_bank_decoder_bitstream(fp, bitstream_file,
@ -961,7 +966,7 @@ void print_verilog_full_testbench_ql_memory_bank_bitstream(std::fstream& fp,
fast_configuration, fast_configuration,
bit_value_to_skip, bit_value_to_skip,
module_manager, top_module, module_manager, top_module,
fabric_bitstream); fabric_bitstream, blwl_sr_banks);
} }
} }

View File

@ -17,6 +17,7 @@
#include "fabric_global_port_info.h" #include "fabric_global_port_info.h"
#include "vpr_netlist_annotation.h" #include "vpr_netlist_annotation.h"
#include "simulation_setting.h" #include "simulation_setting.h"
#include "memory_bank_shift_register_banks.h"
#include "verilog_testbench_options.h" #include "verilog_testbench_options.h"
/******************************************************************** /********************************************************************
@ -53,6 +54,7 @@ int print_verilog_top_testbench_configuration_protocol_ql_memory_bank_stimulus(s
const bool& fast_configuration, const bool& fast_configuration,
const bool& bit_value_to_skip, const bool& bit_value_to_skip,
const FabricBitstream& fabric_bitstream, const FabricBitstream& fabric_bitstream,
const MemoryBankShiftRegisterBanks& blwl_sr_banks,
const float& prog_clock_period, const float& prog_clock_period,
const float& timescale); const float& timescale);
@ -67,7 +69,8 @@ void print_verilog_full_testbench_ql_memory_bank_bitstream(std::fstream& fp,
const bool& bit_value_to_skip, const bool& bit_value_to_skip,
const ModuleManager& module_manager, const ModuleManager& module_manager,
const ModuleId& top_module, const ModuleId& top_module,
const FabricBitstream& fabric_bitstream); const FabricBitstream& fabric_bitstream,
const MemoryBankShiftRegisterBanks& blwl_sr_banks);
} /* end namespace openfpga */ } /* end namespace openfpga */

View File

@ -12,6 +12,7 @@
#include "vtr_log.h" #include "vtr_log.h"
/* Headers from openfpgautil library */ /* Headers from openfpgautil library */
#include "openfpga_reserved_words.h"
#include "openfpga_decode.h" #include "openfpga_decode.h"
#include "fabric_bitstream_utils.h" #include "fabric_bitstream_utils.h"
@ -397,9 +398,109 @@ std::vector<std::string> reshape_bitstream_vectors_to_first_element(const std::v
return rotated_vectors; return rotated_vectors;
} }
/** @brief Split each BL vector in a configuration region into multiple shift register banks
* For example
* Original vector: 1xxx010xxx1
* Resulting vector (2 register register banks):
* 1xxx0
* 10xxx1
*/
static
std::vector<std::string> redistribute_bl_vectors_to_shift_register_banks(const std::vector<std::string> bl_vectors,
const MemoryBankShiftRegisterBanks& blwl_sr_banks) {
std::vector<std::string> multi_bank_bl_vec;
/* Resize the vector by counting the dimension */
/* Compute the start index of each region */
vtr::vector<ConfigRegionId, size_t> region_start_index;
region_start_index.resize(blwl_sr_banks.regions().size(), 0);
size_t total_num_banks = 0;
for (const auto& region : blwl_sr_banks.regions()) {
region_start_index[region] = total_num_banks;
total_num_banks += blwl_sr_banks.bl_banks(region).size();
}
multi_bank_bl_vec.resize(total_num_banks);
/* Resize each bank to be memory efficient */
size_t vec_start_index = 0;
for (const auto& region : blwl_sr_banks.regions()) {
for (const auto& bank : blwl_sr_banks.bl_banks(region)) {
size_t bank_size = blwl_sr_banks.bl_bank_size(region, bank);
multi_bank_bl_vec[vec_start_index].resize(bank_size);
vec_start_index++;
}
}
for (const std::string& region_bl_vec : bl_vectors) {
ConfigRegionId region = ConfigRegionId(&region_bl_vec - &bl_vectors[0]);
for (size_t ibit = 0; ibit < region_bl_vec.size(); ++ibit) {
/* Find the shift register bank id and the offset in data lines */
BasicPort bl_port(std::string(MEMORY_BL_PORT_NAME), ibit, ibit);
FabricBitLineBankId bank_id = blwl_sr_banks.find_bl_shift_register_bank_id(region, bl_port);
BasicPort sr_port = blwl_sr_banks.find_bl_shift_register_bank_data_port(region, bl_port);
VTR_ASSERT(1 == sr_port.get_width());
size_t vec_index = region_start_index[region] + size_t(bank_id);
multi_bank_bl_vec[vec_index][sr_port.get_lsb()] = region_bl_vec[ibit];
}
}
return multi_bank_bl_vec;
}
/** @brief Split each WL vector in a configuration region into multiple shift register banks
* For example
* Original vector: 1xxx010xxx1
* Resulting vector (2 register register banks):
* 1xxx0
* 10xxx1
*/
static
std::vector<std::string> redistribute_wl_vectors_to_shift_register_banks(const std::vector<std::string> wl_vectors,
const MemoryBankShiftRegisterBanks& blwl_sr_banks) {
std::vector<std::string> multi_bank_wl_vec;
/* Resize the vector by counting the dimension */
/* Compute the start index of each region */
vtr::vector<ConfigRegionId, size_t> region_start_index;
region_start_index.resize(blwl_sr_banks.regions().size(), 0);
size_t total_num_banks = 0;
for (const auto& region : blwl_sr_banks.regions()) {
region_start_index[region] = total_num_banks;
total_num_banks += blwl_sr_banks.wl_banks(region).size();
}
multi_bank_wl_vec.resize(total_num_banks);
/* Resize each bank to be memory efficient */
size_t vec_start_index = 0;
for (const auto& region : blwl_sr_banks.regions()) {
for (const auto& bank : blwl_sr_banks.wl_banks(region)) {
size_t bank_size = blwl_sr_banks.wl_bank_size(region, bank);
multi_bank_wl_vec[vec_start_index].resize(bank_size);
vec_start_index++;
}
}
for (const std::string& region_wl_vec : wl_vectors) {
ConfigRegionId region = ConfigRegionId(&region_wl_vec - &wl_vectors[0]);
for (size_t ibit = 0; ibit < region_wl_vec.size(); ++ibit) {
/* Find the shift register bank id and the offset in data lines */
BasicPort wl_port(std::string(MEMORY_WL_PORT_NAME), ibit, ibit);
FabricWordLineBankId bank_id = blwl_sr_banks.find_wl_shift_register_bank_id(region, wl_port);
BasicPort sr_port = blwl_sr_banks.find_wl_shift_register_bank_data_port(region, wl_port);
VTR_ASSERT(1 == sr_port.get_width());
size_t vec_index = region_start_index[region] + size_t(bank_id);
multi_bank_wl_vec[vec_index][sr_port.get_lsb()] = region_wl_vec[ibit];
}
}
return multi_bank_wl_vec;
}
MemoryBankShiftRegisterFabricBitstream build_memory_bank_shift_register_fabric_bitstream(const FabricBitstream& fabric_bitstream, MemoryBankShiftRegisterFabricBitstream build_memory_bank_shift_register_fabric_bitstream(const FabricBitstream& fabric_bitstream,
const MemoryBankShiftRegisterBanks& blwl_sr_banks,
const bool& fast_configuration, const bool& fast_configuration,
//const MemoryBankShiftRegisterBanks& blwl_sr_banks,
const bool& bit_value_to_skip, const bool& bit_value_to_skip,
const char& dont_care_bit) { const char& dont_care_bit) {
MemoryBankFlattenFabricBitstream raw_fabric_bits = build_memory_bank_flatten_fabric_bitstream(fabric_bitstream, fast_configuration, bit_value_to_skip, dont_care_bit); MemoryBankFlattenFabricBitstream raw_fabric_bits = build_memory_bank_flatten_fabric_bitstream(fabric_bitstream, fast_configuration, bit_value_to_skip, dont_care_bit);
@ -411,7 +512,10 @@ MemoryBankShiftRegisterFabricBitstream build_memory_bank_shift_register_fabric_b
MemoryBankShiftRegisterFabricBitstreamWordId word_id = fabric_bits.create_word(); MemoryBankShiftRegisterFabricBitstreamWordId word_id = fabric_bits.create_word();
std::vector<std::string> reshaped_bl_vectors = reshape_bitstream_vectors_to_first_element(bl_vec, dont_care_bit); /* Redistribute the BL vector to multiple banks */
std::vector<std::string> multi_bank_bl_vec = redistribute_bl_vectors_to_shift_register_banks(bl_vec, blwl_sr_banks);
std::vector<std::string> reshaped_bl_vectors = reshape_bitstream_vectors_to_first_element(multi_bank_bl_vec, dont_care_bit);
/* Reverse the vectors due to the shift register chain nature: first-in first-out */ /* Reverse the vectors due to the shift register chain nature: first-in first-out */
std::reverse(reshaped_bl_vectors.begin(), reshaped_bl_vectors.end()); std::reverse(reshaped_bl_vectors.begin(), reshaped_bl_vectors.end());
/* Add the BL word to final bitstream */ /* Add the BL word to final bitstream */
@ -419,7 +523,10 @@ MemoryBankShiftRegisterFabricBitstream build_memory_bank_shift_register_fabric_b
fabric_bits.add_bl_vectors(word_id, reshaped_bl_vec); fabric_bits.add_bl_vectors(word_id, reshaped_bl_vec);
} }
std::vector<std::string> reshaped_wl_vectors = reshape_bitstream_vectors_to_first_element(wl_vec, dont_care_bit); /* Redistribute the WL vector to multiple banks */
std::vector<std::string> multi_bank_wl_vec = redistribute_wl_vectors_to_shift_register_banks(wl_vec, blwl_sr_banks);
std::vector<std::string> reshaped_wl_vectors = reshape_bitstream_vectors_to_first_element(multi_bank_wl_vec, dont_care_bit);
/* Reverse the vectors due to the shift register chain nature: first-in first-out */ /* Reverse the vectors due to the shift register chain nature: first-in first-out */
std::reverse(reshaped_wl_vectors.begin(), reshaped_wl_vectors.end()); std::reverse(reshaped_wl_vectors.begin(), reshaped_wl_vectors.end());
/* Add the BL word to final bitstream */ /* Add the BL word to final bitstream */

View File

@ -95,8 +95,8 @@ MemoryBankFlattenFabricBitstream build_memory_bank_flatten_fabric_bitstream(cons
* @note the std::map may cause large memory footprint for large bitstream databases! * @note the std::map may cause large memory footprint for large bitstream databases!
*******************************************************************/ *******************************************************************/
MemoryBankShiftRegisterFabricBitstream build_memory_bank_shift_register_fabric_bitstream(const FabricBitstream& fabric_bitstream, MemoryBankShiftRegisterFabricBitstream build_memory_bank_shift_register_fabric_bitstream(const FabricBitstream& fabric_bitstream,
const MemoryBankShiftRegisterBanks& blwl_sr_banks,
const bool& fast_configuration, const bool& fast_configuration,
//const MemoryBankShiftRegisterBanks& blwl_sr_banks,
const bool& bit_value_to_skip, const bool& bit_value_to_skip,
const char& dont_care_bit = 'x'); const char& dont_care_bit = 'x');