[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;
|
||||
}
|
||||
|
||||
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
|
||||
* 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,
|
||||
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,
|
||||
const size_t& bin_len);
|
||||
|
||||
|
|
|
@ -180,6 +180,45 @@ int write_memory_bank_fabric_bitstream_to_text_file(std::fstream& fp,
|
|||
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
|
||||
* to a plain text file
|
||||
|
@ -306,7 +345,27 @@ int write_fabric_bitstream_to_text_file(const BitstreamManager& bitstream_manage
|
|||
bitstream_manager,
|
||||
fabric_bitstream);
|
||||
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:
|
||||
status = write_memory_bank_fabric_bitstream_to_text_file(fp,
|
||||
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:
|
||||
* This is due to that the length of fabric bitstream could be different in each region.
|
||||
* Template:
|
||||
|
@ -232,6 +232,45 @@ 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) {
|
||||
/* 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
|
||||
* 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,
|
||||
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 */
|
||||
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);
|
||||
|
|
Loading…
Reference in New Issue