[FPA-Bistream] Updating fabric bitstream writer to organize bitstream for flatten BL/WLs
This commit is contained in:
parent
a49e3fe57a
commit
8b72447dad
|
@ -80,6 +80,19 @@ std::vector<char> ito1hot_charvec(const size_t& in_int,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string combine_two_1hot_str(const std::string& code1,
|
||||||
|
const std::string& code2) {
|
||||||
|
VTR_ASSERT(code1.length() == code2.length());
|
||||||
|
std::string ret = code1;
|
||||||
|
for (size_t ichar = 0; ichar < code2.length(); ichar++) {
|
||||||
|
VTR_ASSERT('0' == code2[ichar] || '1' == code2[ichar]);
|
||||||
|
if ('1' == code2[ichar]) {
|
||||||
|
ret[ichar] = code2[ichar];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/********************************************************************
|
/********************************************************************
|
||||||
* Converter an integer to a binary vector
|
* Converter an integer to a binary vector
|
||||||
* For example:
|
* For example:
|
||||||
|
|
|
@ -25,6 +25,18 @@ std::vector<size_t> ito1hot_vec(const size_t& in_int,
|
||||||
std::vector<char> ito1hot_charvec(const size_t& in_int,
|
std::vector<char> ito1hot_charvec(const size_t& in_int,
|
||||||
const size_t& bin_len);
|
const size_t& bin_len);
|
||||||
|
|
||||||
|
/********************************************************************
|
||||||
|
* @brief Combine to two 1-hot codes which are in string format
|
||||||
|
* Any unique '1' will be merged
|
||||||
|
* For example:
|
||||||
|
* Code 1: 001000110
|
||||||
|
* Code 2: 010001001
|
||||||
|
* Output: 011001111
|
||||||
|
* @note This function requires two codes in the same length
|
||||||
|
********************************************************************/
|
||||||
|
std::string combine_two_1hot_str(const std::string& code1,
|
||||||
|
const std::string& code2);
|
||||||
|
|
||||||
std::vector<size_t> itobin_vec(const size_t& in_int,
|
std::vector<size_t> itobin_vec(const size_t& in_int,
|
||||||
const size_t& bin_len);
|
const size_t& bin_len);
|
||||||
|
|
||||||
|
|
|
@ -180,6 +180,45 @@ int write_memory_bank_fabric_bitstream_to_text_file(std::fstream& fp,
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/********************************************************************
|
||||||
|
* Write the fabric bitstream fitting a memory bank protocol
|
||||||
|
* to a plain text file
|
||||||
|
*
|
||||||
|
* Return:
|
||||||
|
* - 0 if succeed
|
||||||
|
* - 1 if critical errors occured
|
||||||
|
*******************************************************************/
|
||||||
|
static
|
||||||
|
int write_memory_bank_flatten_fabric_bitstream_to_text_file(std::fstream& fp,
|
||||||
|
const FabricBitstream& fabric_bitstream) {
|
||||||
|
int status = 0;
|
||||||
|
|
||||||
|
MemoryBankFabricBitstream fabric_bits_by_addr = build_memory_bank_fabric_bitstream_by_address(fabric_bitstream);
|
||||||
|
|
||||||
|
/* 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();
|
||||||
|
|
||||||
|
/* Output information about how to intepret the bitstream */
|
||||||
|
fp << "// Bitstream length: " << fabric_bits_by_addr.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) {
|
||||||
|
/* Write BL address code */
|
||||||
|
fp << addr_din_pair.first.first;
|
||||||
|
/* Write WL address code */
|
||||||
|
fp << addr_din_pair.first.second;
|
||||||
|
fp << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
/********************************************************************
|
/********************************************************************
|
||||||
* Write the fabric bitstream fitting a frame-based protocol
|
* Write the fabric bitstream fitting a frame-based protocol
|
||||||
* to a plain text file
|
* to a plain text file
|
||||||
|
@ -306,7 +345,27 @@ int write_fabric_bitstream_to_text_file(const BitstreamManager& bitstream_manage
|
||||||
bitstream_manager,
|
bitstream_manager,
|
||||||
fabric_bitstream);
|
fabric_bitstream);
|
||||||
break;
|
break;
|
||||||
case CONFIG_MEM_QL_MEMORY_BANK:
|
case CONFIG_MEM_QL_MEMORY_BANK: {
|
||||||
|
/* Bitstream organization depends on the BL/WL protocols
|
||||||
|
* - If BL uses decoders, we have to config each memory cell one by one.
|
||||||
|
* - If BL uses flatten, we can configure all the memory cells on the same row by enabling dedicated WL
|
||||||
|
* In such case, we will merge the BL data under the same WL address
|
||||||
|
* Fast configuration is NOT applicable in this case
|
||||||
|
* - if BL uses shift-register, TODO
|
||||||
|
*/
|
||||||
|
if (BLWL_PROTOCOL_DECODER == config_protocol.bl_protocol_type()) {
|
||||||
|
status = write_memory_bank_fabric_bitstream_to_text_file(fp,
|
||||||
|
apply_fast_configuration,
|
||||||
|
bit_value_to_skip,
|
||||||
|
fabric_bitstream);
|
||||||
|
} else {
|
||||||
|
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,
|
||||||
|
fabric_bitstream);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
case CONFIG_MEM_MEMORY_BANK:
|
case CONFIG_MEM_MEMORY_BANK:
|
||||||
status = write_memory_bank_fabric_bitstream_to_text_file(fp,
|
status = write_memory_bank_fabric_bitstream_to_text_file(fp,
|
||||||
apply_fast_configuration,
|
apply_fast_configuration,
|
||||||
|
|
|
@ -188,7 +188,7 @@ size_t find_frame_based_fast_configuration_fabric_bitstream_size(const FabricBit
|
||||||
}
|
}
|
||||||
|
|
||||||
/********************************************************************
|
/********************************************************************
|
||||||
* Reorganize the fabric bitstream for memory banks
|
* Reorganize the fabric bitstream for memory banks which use BL and WL decoders
|
||||||
* by the same address across regions:
|
* by the same address across regions:
|
||||||
* This is due to that the length of fabric bitstream could be different in each region.
|
* This is due to that the length of fabric bitstream could be different in each region.
|
||||||
* Template:
|
* Template:
|
||||||
|
@ -232,6 +232,45 @@ MemoryBankFabricBitstream build_memory_bank_fabric_bitstream_by_address(const Fa
|
||||||
return fabric_bits_by_addr;
|
return fabric_bits_by_addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MemoryBankFlattenFabricBitstream build_memory_bank_flatten_fabric_bitstream(const FabricBitstream& fabric_bitstream) {
|
||||||
|
/* 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)) {
|
||||||
|
/* Create string for BL address */
|
||||||
|
std::string bl_addr_str;
|
||||||
|
for (const char& addr_bit : fabric_bitstream.bit_bl_address(bit_id)) {
|
||||||
|
bl_addr_str.push_back(addr_bit);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create string for WL address */
|
||||||
|
std::string wl_addr_str;
|
||||||
|
for (const char& addr_bit : fabric_bitstream.bit_wl_address(bit_id)) {
|
||||||
|
wl_addr_str.push_back(addr_bit);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Place the config bit */
|
||||||
|
auto result = fabric_bits_per_region[region].find(wl_addr_str);
|
||||||
|
if (result == fabric_bits_per_region[region].end()) {
|
||||||
|
/* This is a new bit, resize the vector to the number of regions
|
||||||
|
* and deposit '0' to all the bits
|
||||||
|
*/
|
||||||
|
fabric_bits_per_region[region][wl_addr_str] = bl_addr_str;
|
||||||
|
} else {
|
||||||
|
VTR_ASSERT_SAFE(result != fabric_bits_per_region[region].end());
|
||||||
|
result->second = combine_two_1hot_str(bl_addr_str, result->second);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TODO: Combine the bitstream from different region into a unique one. Now we follow the convention: use (BL, WL) pairs */
|
||||||
|
MemoryBankFlattenFabricBitstream fabric_bits;
|
||||||
|
|
||||||
|
return fabric_bits;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/********************************************************************
|
/********************************************************************
|
||||||
* For fast configuration, the number of bits to be skipped
|
* For fast configuration, the number of bits to be skipped
|
||||||
* the rule to skip any configuration bit should consider the whole data input values.
|
* the rule to skip any configuration bit should consider the whole data input values.
|
||||||
|
|
|
@ -37,6 +37,29 @@ FrameFabricBitstream build_frame_based_fabric_bitstream_by_address(const FabricB
|
||||||
size_t find_frame_based_fast_configuration_fabric_bitstream_size(const FabricBitstream& fabric_bitstream,
|
size_t find_frame_based_fast_configuration_fabric_bitstream_size(const FabricBitstream& fabric_bitstream,
|
||||||
const bool& bit_value_to_skip);
|
const bool& bit_value_to_skip);
|
||||||
|
|
||||||
|
/********************************************************************
|
||||||
|
* @ brief Reorganize the fabric bitstream for memory banks which use flatten or shift register to manipulate BL and WLs
|
||||||
|
* For each configuration region, we will merge BL address (which are 1-hot codes) under the same WL address
|
||||||
|
*
|
||||||
|
* Quick Example
|
||||||
|
* <bl of region A>_<bl of region B> <wl of region A>_<wl of region B>
|
||||||
|
* An example:
|
||||||
|
* 010_111 000_101
|
||||||
|
*
|
||||||
|
* Note that all the BL/WLs across configuration regions are independent. We will combine them together
|
||||||
|
* Quick Example
|
||||||
|
* <bl of region A>_<bl of region B> <wl of region A>_<wl of region B>
|
||||||
|
* 001_010 000_000
|
||||||
|
* 100_100 000_000
|
||||||
|
*
|
||||||
|
* the bitstream will be merged as
|
||||||
|
* 101_110 000_000
|
||||||
|
*
|
||||||
|
* @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);
|
||||||
|
|
||||||
/* Alias to a specific organization of bitstreams for memory bank configuration protocol */
|
/* 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;
|
typedef std::map<std::pair<std::string, std::string>, std::vector<bool>> MemoryBankFabricBitstream;
|
||||||
MemoryBankFabricBitstream build_memory_bank_fabric_bitstream_by_address(const FabricBitstream& fabric_bitstream);
|
MemoryBankFabricBitstream build_memory_bank_fabric_bitstream_by_address(const FabricBitstream& fabric_bitstream);
|
||||||
|
|
Loading…
Reference in New Issue