use char in fabric bitstream to save memory footprint

This commit is contained in:
tangxifan 2020-07-02 15:56:50 -06:00
parent 405824081b
commit 9f19c36a89
7 changed files with 68 additions and 35 deletions

View File

@ -73,4 +73,34 @@ std::vector<size_t> itobin_vec(const size_t& in_int,
return ret;
}
/********************************************************************
* Converter an integer to a binary vector
* For example:
* Input integer: 4
* Binary length : 3
* Output:
* index | 0 | 1 | 2
* ret | 0 | 0 | 1
*
* This function is optimized to return a vector of char
* which has a smaller memory footprint than size_t
********************************************************************/
std::vector<char> itobin_charvec(const size_t& in_int,
const size_t& bin_len) {
std::vector<char> ret(bin_len, '0');
/* Make sure we do not have any overflow! */
VTR_ASSERT ( (in_int < pow(2., bin_len)) );
size_t temp = in_int;
for (size_t i = 0; i < bin_len; i++) {
if (1 == temp % 2) {
ret[i] = '1'; /* Keep a good sequence of bits */
}
temp = temp / 2;
}
return ret;
}
} /* end namespace openfpga */

View File

@ -18,6 +18,9 @@ std::vector<size_t> ito1hot_vec(const size_t& in_int,
std::vector<size_t> itobin_vec(const size_t& in_int,
const size_t& bin_len);
std::vector<char> itobin_charvec(const size_t& in_int,
const size_t& bin_len);
} /* namespace openfpga ends */
#endif

View File

@ -158,11 +158,11 @@ void rec_build_module_fabric_dependent_memory_bank_bitstream(const BitstreamMana
/* Find BL address */
size_t cur_bl_index = std::floor(cur_mem_index / num_bls);
std::vector<size_t> bl_addr_bits_vec = itobin_vec(cur_bl_index, bl_addr_size);
std::vector<char> bl_addr_bits_vec = itobin_charvec(cur_bl_index, bl_addr_size);
/* Find WL address */
size_t cur_wl_index = cur_mem_index % num_wls;
std::vector<size_t> wl_addr_bits_vec = itobin_vec(cur_wl_index, wl_addr_size);
std::vector<char> wl_addr_bits_vec = itobin_charvec(cur_wl_index, wl_addr_size);
/* Set BL address */
fabric_bitstream.set_bit_bl_address(fabric_bit, bl_addr_bits_vec);
@ -206,7 +206,7 @@ void rec_build_module_fabric_dependent_frame_bitstream(const BitstreamManager& b
const std::vector<ConfigBlockId>& parent_blocks,
const ModuleManager& module_manager,
const std::vector<ModuleId>& parent_modules,
const std::vector<size_t>& addr_code,
const std::vector<char>& addr_code,
FabricBitstream& fabric_bitstream) {
/* Depth-first search: if we have any children in the parent_block,
@ -272,13 +272,13 @@ void rec_build_module_fabric_dependent_frame_bitstream(const BitstreamManager& b
child_modules.push_back(child_module);
/* Set address, apply binary conversion from the first to the last element in the address list */
std::vector<size_t> child_addr_code = addr_code;
std::vector<char> child_addr_code = addr_code;
if (true == add_addr_code) {
/* Find the address port from the decoder module */
const ModulePortId& decoder_addr_port_id = module_manager.find_module_port(decoder_module, std::string(DECODER_ADDRESS_PORT_NAME));
const BasicPort& decoder_addr_port = module_manager.module_port(decoder_module, decoder_addr_port_id);
std::vector<size_t> addr_bits_vec = itobin_vec(child_id, decoder_addr_port.get_width());
std::vector<char> addr_bits_vec = itobin_charvec(child_id, decoder_addr_port.get_width());
child_addr_code.insert(child_addr_code.begin(), addr_bits_vec.begin(), addr_bits_vec.end());
@ -316,7 +316,7 @@ void rec_build_module_fabric_dependent_frame_bitstream(const BitstreamManager& b
const ModulePortId& child_addr_port_id = module_manager.find_module_port(child_module, std::string(DECODER_ADDRESS_PORT_NAME));
const BasicPort& child_addr_port = module_manager.module_port(child_module, child_addr_port_id);
if (0 < max_child_addr_code_size - child_addr_port.get_width()) {
std::vector<size_t> dummy_codes(max_child_addr_code_size - child_addr_port.get_width(), 0);
std::vector<char> dummy_codes(max_child_addr_code_size - child_addr_port.get_width(), '0');
child_addr_code.insert(child_addr_code.begin(), dummy_codes.begin(), dummy_codes.end());
}
}
@ -349,9 +349,9 @@ void rec_build_module_fabric_dependent_frame_bitstream(const BitstreamManager& b
for (size_t ibit = 0; ibit < bitstream_manager.block_bits(parent_blocks.back()).size(); ++ibit) {
ConfigBitId config_bit = bitstream_manager.block_bits(parent_blocks.back())[ibit];
std::vector<size_t> addr_bits_vec = itobin_vec(ibit, decoder_addr_port.get_width());
std::vector<char> addr_bits_vec = itobin_charvec(ibit, decoder_addr_port.get_width());
std::vector<size_t> child_addr_code = addr_code;
std::vector<char> child_addr_code = addr_code;
child_addr_code.insert(child_addr_code.begin(), addr_bits_vec.begin(), addr_bits_vec.end());
@ -429,7 +429,7 @@ void build_module_fabric_dependent_bitstream(const ConfigProtocol& config_protoc
std::vector<ConfigBlockId>(1, top_block),
module_manager,
std::vector<ModuleId>(1, top_module),
std::vector<size_t>(),
std::vector<char>(),
fabric_bitstream);
break;
}

View File

@ -27,25 +27,25 @@ ConfigBitId FabricBitstream::config_bit(const FabricBitId& bit_id) const {
return config_bit_ids_[bit_id];
}
std::vector<size_t> FabricBitstream::bit_address(const FabricBitId& bit_id) const {
std::vector<char> FabricBitstream::bit_address(const FabricBitId& bit_id) const {
/* Ensure a valid id */
VTR_ASSERT(true == valid_bit_id(bit_id));
return bit_addresses_[bit_id][0];
}
std::vector<size_t> FabricBitstream::bit_bl_address(const FabricBitId& bit_id) const {
std::vector<char> FabricBitstream::bit_bl_address(const FabricBitId& bit_id) const {
return bit_address(bit_id);
}
std::vector<size_t> FabricBitstream::bit_wl_address(const FabricBitId& bit_id) const {
std::vector<char> FabricBitstream::bit_wl_address(const FabricBitId& bit_id) const {
/* Ensure a valid id */
VTR_ASSERT(true == valid_bit_id(bit_id));
return bit_addresses_[bit_id][1];
}
bool FabricBitstream::bit_din(const FabricBitId& bit_id) const {
char FabricBitstream::bit_din(const FabricBitId& bit_id) const {
/* Ensure a valid id */
VTR_ASSERT(true == valid_bit_id(bit_id));
@ -74,24 +74,24 @@ FabricBitId FabricBitstream::add_bit(const ConfigBitId& config_bit_id) {
}
void FabricBitstream::set_bit_address(const FabricBitId& bit_id,
const std::vector<size_t>& address) {
const std::vector<char>& address) {
VTR_ASSERT(true == valid_bit_id(bit_id));
bit_addresses_[bit_id][0] = address;
}
void FabricBitstream::set_bit_bl_address(const FabricBitId& bit_id,
const std::vector<size_t>& address) {
const std::vector<char>& address) {
set_bit_address(bit_id, address);
}
void FabricBitstream::set_bit_wl_address(const FabricBitId& bit_id,
const std::vector<size_t>& address) {
const std::vector<char>& address) {
VTR_ASSERT(true == valid_bit_id(bit_id));
bit_addresses_[bit_id][1] = address;
}
void FabricBitstream::set_bit_din(const FabricBitId& bit_id,
const bool& din) {
const char& din) {
VTR_ASSERT(true == valid_bit_id(bit_id));
bit_dins_[bit_id] = din;
}
@ -105,7 +105,7 @@ void FabricBitstream::reverse() {
/******************************************************************************
* Public Validators
******************************************************************************/
bool FabricBitstream::valid_bit_id(const FabricBitId& bit_id) const {
char FabricBitstream::valid_bit_id(const FabricBitId& bit_id) const {
return (size_t(bit_id) < bit_ids_.size()) && (bit_id == bit_ids_[bit_id]);
}

View File

@ -52,12 +52,12 @@ class FabricBitstream {
ConfigBitId config_bit(const FabricBitId& bit_id) const;
/* Find the address of bitstream */
std::vector<size_t> bit_address(const FabricBitId& bit_id) const;
std::vector<size_t> bit_bl_address(const FabricBitId& bit_id) const;
std::vector<size_t> bit_wl_address(const FabricBitId& bit_id) const;
std::vector<char> bit_address(const FabricBitId& bit_id) const;
std::vector<char> bit_bl_address(const FabricBitId& bit_id) const;
std::vector<char> bit_wl_address(const FabricBitId& bit_id) const;
/* Find the data-in of bitstream */
bool bit_din(const FabricBitId& bit_id) const;
char bit_din(const FabricBitId& bit_id) const;
public: /* Public Mutators */
/* Reserve config bits */
@ -67,16 +67,16 @@ class FabricBitstream {
FabricBitId add_bit(const ConfigBitId& config_bit_id);
void set_bit_address(const FabricBitId& bit_id,
const std::vector<size_t>& address);
const std::vector<char>& address);
void set_bit_bl_address(const FabricBitId& bit_id,
const std::vector<size_t>& address);
const std::vector<char>& address);
void set_bit_wl_address(const FabricBitId& bit_id,
const std::vector<size_t>& address);
const std::vector<char>& address);
void set_bit_din(const FabricBitId& bit_id,
const bool& din);
const char& din);
/* Reverse bit sequence of the fabric bitstream
* This is required by configuration chain protocol
@ -84,7 +84,7 @@ class FabricBitstream {
void reverse();
public: /* Public Validators */
bool valid_bit_id(const FabricBitId& bit_id) const;
char valid_bit_id(const FabricBitId& bit_id) const;
private: /* Internal data */
/* Unique id of a bit in the Bitstream */
@ -97,10 +97,10 @@ class FabricBitstream {
*
* We use a 2-element array, as we may have a BL address and a WL address
*/
vtr::vector<FabricBitId, std::array<std::vector<size_t>, 2>> bit_addresses_;
vtr::vector<FabricBitId, std::array<std::vector<char>, 2>> bit_addresses_;
/* Data input (Din) bits: this is designed for memory decoders */
vtr::vector<FabricBitId, bool> bit_dins_;
vtr::vector<FabricBitId, char> bit_dins_;
};
} /* end namespace openfpga */

View File

@ -50,11 +50,11 @@ int write_fabric_config_bit_to_text_file(std::fstream& fp,
fp << bitstream_manager.bit_value(fabric_bitstream.config_bit(fabric_bit));
break;
case CONFIG_MEM_MEMORY_BANK: {
for (const size_t& addr_bit : fabric_bitstream.bit_bl_address(fabric_bit)) {
for (const char& addr_bit : fabric_bitstream.bit_bl_address(fabric_bit)) {
fp << addr_bit;
}
write_space_to_file(fp, 1);
for (const size_t& addr_bit : fabric_bitstream.bit_wl_address(fabric_bit)) {
for (const char& addr_bit : fabric_bitstream.bit_wl_address(fabric_bit)) {
fp << addr_bit;
}
write_space_to_file(fp, 1);
@ -63,7 +63,7 @@ int write_fabric_config_bit_to_text_file(std::fstream& fp,
break;
}
case CONFIG_MEM_FRAME_BASED: {
for (const size_t& addr_bit : fabric_bitstream.bit_address(fabric_bit)) {
for (const char& addr_bit : fabric_bitstream.bit_address(fabric_bit)) {
fp << addr_bit;
}
write_space_to_file(fp, 1);

View File

@ -1223,14 +1223,14 @@ void print_verilog_top_testbench_memory_bank_bitstream(std::fstream& fp,
fp << "\t\t" << std::string(TOP_TESTBENCH_PROG_TASK_NAME);
fp << "(" << bl_addr_port.get_width() << "'b";
VTR_ASSERT(bl_addr_port.get_width() == fabric_bitstream.bit_bl_address(bit_id).size());
for (const size_t& addr_bit : fabric_bitstream.bit_bl_address(bit_id)) {
for (const char& addr_bit : fabric_bitstream.bit_bl_address(bit_id)) {
fp << addr_bit;
}
fp << ", ";
fp << wl_addr_port.get_width() << "'b";
VTR_ASSERT(wl_addr_port.get_width() == fabric_bitstream.bit_wl_address(bit_id).size());
for (const size_t& addr_bit : fabric_bitstream.bit_wl_address(bit_id)) {
for (const char& addr_bit : fabric_bitstream.bit_wl_address(bit_id)) {
fp << addr_bit;
}
@ -1319,7 +1319,7 @@ void print_verilog_top_testbench_frame_decoder_bitstream(std::fstream& fp,
fp << "\t\t" << std::string(TOP_TESTBENCH_PROG_TASK_NAME);
fp << "(" << addr_port.get_width() << "'b";
VTR_ASSERT(addr_port.get_width() == fabric_bitstream.bit_address(bit_id).size());
for (const size_t& addr_bit : fabric_bitstream.bit_address(bit_id)) {
for (const char& addr_bit : fabric_bitstream.bit_address(bit_id)) {
fp << addr_bit;
}
fp << ", ";