[FPGA-Bitstream] Upgraded bitstream writer to support flatten BL/WLs
This commit is contained in:
parent
1a2a2a6e63
commit
386812777c
|
@ -302,6 +302,7 @@ void build_module_fabric_dependent_bitstream_ql_memory_bank(const ConfigProtocol
|
|||
/* TODO */
|
||||
VTR_ASSERT(BLWL_PROTOCOL_SHIFT_REGISTER == config_protocol.bl_protocol_type());
|
||||
}
|
||||
BasicPort cur_bl_addr_port_info = module_manager.module_port(top_module, cur_bl_addr_port);
|
||||
|
||||
ModulePortId cur_wl_addr_port;
|
||||
if (BLWL_PROTOCOL_DECODER == config_protocol.wl_protocol_type()) {
|
||||
|
|
|
@ -144,7 +144,7 @@ void FabricBitstream::set_bit_address(const FabricBitId& bit_id,
|
|||
VTR_ASSERT(true == valid_bit_id(bit_id));
|
||||
VTR_ASSERT(true == use_address_);
|
||||
if (tolerant_short_address) {
|
||||
VTR_ASSERT(address_length_ => address.size());
|
||||
VTR_ASSERT(address_length_ >= address.size());
|
||||
} else {
|
||||
VTR_ASSERT(address_length_ == address.size());
|
||||
}
|
||||
|
@ -164,7 +164,7 @@ void FabricBitstream::set_bit_wl_address(const FabricBitId& bit_id,
|
|||
VTR_ASSERT(true == use_address_);
|
||||
VTR_ASSERT(true == use_wl_address_);
|
||||
if (tolerant_short_address) {
|
||||
VTR_ASSERT(wl_address_length_ => address.size());
|
||||
VTR_ASSERT(wl_address_length_ >= address.size());
|
||||
} else {
|
||||
VTR_ASSERT(wl_address_length_ == address.size());
|
||||
}
|
||||
|
|
|
@ -190,29 +190,40 @@ int write_memory_bank_fabric_bitstream_to_text_file(std::fstream& fp,
|
|||
*******************************************************************/
|
||||
static
|
||||
int write_memory_bank_flatten_fabric_bitstream_to_text_file(std::fstream& fp,
|
||||
const bool& bit_value_to_skip,
|
||||
const FabricBitstream& fabric_bitstream) {
|
||||
int status = 0;
|
||||
|
||||
MemoryBankFabricBitstream fabric_bits_by_addr = build_memory_bank_fabric_bitstream_by_address(fabric_bitstream);
|
||||
MemoryBankFlattenFabricBitstream fabric_bits = build_memory_bank_flatten_fabric_bitstream(fabric_bitstream, bit_value_to_skip);
|
||||
|
||||
/* The address sizes and data input sizes are the same across any element,
|
||||
* just get it from the 1st element to save runtime
|
||||
*/
|
||||
size_t bl_addr_size = fabric_bits_by_addr.begin()->first.first.size();
|
||||
size_t wl_addr_size = fabric_bits_by_addr.begin()->first.second.size();
|
||||
size_t bl_addr_size = 0;
|
||||
for (const auto& bl_vec : fabric_bits.begin()->first) {
|
||||
bl_addr_size += bl_vec.size();
|
||||
}
|
||||
size_t wl_addr_size = 0;
|
||||
for (const auto& wl_vec : fabric_bits.begin()->second) {
|
||||
wl_addr_size += wl_vec.size();
|
||||
}
|
||||
|
||||
/* Output information about how to intepret the bitstream */
|
||||
fp << "// Bitstream length: " << fabric_bits_by_addr.size() << std::endl;
|
||||
fp << "// Bitstream length: " << fabric_bits.size() << std::endl;
|
||||
fp << "// Bitstream width (LSB -> MSB): ";
|
||||
fp << "<bl_address " << bl_addr_size << " bits>";
|
||||
fp << "<wl_address " << wl_addr_size << " bits>";
|
||||
fp << std::endl;
|
||||
|
||||
for (const auto& addr_din_pair : fabric_bits_by_addr) {
|
||||
for (const auto& addr_pair : fabric_bits) {
|
||||
/* Write BL address code */
|
||||
fp << addr_din_pair.first.first;
|
||||
for (const auto& bl_vec : addr_pair.first) {
|
||||
fp << bl_vec;
|
||||
}
|
||||
/* Write WL address code */
|
||||
fp << addr_din_pair.first.second;
|
||||
for (const auto& wl_vec : addr_pair.second) {
|
||||
fp << wl_vec;
|
||||
}
|
||||
fp << std::endl;
|
||||
}
|
||||
|
||||
|
@ -362,6 +373,7 @@ int write_fabric_bitstream_to_text_file(const BitstreamManager& bitstream_manage
|
|||
VTR_ASSERT(BLWL_PROTOCOL_DECODER == config_protocol.bl_protocol_type()
|
||||
|| BLWL_PROTOCOL_SHIFT_REGISTER == config_protocol.bl_protocol_type());
|
||||
status = write_memory_bank_flatten_fabric_bitstream_to_text_file(fp,
|
||||
bit_value_to_skip,
|
||||
fabric_bitstream);
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -232,12 +232,17 @@ MemoryBankFabricBitstream build_memory_bank_fabric_bitstream_by_address(const Fa
|
|||
return fabric_bits_by_addr;
|
||||
}
|
||||
|
||||
MemoryBankFlattenFabricBitstream build_memory_bank_flatten_fabric_bitstream(const FabricBitstream& fabric_bitstream) {
|
||||
MemoryBankFlattenFabricBitstream build_memory_bank_flatten_fabric_bitstream(const FabricBitstream& fabric_bitstream,
|
||||
const bool& bit_value_to_skip) {
|
||||
/* Build the bitstream by each region, here we use (WL, BL) pairs when storing bitstreams */
|
||||
vtr::vector<FabricBitRegionId, std::map<std::string, std::string>> fabric_bits_per_region;
|
||||
fabric_bits_per_region.resize(fabric_bitstream.num_regions());
|
||||
for (const FabricBitRegionId& region : fabric_bitstream.regions()) {
|
||||
for (const FabricBitId& bit_id : fabric_bitstream.region_bits(region)) {
|
||||
/* Skip din because they should be pre-configured through programming reset/set */
|
||||
if ((fabric_bitstream.bit_din(bit_id) == '1') == bit_value_to_skip) {
|
||||
continue;
|
||||
}
|
||||
/* Create string for BL address */
|
||||
std::string bl_addr_str;
|
||||
for (const char& addr_bit : fabric_bitstream.bit_bl_address(bit_id)) {
|
||||
|
@ -264,8 +269,55 @@ MemoryBankFlattenFabricBitstream build_memory_bank_flatten_fabric_bitstream(cons
|
|||
}
|
||||
}
|
||||
|
||||
/* TODO: Combine the bitstream from different region into a unique one. Now we follow the convention: use (BL, WL) pairs */
|
||||
/* Find all the keys for the hash tables containing bitstream of each region */
|
||||
vtr::vector<FabricBitRegionId, std::vector<std::string>> fabric_bits_per_region_keys;
|
||||
fabric_bits_per_region_keys.resize(fabric_bitstream.num_regions());
|
||||
for (const FabricBitRegionId& region : fabric_bitstream.regions()) {
|
||||
/* Pre-allocate memory, because the key size may be large */
|
||||
fabric_bits_per_region_keys[region].reserve(fabric_bits_per_region[region].size());
|
||||
for (const auto& pair : fabric_bits_per_region[region]) {
|
||||
fabric_bits_per_region_keys[region].push_back(pair.first);
|
||||
}
|
||||
}
|
||||
|
||||
/* Find the maxium key size */
|
||||
size_t max_key_size = 0;
|
||||
for (const FabricBitRegionId& region : fabric_bitstream.regions()) {
|
||||
max_key_size = std::max(max_key_size, fabric_bits_per_region_keys[region].size());
|
||||
}
|
||||
|
||||
/* Find the BL/WL sizes per region; Pair convention is (BL, WL)
|
||||
* The address sizes are the same across any element,
|
||||
* just get it from the 1st element to save runtime
|
||||
*/
|
||||
vtr::vector<FabricBitRegionId, std::pair<size_t, size_t>> max_blwl_sizes_per_region;
|
||||
max_blwl_sizes_per_region.resize(fabric_bitstream.num_regions());
|
||||
for (const FabricBitRegionId& region : fabric_bitstream.regions()) {
|
||||
max_blwl_sizes_per_region[region].first = std::max(max_blwl_sizes_per_region[region].first, fabric_bits_per_region[region].begin()->second.size());
|
||||
max_blwl_sizes_per_region[region].second = std::max(max_blwl_sizes_per_region[region].second, fabric_bits_per_region[region].begin()->first.size());
|
||||
}
|
||||
|
||||
/* Combine the bitstream from different region into a unique one. Now we follow the convention: use (BL, WL) pairs */
|
||||
MemoryBankFlattenFabricBitstream fabric_bits;
|
||||
for (size_t ikey = 0; ikey < max_key_size; ikey++) {
|
||||
/* Prepare the final BL/WL vectors to be added to the bitstream database */
|
||||
std::vector<std::string> cur_bl_vectors;
|
||||
std::vector<std::string> cur_wl_vectors;
|
||||
for (const FabricBitRegionId& region : fabric_bitstream.regions()) {
|
||||
/* If the key id is in bound for the key list in this region, find the BL and WL and add to the final bitstream database
|
||||
* If the key id is out of bound for the key list in this region, we append an all-zero string for both BL and WLs
|
||||
*/
|
||||
if (ikey < fabric_bits_per_region_keys[region].size()) {
|
||||
cur_wl_vectors.push_back(fabric_bits_per_region_keys[region][ikey]);
|
||||
cur_bl_vectors.push_back(fabric_bits_per_region[region].at(fabric_bits_per_region_keys[region][ikey]));
|
||||
} else {
|
||||
cur_wl_vectors.push_back(std::string(max_blwl_sizes_per_region[region].second, '0'));
|
||||
cur_bl_vectors.push_back(std::string(max_blwl_sizes_per_region[region].first, '0'));
|
||||
}
|
||||
}
|
||||
/* Add the pair to std map */
|
||||
fabric_bits[cur_bl_vectors] = cur_wl_vectors;
|
||||
}
|
||||
|
||||
return fabric_bits;
|
||||
}
|
||||
|
|
|
@ -58,7 +58,8 @@ size_t find_frame_based_fast_configuration_fabric_bitstream_size(const FabricBit
|
|||
* @note the std::map may cause large memory footprint for large bitstream databases!
|
||||
*******************************************************************/
|
||||
typedef std::map<std::vector<std::string>, std::vector<std::string>> MemoryBankFlattenFabricBitstream;
|
||||
MemoryBankFlattenFabricBitstream build_memory_bank_flatten_fabric_bitstream(const FabricBitstream& fabric_bitstream);
|
||||
MemoryBankFlattenFabricBitstream build_memory_bank_flatten_fabric_bitstream(const FabricBitstream& fabric_bitstream,
|
||||
const bool& bit_value_to_skip);
|
||||
|
||||
/* Alias to a specific organization of bitstreams for memory bank configuration protocol */
|
||||
typedef std::map<std::pair<std::string, std::string>, std::vector<bool>> MemoryBankFabricBitstream;
|
||||
|
|
Loading…
Reference in New Issue