From 3eb601531a4f4712f9a7ce2955600b58e9ca9cca Mon Sep 17 00:00:00 2001 From: tangxifan Date: Sat, 2 Oct 2021 23:39:53 -0700 Subject: [PATCH] [FPGA-Verilog] Many bug fixes --- .../verilog_top_testbench_memory_bank.cpp | 26 ++++++++++--------- openfpga/src/utils/fabric_bitstream_utils.cpp | 14 ++++++---- 2 files changed, 23 insertions(+), 17 deletions(-) diff --git a/openfpga/src/fpga_verilog/verilog_top_testbench_memory_bank.cpp b/openfpga/src/fpga_verilog/verilog_top_testbench_memory_bank.cpp index 76151a8b2..a750ff68b 100644 --- a/openfpga/src/fpga_verilog/verilog_top_testbench_memory_bank.cpp +++ b/openfpga/src/fpga_verilog/verilog_top_testbench_memory_bank.cpp @@ -226,7 +226,7 @@ void print_verilog_top_testbench_global_shift_register_clock_ports_stimuli(std:: stimuli_clock_port.set_width(1); } else { VTR_ASSERT(true == fabric_global_port_info.global_port_is_wl(fabric_global_port)); - stimuli_clock_port.set_name(std::string(TOP_TB_BL_SHIFT_REGISTER_CLOCK_PORT_NAME)); + stimuli_clock_port.set_name(std::string(TOP_TB_WL_SHIFT_REGISTER_CLOCK_PORT_NAME)); stimuli_clock_port.set_width(1); } @@ -244,7 +244,6 @@ void print_verilog_top_testbench_global_shift_register_clock_ports_stimuli(std:: */ static void print_verilog_full_testbench_ql_memory_bank_shift_register_clock_generator(std::fstream& fp, - const BasicPort& prog_clock_port, const BasicPort& start_sr_port, const BasicPort& sr_clock_port, const float& sr_clock_period) { @@ -252,7 +251,7 @@ void print_verilog_full_testbench_ql_memory_bank_shift_register_clock_generator( valid_file_stream(fp); fp << "always"; - fp << " @(negedge " << generate_verilog_port(VERILOG_PORT_CONKT, prog_clock_port) << ")"; + fp << " @(posedge " << generate_verilog_port(VERILOG_PORT_CONKT, start_sr_port) << ")"; fp << " begin"; fp << std::endl; @@ -314,18 +313,21 @@ void print_verilog_top_testbench_configuration_protocol_ql_memory_bank_stimulus( fast_configuration, bit_value_to_skip); - /* TODO: Consider auto-tuned clock period for now */ - float bl_sr_clock_period = prog_clock_period / fabric_bits_by_addr.bl_word_size() / timescale; - float wl_sr_clock_period = prog_clock_period / fabric_bits_by_addr.wl_word_size() / timescale; + /* TODO: Consider auto-tuned clock period for now: + * - the BL/WL shift register clock only works in the second half of the programming clock period + * - add 2 idle clocks to avoid racing between programming clock and shift register clocks at edge + */ + float bl_sr_clock_period = 0.25 * prog_clock_period / (fabric_bits_by_addr.bl_word_size() + 2) / timescale; + float wl_sr_clock_period = 0.25 * prog_clock_period / (fabric_bits_by_addr.wl_word_size() + 2) / timescale; if (BLWL_PROTOCOL_SHIFT_REGISTER == config_protocol.bl_protocol_type()) { print_verilog_comment(fp, "----- BL Shift register clock generator -----"); - print_verilog_full_testbench_ql_memory_bank_shift_register_clock_generator(fp, prog_clock_port, start_bl_sr_port, bl_sr_clock_port, 0.5 * bl_sr_clock_period); + print_verilog_full_testbench_ql_memory_bank_shift_register_clock_generator(fp, start_bl_sr_port, bl_sr_clock_port, bl_sr_clock_period); } if (BLWL_PROTOCOL_SHIFT_REGISTER == config_protocol.wl_protocol_type()) { print_verilog_comment(fp, "----- WL Shift register clock generator -----"); - print_verilog_full_testbench_ql_memory_bank_shift_register_clock_generator(fp, prog_clock_port, start_wl_sr_port, wl_sr_clock_port, 0.5 * wl_sr_clock_period); + print_verilog_full_testbench_ql_memory_bank_shift_register_clock_generator(fp, start_wl_sr_port, wl_sr_clock_port, wl_sr_clock_period); } } } @@ -663,8 +665,8 @@ void print_verilog_full_testbench_ql_memory_bank_shift_register_bitstream(std::f fp << "\t\t"; fp << generate_verilog_ports(bl_head_ports); fp << " <= "; - fp << TOP_TB_BITSTREAM_MEM_REG_NAME << "["; - fp << TOP_TB_BITSTREAM_INDEX_REG_NAME << "*(`" << TOP_TB_BITSTREAM_BL_WORD_SIZE_VARIABLE << " + `" << TOP_TB_BITSTREAM_WL_WORD_SIZE_VARIABLE << ") + " << TOP_TB_BL_SHIFT_REGISTER_COUNT_PORT_NAME; + fp << TOP_TB_BITSTREAM_MEM_REG_NAME << "[("; + fp << TOP_TB_BITSTREAM_INDEX_REG_NAME << "-1)*(`" << TOP_TB_BITSTREAM_BL_WORD_SIZE_VARIABLE << " + `" << TOP_TB_BITSTREAM_WL_WORD_SIZE_VARIABLE << ") + " << TOP_TB_BL_SHIFT_REGISTER_COUNT_PORT_NAME; fp << "];" << std::endl; fp << "\t\t"; @@ -707,8 +709,8 @@ void print_verilog_full_testbench_ql_memory_bank_shift_register_bitstream(std::f fp << "\t\t"; fp << generate_verilog_ports(wl_head_ports); fp << " <= "; - fp << TOP_TB_BITSTREAM_MEM_REG_NAME << "["; - fp << TOP_TB_BITSTREAM_INDEX_REG_NAME << "*(`" << TOP_TB_BITSTREAM_BL_WORD_SIZE_VARIABLE << " + `" << TOP_TB_BITSTREAM_WL_WORD_SIZE_VARIABLE << ") + `" << TOP_TB_BITSTREAM_WL_WORD_SIZE_VARIABLE << " + " << TOP_TB_WL_SHIFT_REGISTER_COUNT_PORT_NAME; + fp << TOP_TB_BITSTREAM_MEM_REG_NAME << "[("; + fp << TOP_TB_BITSTREAM_INDEX_REG_NAME << "-1)*(`" << TOP_TB_BITSTREAM_BL_WORD_SIZE_VARIABLE << " + `" << TOP_TB_BITSTREAM_WL_WORD_SIZE_VARIABLE << ") + `" << TOP_TB_BITSTREAM_BL_WORD_SIZE_VARIABLE << " + " << TOP_TB_WL_SHIFT_REGISTER_COUNT_PORT_NAME; fp << "];" << std::endl; fp << "\t\t"; diff --git a/openfpga/src/utils/fabric_bitstream_utils.cpp b/openfpga/src/utils/fabric_bitstream_utils.cpp index 8d66f300f..31163efcc 100644 --- a/openfpga/src/utils/fabric_bitstream_utils.cpp +++ b/openfpga/src/utils/fabric_bitstream_utils.cpp @@ -366,8 +366,8 @@ MemoryBankFlattenFabricBitstream build_memory_bank_flatten_fabric_bitstream(cons * *******************************************************************/ static -std::vector reshape_bitstream_vectors_to_last_element(const std::vector& bitstream_vectors, - const char& default_bit_to_fill) { +std::vector reshape_bitstream_vectors_to_first_element(const std::vector& bitstream_vectors, + const char& default_bit_to_fill) { /* Find the max sizes of BL bits, this determines the size of shift register chain */ size_t max_vec_size = 0; for (const auto& vec : bitstream_vectors) { @@ -377,8 +377,8 @@ std::vector reshape_bitstream_vectors_to_last_element(const std::ve std::vector reshaped_vectors(bitstream_vectors.size(), std::string()); size_t col_cnt = 0; for (const auto& vec : bitstream_vectors) { - reshaped_vectors[col_cnt].resize(max_vec_size - vec.size(), default_bit_to_fill); reshaped_vectors[col_cnt] += vec; + reshaped_vectors[col_cnt] += std::string(max_vec_size - vec.size(), default_bit_to_fill); col_cnt++; } @@ -408,13 +408,17 @@ MemoryBankShiftRegisterFabricBitstream build_memory_bank_shift_register_fabric_b MemoryBankShiftRegisterFabricBitstreamWordId word_id = fabric_bits.create_word(); - std::vector reshaped_bl_vectors = reshape_bitstream_vectors_to_last_element(bl_vec, '0'); + std::vector reshaped_bl_vectors = reshape_bitstream_vectors_to_first_element(bl_vec, '0'); + /* Reverse the vectors due to the shift register chain nature: first-in first-out */ + //std::reverse(reshaped_bl_vectors.begin(), reshaped_bl_vectors.end()); /* Add the BL word to final bitstream */ for (const auto& reshaped_bl_vec : reshaped_bl_vectors) { fabric_bits.add_bl_vectors(word_id, reshaped_bl_vec); } - std::vector reshaped_wl_vectors = reshape_bitstream_vectors_to_last_element(wl_vec, '0'); + std::vector reshaped_wl_vectors = reshape_bitstream_vectors_to_first_element(wl_vec, '0'); + /* Reverse the vectors due to the shift register chain nature: first-in first-out */ + //std::reverse(reshaped_wl_vectors.begin(), reshaped_wl_vectors.end()); /* Add the BL word to final bitstream */ for (const auto& reshaped_wl_vec : reshaped_wl_vectors) { fabric_bits.add_wl_vectors(word_id, reshaped_wl_vec);