From 3f14fe62c7457debcb0f8f1135aded2fae82757a Mon Sep 17 00:00:00 2001 From: tangxifan Date: Wed, 15 Jul 2020 11:44:23 -0600 Subject: [PATCH] add fast configuration support for configuration chain protocol --- .../fpga_verilog/verilog_top_testbench.cpp | 35 ++++++++++++++++--- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/openfpga/src/fpga_verilog/verilog_top_testbench.cpp b/openfpga/src/fpga_verilog/verilog_top_testbench.cpp index 9e7bde572..00e6a80f5 100644 --- a/openfpga/src/fpga_verilog/verilog_top_testbench.cpp +++ b/openfpga/src/fpga_verilog/verilog_top_testbench.cpp @@ -561,6 +561,7 @@ void print_verilog_top_testbench_ports(std::fstream& fp, static size_t calculate_num_config_clock_cycles(const e_config_protocol_type& sram_orgz_type, const bool& fast_configuration, + const BitstreamManager& bitstream_manager, const FabricBitstream& fabric_bitstream) { size_t num_config_clock_cycles = 1 + fabric_bitstream.num_bits(); @@ -573,7 +574,17 @@ size_t calculate_num_config_clock_cycles(const e_config_protocol_type& sram_orgz num_config_clock_cycles = 2; break; case CONFIG_MEM_SCAN_CHAIN: - /* Fast configuraiton is not applicable to configuration chain protocol*/ + /* For fast configuraiton, the bitstream size counts from the first bit '1' */ + if (true == fast_configuration) { + size_t num_bits_to_skip = 0; + for (const FabricBitId& bit_id : fabric_bitstream.bits()) { + if (true == bitstream_manager.bit_value(fabric_bitstream.config_bit(bit_id))) { + break; + } + num_bits_to_skip++; + } + num_config_clock_cycles -= num_bits_to_skip; + } break; case CONFIG_MEM_MEMORY_BANK: case CONFIG_MEM_FRAME_BASED: { @@ -1108,6 +1119,7 @@ void print_verilog_top_testbench_vanilla_bitstream(std::fstream& fp, *******************************************************************/ static void print_verilog_top_testbench_configuration_chain_bitstream(std::fstream& fp, + const bool& fast_configuration, const BitstreamManager& bitstream_manager, const FabricBitstream& fabric_bitstream) { /* Validate the file stream */ @@ -1132,10 +1144,23 @@ void print_verilog_top_testbench_configuration_chain_bitstream(std::fstream& fp, fp << std::endl; - /* Attention: the configuration chain protcol requires the last configuration bit is fed first - * We will visit the fabric bitstream in a reverse way + /* Attention: when the fast configuration is enabled, we will start from the first bit '1' + * This requires a reset signal (as we forced in the first clock cycle) */ + bool first_bit_one = false; for (const FabricBitId& bit_id : fabric_bitstream.bits()) { + if (true == bitstream_manager.bit_value(fabric_bitstream.config_bit(bit_id))) { + first_bit_one = true; + } + + /* In fast configuration mode, we do not output anything + * until we have to (the first bit '1' detected) + */ + if ( (true == fast_configuration) + && (false == first_bit_one)) { + continue; + } + fp << "\t\t" << std::string(TOP_TESTBENCH_PROG_TASK_NAME); fp << "(1'b" << (size_t)bitstream_manager.bit_value(fabric_bitstream.config_bit(bit_id)) << ");" << std::endl; } @@ -1382,7 +1407,8 @@ void print_verilog_top_testbench_bitstream(std::fstream& fp, bitstream_manager, fabric_bitstream); break; case CONFIG_MEM_SCAN_CHAIN: - print_verilog_top_testbench_configuration_chain_bitstream(fp, bitstream_manager, fabric_bitstream); + print_verilog_top_testbench_configuration_chain_bitstream(fp, fast_configuration, + bitstream_manager, fabric_bitstream); break; case CONFIG_MEM_MEMORY_BANK: print_verilog_top_testbench_memory_bank_bitstream(fp, fast_configuration, @@ -1471,6 +1497,7 @@ void print_verilog_top_testbench(const ModuleManager& module_manager, /* Estimate the number of configuration clock cycles */ size_t num_config_clock_cycles = calculate_num_config_clock_cycles(sram_orgz_type, fast_configuration, + bitstream_manager, fabric_bitstream); /* Generate stimuli for general control signals */