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; 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 */ } /* 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, std::vector<size_t> itobin_vec(const size_t& in_int,
const size_t& bin_len); const size_t& bin_len);
std::vector<char> itobin_charvec(const size_t& in_int,
const size_t& bin_len);
} /* namespace openfpga ends */ } /* namespace openfpga ends */
#endif #endif

View File

@ -158,11 +158,11 @@ void rec_build_module_fabric_dependent_memory_bank_bitstream(const BitstreamMana
/* Find BL address */ /* Find BL address */
size_t cur_bl_index = std::floor(cur_mem_index / num_bls); 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 */ /* Find WL address */
size_t cur_wl_index = cur_mem_index % num_wls; 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 */ /* Set BL address */
fabric_bitstream.set_bit_bl_address(fabric_bit, bl_addr_bits_vec); 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 std::vector<ConfigBlockId>& parent_blocks,
const ModuleManager& module_manager, const ModuleManager& module_manager,
const std::vector<ModuleId>& parent_modules, const std::vector<ModuleId>& parent_modules,
const std::vector<size_t>& addr_code, const std::vector<char>& addr_code,
FabricBitstream& fabric_bitstream) { FabricBitstream& fabric_bitstream) {
/* Depth-first search: if we have any children in the parent_block, /* 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); child_modules.push_back(child_module);
/* Set address, apply binary conversion from the first to the last element in the address list */ /* 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) { if (true == add_addr_code) {
/* Find the address port from the decoder module */ /* 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 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); 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()); 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 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); 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()) { 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()); 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) { 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]; 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()); 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), std::vector<ConfigBlockId>(1, top_block),
module_manager, module_manager,
std::vector<ModuleId>(1, top_module), std::vector<ModuleId>(1, top_module),
std::vector<size_t>(), std::vector<char>(),
fabric_bitstream); fabric_bitstream);
break; break;
} }

View File

@ -27,25 +27,25 @@ ConfigBitId FabricBitstream::config_bit(const FabricBitId& bit_id) const {
return config_bit_ids_[bit_id]; 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 */ /* Ensure a valid id */
VTR_ASSERT(true == valid_bit_id(bit_id)); VTR_ASSERT(true == valid_bit_id(bit_id));
return bit_addresses_[bit_id][0]; 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); 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 */ /* Ensure a valid id */
VTR_ASSERT(true == valid_bit_id(bit_id)); VTR_ASSERT(true == valid_bit_id(bit_id));
return bit_addresses_[bit_id][1]; 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 */ /* Ensure a valid id */
VTR_ASSERT(true == valid_bit_id(bit_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, 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)); VTR_ASSERT(true == valid_bit_id(bit_id));
bit_addresses_[bit_id][0] = address; bit_addresses_[bit_id][0] = address;
} }
void FabricBitstream::set_bit_bl_address(const FabricBitId& bit_id, 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); set_bit_address(bit_id, address);
} }
void FabricBitstream::set_bit_wl_address(const FabricBitId& bit_id, 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)); VTR_ASSERT(true == valid_bit_id(bit_id));
bit_addresses_[bit_id][1] = address; bit_addresses_[bit_id][1] = address;
} }
void FabricBitstream::set_bit_din(const FabricBitId& bit_id, void FabricBitstream::set_bit_din(const FabricBitId& bit_id,
const bool& din) { const char& din) {
VTR_ASSERT(true == valid_bit_id(bit_id)); VTR_ASSERT(true == valid_bit_id(bit_id));
bit_dins_[bit_id] = din; bit_dins_[bit_id] = din;
} }
@ -105,7 +105,7 @@ void FabricBitstream::reverse() {
/****************************************************************************** /******************************************************************************
* Public Validators * 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]); 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; ConfigBitId config_bit(const FabricBitId& bit_id) const;
/* Find the address of bitstream */ /* Find the address of bitstream */
std::vector<size_t> bit_address(const FabricBitId& bit_id) const; std::vector<char> bit_address(const FabricBitId& bit_id) const;
std::vector<size_t> bit_bl_address(const FabricBitId& bit_id) const; std::vector<char> bit_bl_address(const FabricBitId& bit_id) const;
std::vector<size_t> bit_wl_address(const FabricBitId& bit_id) const; std::vector<char> bit_wl_address(const FabricBitId& bit_id) const;
/* Find the data-in of bitstream */ /* 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 */ public: /* Public Mutators */
/* Reserve config bits */ /* Reserve config bits */
@ -67,16 +67,16 @@ class FabricBitstream {
FabricBitId add_bit(const ConfigBitId& config_bit_id); FabricBitId add_bit(const ConfigBitId& config_bit_id);
void set_bit_address(const FabricBitId& 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, 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, 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, void set_bit_din(const FabricBitId& bit_id,
const bool& din); const char& din);
/* Reverse bit sequence of the fabric bitstream /* Reverse bit sequence of the fabric bitstream
* This is required by configuration chain protocol * This is required by configuration chain protocol
@ -84,7 +84,7 @@ class FabricBitstream {
void reverse(); void reverse();
public: /* Public Validators */ public: /* Public Validators */
bool valid_bit_id(const FabricBitId& bit_id) const; char valid_bit_id(const FabricBitId& bit_id) const;
private: /* Internal data */ private: /* Internal data */
/* Unique id of a bit in the Bitstream */ /* 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 * 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 */ /* 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 */ } /* 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)); fp << bitstream_manager.bit_value(fabric_bitstream.config_bit(fabric_bit));
break; break;
case CONFIG_MEM_MEMORY_BANK: { 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; fp << addr_bit;
} }
write_space_to_file(fp, 1); 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; fp << addr_bit;
} }
write_space_to_file(fp, 1); write_space_to_file(fp, 1);
@ -63,7 +63,7 @@ int write_fabric_config_bit_to_text_file(std::fstream& fp,
break; break;
} }
case CONFIG_MEM_FRAME_BASED: { 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; fp << addr_bit;
} }
write_space_to_file(fp, 1); 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 << "\t\t" << std::string(TOP_TESTBENCH_PROG_TASK_NAME);
fp << "(" << bl_addr_port.get_width() << "'b"; fp << "(" << bl_addr_port.get_width() << "'b";
VTR_ASSERT(bl_addr_port.get_width() == fabric_bitstream.bit_bl_address(bit_id).size()); 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 << addr_bit;
} }
fp << ", "; fp << ", ";
fp << wl_addr_port.get_width() << "'b"; fp << wl_addr_port.get_width() << "'b";
VTR_ASSERT(wl_addr_port.get_width() == fabric_bitstream.bit_wl_address(bit_id).size()); 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; 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 << "\t\t" << std::string(TOP_TESTBENCH_PROG_TASK_NAME);
fp << "(" << addr_port.get_width() << "'b"; fp << "(" << addr_port.get_width() << "'b";
VTR_ASSERT(addr_port.get_width() == fabric_bitstream.bit_address(bit_id).size()); 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 << addr_bit;
} }
fp << ", "; fp << ", ";