diff --git a/openfpga/src/fabric/build_top_module.cpp b/openfpga/src/fabric/build_top_module.cpp index 2aad3f1f4..76da64d9f 100644 --- a/openfpga/src/fabric/build_top_module.cpp +++ b/openfpga/src/fabric/build_top_module.cpp @@ -428,12 +428,14 @@ int build_top_module(ModuleManager& module_manager, /* Add module nets to connect memory cells inside * This is a one-shot addition that covers all the memory modules in this pb module! */ - if (0 < module_manager.configurable_children(top_module).size()) { - add_top_module_nets_memory_config_bus(module_manager, decoder_lib, blwl_sr_banks, - top_module, - circuit_lib, - config_protocol, circuit_lib.design_tech_type(sram_model), - top_module_num_config_bits); + if (false == frame_view) { + if (0 < module_manager.configurable_children(top_module).size()) { + add_top_module_nets_memory_config_bus(module_manager, decoder_lib, blwl_sr_banks, + top_module, + circuit_lib, + config_protocol, circuit_lib.design_tech_type(sram_model), + top_module_num_config_bits); + } } /* Add global ports to the top module: diff --git a/openfpga/src/fpga_bitstream/fabric_bitstream.cpp b/openfpga/src/fpga_bitstream/fabric_bitstream.cpp index baa282991..f622f3fbc 100644 --- a/openfpga/src/fpga_bitstream/fabric_bitstream.cpp +++ b/openfpga/src/fpga_bitstream/fabric_bitstream.cpp @@ -72,7 +72,14 @@ std::vector FabricBitstream::bit_address(const FabricBitId& bit_id) const VTR_ASSERT(true == use_address_); /* Decode address bits */ - return decode_address_bits(bit_address_1bits_[bit_id], bit_address_xbits_[bit_id]); + std::vector addr_bits; + addr_bits.reserve(address_length_); + for (size_t curr_idx = 0; curr_idx < bit_address_1bits_[bit_id].size(); curr_idx++) { + size_t curr_addr_len = std::min(size_t(64), address_length_ - curr_idx * 64); + std::vector curr_addr_vec = decode_address_bits(bit_address_1bits_[bit_id][curr_idx], bit_address_xbits_[bit_id][curr_idx], curr_addr_len); + addr_bits.insert(addr_bits.end(), curr_addr_vec.begin(), curr_addr_vec.end()); + } + return addr_bits; } std::vector FabricBitstream::bit_bl_address(const FabricBitId& bit_id) const { @@ -85,7 +92,15 @@ std::vector FabricBitstream::bit_wl_address(const FabricBitId& bit_id) con VTR_ASSERT(true == use_address_); VTR_ASSERT(true == use_wl_address_); - return decode_wl_address_bits(bit_wl_address_1bits_[bit_id], bit_wl_address_xbits_[bit_id]); + /* Decode address bits */ + std::vector addr_bits; + addr_bits.reserve(wl_address_length_); + for (size_t curr_idx = 0; curr_idx < bit_wl_address_1bits_[bit_id].size(); curr_idx++) { + size_t curr_addr_len = std::min(size_t(64), wl_address_length_ - curr_idx * 64); + std::vector curr_addr_vec = decode_address_bits(bit_wl_address_1bits_[bit_id][curr_idx], bit_wl_address_xbits_[bit_id][curr_idx], curr_addr_len); + addr_bits.insert(addr_bits.end(), curr_addr_vec.begin(), curr_addr_vec.end()); + } + return addr_bits; } char FabricBitstream::bit_din(const FabricBitId& bit_id) const { @@ -152,9 +167,14 @@ void FabricBitstream::set_bit_address(const FabricBitId& bit_id, } else { VTR_ASSERT(address_length_ == address.size()); } - /* Encode bit '1' and bit 'x' into two numbers */ - bit_address_1bits_[bit_id] = encode_address_1bits(address); - bit_address_xbits_[bit_id] = encode_address_xbits(address); + /* Split the address into several 64 vectors */ + for (size_t start_idx = 0; start_idx < address.size(); start_idx = start_idx + 64) { + size_t curr_end_idx = std::min(address.size(), start_idx + 64); + std::vector curr_addr_vec64(address.begin() + start_idx, address.begin() + curr_end_idx); + /* Encode bit '1' and bit 'x' into two numbers */ + bit_address_1bits_[bit_id].push_back(encode_address_1bits(curr_addr_vec64)); + bit_address_xbits_[bit_id].push_back(encode_address_xbits(curr_addr_vec64)); + } } void FabricBitstream::set_bit_bl_address(const FabricBitId& bit_id, @@ -174,9 +194,14 @@ void FabricBitstream::set_bit_wl_address(const FabricBitId& bit_id, } else { VTR_ASSERT(wl_address_length_ == address.size()); } - /* Encode bit '1' and bit 'x' into two numbers */ - bit_wl_address_1bits_[bit_id] = encode_address_1bits(address); - bit_wl_address_xbits_[bit_id] = encode_address_xbits(address); + /* Split the address into several 64 vectors */ + for (size_t start_idx = 0; start_idx < address.size(); start_idx = start_idx + 64) { + size_t curr_end_idx = std::min(address.size(), start_idx + 64); + std::vector curr_addr_vec64(address.begin() + start_idx, address.begin() + curr_end_idx); + /* Encode bit '1' and bit 'x' into two numbers */ + bit_wl_address_1bits_[bit_id].push_back(encode_address_1bits(curr_addr_vec64)); + bit_wl_address_xbits_[bit_id].push_back(encode_address_xbits(curr_addr_vec64)); + } } void FabricBitstream::set_bit_din(const FabricBitId& bit_id, @@ -269,7 +294,7 @@ bool FabricBitstream::valid_region_id(const FabricBitRegionId& region_id) const return (size_t(region_id) < num_regions_); } -size_t FabricBitstream::encode_address_1bits(const std::vector& address) const { +uint64_t FabricBitstream::encode_address_1bits(const std::vector& address) const { /* Convert all the 'x' bit into 0 */ std::vector binary_address = address; for (char& bit : binary_address) { @@ -278,10 +303,10 @@ size_t FabricBitstream::encode_address_1bits(const std::vector& address) c } } /* Convert the binary address to a number */ - return bintoi_charvec(binary_address); + return (uint64_t)bintoi_charvec(binary_address); } -size_t FabricBitstream::encode_address_xbits(const std::vector& address) const { +uint64_t FabricBitstream::encode_address_xbits(const std::vector& address) const { /* Convert all the '1' bit into 0 and Convert all the 'x' bit into 1 */ std::vector binary_address = address; for (char& bit : binary_address) { @@ -293,14 +318,14 @@ size_t FabricBitstream::encode_address_xbits(const std::vector& address) c } } /* Convert the binary address to a number */ - return bintoi_charvec(binary_address); + return (uint64_t)bintoi_charvec(binary_address); } -std::vector FabricBitstream::decode_address_bits(const size_t& bit1, const size_t& bitx) const { +std::vector FabricBitstream::decode_address_bits(const size_t& bit1, const size_t& bitx, const size_t& addr_len) const { /* Decode the bit1 number to a binary vector */ - std::vector ret_vec = itobin_charvec(bit1, address_length_); + std::vector ret_vec = itobin_charvec(bit1, addr_len); /* Decode the bitx number to a binary vector */ - std::vector bitx_vec = itobin_charvec(bitx, address_length_); + std::vector bitx_vec = itobin_charvec(bitx, addr_len); /* Combine the two vectors: 'x' overwrite any bit '0' and '1' */ for (size_t ibit = 0; ibit < ret_vec.size(); ++ibit) { if (bitx_vec[ibit] == '1') { @@ -310,19 +335,4 @@ std::vector FabricBitstream::decode_address_bits(const size_t& bit1, const return ret_vec; } -std::vector FabricBitstream::decode_wl_address_bits(const size_t& bit1, const size_t& bitx) const { - /* Decode the bit1 number to a binary vector */ - std::vector ret_vec = itobin_charvec(bit1, wl_address_length_); - /* Decode the bitx number to a binary vector */ - std::vector bitx_vec = itobin_charvec(bitx, wl_address_length_); - /* Combine the two vectors: 'x' overwrite any bit '0' and '1' */ - for (size_t ibit = 0; ibit < ret_vec.size(); ++ibit) { - if (bitx_vec[ibit] == '1') { - ret_vec[ibit] = 'x'; - } - } - return ret_vec; -} - - } /* end namespace openfpga */ diff --git a/openfpga/src/fpga_bitstream/fabric_bitstream.h b/openfpga/src/fpga_bitstream/fabric_bitstream.h index bc0c8c6df..12f2f9e03 100644 --- a/openfpga/src/fpga_bitstream/fabric_bitstream.h +++ b/openfpga/src/fpga_bitstream/fabric_bitstream.h @@ -188,10 +188,9 @@ class FabricBitstream { bool valid_region_id(const FabricBitRegionId& bit_id) const; private: /* Private APIs */ - size_t encode_address_1bits(const std::vector& address) const; - size_t encode_address_xbits(const std::vector& address) const; - std::vector decode_address_bits(const size_t& bit1, const size_t& bitx) const; - std::vector decode_wl_address_bits(const size_t& bit1, const size_t& bitx) const; + uint64_t encode_address_1bits(const std::vector& address) const; + uint64_t encode_address_xbits(const std::vector& address) const; + std::vector decode_address_bits(const size_t& bit1, const size_t& bitx, const size_t& addr_len) const; private: /* Internal data */ /* Unique id of a region in the Bitstream */ @@ -224,15 +223,12 @@ class FabricBitstream { * - bit-x number: which encodes the 'x' bits into a number. For example, * 101x1 -> 00010 -> 2 * - * TODO: There is a limitation here, when the length of address vector is more than 64, - * A size_t number overflows (cannot represent any binary number > 64 bit). - * Such thing can entirely happen even in a medium sized FPGA. - * A solution can be use multiple size_t to fit. But clearly, we should not use vector in vector, which causes large memory overhead! + * Note that when the length of address vector is more than 64, we use multiple 64-bit data to store the encoded values */ - vtr::vector bit_address_1bits_; - vtr::vector bit_address_xbits_; - vtr::vector bit_wl_address_1bits_; - vtr::vector bit_wl_address_xbits_; + vtr::vector> bit_address_1bits_; + vtr::vector> bit_address_xbits_; + vtr::vector> bit_wl_address_1bits_; + vtr::vector> bit_wl_address_xbits_; /* Data input (Din) bits: this is designed for memory decoders */ vtr::vector bit_dins_; diff --git a/openfpga_flow/regression_test_scripts/fpga_bitstream_reg_test.sh b/openfpga_flow/regression_test_scripts/fpga_bitstream_reg_test.sh index 3f77b067b..6ddee3f9f 100755 --- a/openfpga_flow/regression_test_scripts/fpga_bitstream_reg_test.sh +++ b/openfpga_flow/regression_test_scripts/fpga_bitstream_reg_test.sh @@ -18,7 +18,7 @@ run-task fpga_bitstream/generate_bitstream/ql_memory_bank_shift_register/device_ echo -e "Testing bitstream generation for an 96x96 FPGA device"; run-task fpga_bitstream/generate_bitstream/configuration_chain/device_96x96 $@ -run-task fpga_bitstream/generate_bitstream/ql_memory_bank_shift_register/device_96x96 $@ +run-task fpga_bitstream/generate_bitstream/ql_memory_bank_shift_register/device_72x72 $@ echo -e "Testing loading architecture bitstream from an external file"; run-task fpga_bitstream/load_external_architecture_bitstream $@ diff --git a/openfpga_flow/tasks/fpga_bitstream/generate_bitstream/ql_memory_bank_shift_register/device_96x96/config/task.conf b/openfpga_flow/tasks/fpga_bitstream/generate_bitstream/ql_memory_bank_shift_register/device_72x72/config/task.conf similarity index 97% rename from openfpga_flow/tasks/fpga_bitstream/generate_bitstream/ql_memory_bank_shift_register/device_96x96/config/task.conf rename to openfpga_flow/tasks/fpga_bitstream/generate_bitstream/ql_memory_bank_shift_register/device_72x72/config/task.conf index 00c5de64d..7efa743ee 100644 --- a/openfpga_flow/tasks/fpga_bitstream/generate_bitstream/ql_memory_bank_shift_register/device_96x96/config/task.conf +++ b/openfpga_flow/tasks/fpga_bitstream/generate_bitstream/ql_memory_bank_shift_register/device_72x72/config/task.conf @@ -21,7 +21,7 @@ openfpga_shell_template=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_shell_scrip openfpga_arch_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_arch/k4_N4_40nm_qlbanksr_openfpga.xml openfpga_sim_setting_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_simulation_settings/fixed_sim_openfpga.xml openfpga_vpr_route_chan_width=100 -openfpga_vpr_device_layout=96x96 +openfpga_vpr_device_layout=72x72 [ARCHITECTURES] arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/vpr_arch/k4_N4_tileable_40nm.xml diff --git a/openfpga_flow/vpr_arch/k4_N4_tileable_40nm.xml b/openfpga_flow/vpr_arch/k4_N4_tileable_40nm.xml index 056dcb034..c29067b03 100644 --- a/openfpga_flow/vpr_arch/k4_N4_tileable_40nm.xml +++ b/openfpga_flow/vpr_arch/k4_N4_tileable_40nm.xml @@ -91,6 +91,13 @@ + + + + + + +