From 2a9377b3f45a0c58c45ac1b68356f218d267c119 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Fri, 3 Jul 2020 15:12:29 -0600 Subject: [PATCH] use encoded address in storage of fabric bitstream to save memory --- .../libopenfpgautil/src/openfpga_decode.cpp | 25 ++++++++++++++++ .../libopenfpgautil/src/openfpga_decode.h | 2 ++ .../fpga_bitstream/build_fabric_bitstream.cpp | 17 ++++++++--- .../src/fpga_bitstream/fabric_bitstream.cpp | 29 ++++++++++++++++--- .../src/fpga_bitstream/fabric_bitstream.h | 10 +++++-- 5 files changed, 73 insertions(+), 10 deletions(-) diff --git a/libopenfpga/libopenfpgautil/src/openfpga_decode.cpp b/libopenfpga/libopenfpgautil/src/openfpga_decode.cpp index fb0e32a37..168f98e42 100644 --- a/libopenfpga/libopenfpgautil/src/openfpga_decode.cpp +++ b/libopenfpga/libopenfpgautil/src/openfpga_decode.cpp @@ -103,4 +103,29 @@ std::vector itobin_charvec(const size_t& in_int, return ret; } +/******************************************************************** + * Converter a binary vector to an integer + * For example: + * Binary length : 3 + * Input: + * index | 0 | 1 | 2 + * ret | 0 | 0 | 1 + * + * Output integer: 4 + * + * This function is optimized to return a vector of char + * which has a smaller memory footprint than size_t + ********************************************************************/ +size_t bintoi_charvec(const std::vector& bin) { + size_t ret = 0; + + for (size_t i = 0; i < bin.size(); ++i) { + if ('1' == bin[i]) { + ret += pow(2., i); + } + } + + return ret; +} + } /* end namespace openfpga */ diff --git a/libopenfpga/libopenfpgautil/src/openfpga_decode.h b/libopenfpga/libopenfpgautil/src/openfpga_decode.h index 064717fbc..ab6778c86 100644 --- a/libopenfpga/libopenfpgautil/src/openfpga_decode.h +++ b/libopenfpga/libopenfpgautil/src/openfpga_decode.h @@ -21,6 +21,8 @@ std::vector itobin_vec(const size_t& in_int, std::vector itobin_charvec(const size_t& in_int, const size_t& bin_len); +size_t bintoi_charvec(const std::vector& bin); + } /* namespace openfpga ends */ #endif diff --git a/openfpga/src/fpga_bitstream/build_fabric_bitstream.cpp b/openfpga/src/fpga_bitstream/build_fabric_bitstream.cpp index 38724aad8..b960d188a 100644 --- a/openfpga/src/fpga_bitstream/build_fabric_bitstream.cpp +++ b/openfpga/src/fpga_bitstream/build_fabric_bitstream.cpp @@ -398,10 +398,6 @@ void build_module_fabric_dependent_bitstream(const ConfigProtocol& config_protoc break; } case CONFIG_MEM_MEMORY_BANK: { - /* Reserve bits before build-up */ - fabric_bitstream.set_use_address(true); - fabric_bitstream.set_use_wl_address(true); - fabric_bitstream.reserve_bits(bitstream_manager.num_bits()); size_t cur_mem_index = 0; /* Find BL address port size */ @@ -426,6 +422,13 @@ void build_module_fabric_dependent_bitstream(const ConfigProtocol& config_protoc ModulePortId wl_port = module_manager.find_module_port(wl_decoder_module, std::string(DECODER_DATA_OUT_PORT_NAME)); BasicPort wl_port_info = module_manager.module_port(wl_decoder_module, wl_port); + /* Reserve bits before build-up */ + fabric_bitstream.set_use_address(true); + fabric_bitstream.set_use_wl_address(true); + fabric_bitstream.set_bl_address_length(bl_port_info.get_width()); + fabric_bitstream.set_wl_address_length(wl_port_info.get_width()); + fabric_bitstream.reserve_bits(bitstream_manager.num_bits()); + rec_build_module_fabric_dependent_memory_bank_bitstream(bitstream_manager, top_block, module_manager, top_module, top_module, bl_addr_port_info.get_width(), @@ -436,9 +439,15 @@ void build_module_fabric_dependent_bitstream(const ConfigProtocol& config_protoc break; } case CONFIG_MEM_FRAME_BASED: { + + /* Find address port size */ + ModulePortId addr_port = module_manager.find_module_port(top_module, std::string(DECODER_ADDRESS_PORT_NAME)); + BasicPort addr_port_info = module_manager.module_port(top_module, addr_port); + /* Reserve bits before build-up */ fabric_bitstream.set_use_address(true); fabric_bitstream.reserve_bits(bitstream_manager.num_bits()); + fabric_bitstream.set_address_length(addr_port_info.get_width()); rec_build_module_fabric_dependent_frame_bitstream(bitstream_manager, std::vector(1, top_block), diff --git a/openfpga/src/fpga_bitstream/fabric_bitstream.cpp b/openfpga/src/fpga_bitstream/fabric_bitstream.cpp index f8f3a956f..750cc0296 100644 --- a/openfpga/src/fpga_bitstream/fabric_bitstream.cpp +++ b/openfpga/src/fpga_bitstream/fabric_bitstream.cpp @@ -4,6 +4,7 @@ #include #include "vtr_assert.h" +#include "openfpga_decode.h" #include "fabric_bitstream.h" /* begin namespace openfpga */ @@ -15,6 +16,8 @@ namespace openfpga { FabricBitstream::FabricBitstream() { num_bits_ = 0; invalid_bit_ids_.clear(); + address_length_ = 0; + wl_address_length_ = 0; } /************************************************** @@ -45,7 +48,7 @@ std::vector FabricBitstream::bit_address(const FabricBitId& bit_id) const VTR_ASSERT(true == valid_bit_id(bit_id)); VTR_ASSERT(true == use_address_); - return bit_addresses_[bit_id]; + return itobin_charvec(bit_addresses_[bit_id], address_length_); } std::vector FabricBitstream::bit_bl_address(const FabricBitId& bit_id) const { @@ -58,7 +61,7 @@ std::vector FabricBitstream::bit_wl_address(const FabricBitId& bit_id) con VTR_ASSERT(true == use_address_); VTR_ASSERT(true == use_wl_address_); - return bit_wl_addresses_[bit_id]; + return itobin_charvec(bit_wl_addresses_[bit_id], wl_address_length_); } char FabricBitstream::bit_din(const FabricBitId& bit_id) const { @@ -106,7 +109,8 @@ void FabricBitstream::set_bit_address(const FabricBitId& bit_id, const std::vector& address) { VTR_ASSERT(true == valid_bit_id(bit_id)); VTR_ASSERT(true == use_address_); - bit_addresses_[bit_id] = address; + VTR_ASSERT(address_length_ == address.size()); + bit_addresses_[bit_id] = bintoi_charvec(address); } void FabricBitstream::set_bit_bl_address(const FabricBitId& bit_id, @@ -119,7 +123,8 @@ void FabricBitstream::set_bit_wl_address(const FabricBitId& bit_id, VTR_ASSERT(true == valid_bit_id(bit_id)); VTR_ASSERT(true == use_address_); VTR_ASSERT(true == use_wl_address_); - bit_wl_addresses_[bit_id] = address; + VTR_ASSERT(wl_address_length_ == address.size()); + bit_wl_addresses_[bit_id] = bintoi_charvec(address); } void FabricBitstream::set_bit_din(const FabricBitId& bit_id, @@ -149,6 +154,16 @@ void FabricBitstream::set_use_address(const bool& enable) { } } +void FabricBitstream::set_address_length(const size_t& length) { + if (true == use_address_) { + address_length_ = length; + } +} + +void FabricBitstream::set_bl_address_length(const size_t& length) { + set_address_length(length); +} + void FabricBitstream::set_use_wl_address(const bool& enable) { /* Add a lock, only can be modified when num bits are zero*/ if (0 == num_bits_) { @@ -156,6 +171,12 @@ void FabricBitstream::set_use_wl_address(const bool& enable) { } } +void FabricBitstream::set_wl_address_length(const size_t& length) { + if (true == use_address_) { + wl_address_length_ = length; + } +} + /****************************************************************************** * Public Validators ******************************************************************************/ diff --git a/openfpga/src/fpga_bitstream/fabric_bitstream.h b/openfpga/src/fpga_bitstream/fabric_bitstream.h index ea64b4590..9869fffed 100644 --- a/openfpga/src/fpga_bitstream/fabric_bitstream.h +++ b/openfpga/src/fpga_bitstream/fabric_bitstream.h @@ -152,11 +152,14 @@ class FabricBitstream { * This function is only applicable before any bits are added */ void set_use_address(const bool& enable); + void set_address_length(const size_t& length); + void set_bl_address_length(const size_t& length); /* Enable the use of WL-address related data * Same priniciple as the set_use_address() */ void set_use_wl_address(const bool& enable); + void set_wl_address_length(const size_t& length); public: /* Public Validators */ char valid_bit_id(const FabricBitId& bit_id) const; @@ -171,14 +174,17 @@ class FabricBitstream { bool use_address_; bool use_wl_address_; + size_t address_length_; + size_t wl_address_length_; + /* Address bits: this is designed for memory decoders * Here we store the binary format of the address, which can be loaded * to the configuration protocol directly * * We use a 2-element array, as we may have a BL address and a WL address */ - vtr::vector> bit_addresses_; - vtr::vector> bit_wl_addresses_; + vtr::vector bit_addresses_; + vtr::vector bit_wl_addresses_; /* Data input (Din) bits: this is designed for memory decoders */ vtr::vector bit_dins_;