diff --git a/docs/source/manual/openfpga_shell/openfpga_commands/fpga_bitstream_commands.rst b/docs/source/manual/openfpga_shell/openfpga_commands/fpga_bitstream_commands.rst index 12c4d8ff5..bf66e4b09 100644 --- a/docs/source/manual/openfpga_shell/openfpga_commands/fpga_bitstream_commands.rst +++ b/docs/source/manual/openfpga_shell/openfpga_commands/fpga_bitstream_commands.rst @@ -77,6 +77,9 @@ write_fabric_bitstream .. note:: If both reset and set ports are defined in the circuit modeling for programming, OpenFPGA will pick the one that will bring largest benefit in speeding up configuration. + .. option:: --keep_dont_care_bits + + Keep don't care bits (``x``) in the outputted bitstream file. This is only applicable to plain text file format. If not enabled, the don't care bits are converted to either logic ``0`` or ``1``. .. option:: --verbose diff --git a/openfpga/src/base/openfpga_bitstream.cpp b/openfpga/src/base/openfpga_bitstream.cpp index 315f647bc..ea390ae08 100644 --- a/openfpga/src/base/openfpga_bitstream.cpp +++ b/openfpga/src/base/openfpga_bitstream.cpp @@ -94,6 +94,7 @@ int write_fabric_bitstream(const OpenfpgaContext& openfpga_ctx, CommandOptionId opt_file = cmd.option("file"); CommandOptionId opt_file_format = cmd.option("format"); CommandOptionId opt_fast_config = cmd.option("fast_configuration"); + CommandOptionId opt_keep_dont_care_bits = cmd.option("keep_dont_care_bits"); /* Write fabric bitstream if required */ int status = CMD_EXEC_SUCCESS; @@ -125,6 +126,7 @@ int write_fabric_bitstream(const OpenfpgaContext& openfpga_ctx, openfpga_ctx.fabric_global_port_info(), cmd_context.option_value(cmd, opt_file), cmd_context.option_enable(cmd, opt_fast_config), + cmd_context.option_enable(cmd, opt_keep_dont_care_bits), cmd_context.option_enable(cmd, opt_verbose)); } diff --git a/openfpga/src/base/openfpga_bitstream_command.cpp b/openfpga/src/base/openfpga_bitstream_command.cpp index a59d19adf..fcf431890 100644 --- a/openfpga/src/base/openfpga_bitstream_command.cpp +++ b/openfpga/src/base/openfpga_bitstream_command.cpp @@ -154,6 +154,9 @@ ShellCommandId add_openfpga_write_fabric_bitstream_command(openfpga::Shell> fabric_bits_per_region; @@ -324,14 +325,14 @@ MemoryBankFlattenFabricBitstream build_memory_bank_flatten_fabric_bitstream(cons std::vector cur_wl_vectors; for (const FabricBitRegionId& region : fabric_bitstream.regions()) { /* If the key id is in bound for the key list in this region, find the BL and WL and add to the final bitstream database - * If the key id is out of bound for the key list in this region, we append an all-zero string for both BL and WLs + * If the key id is out of bound for the key list in this region, we append an all-'x' string for both BL and WLs */ if (ikey < fabric_bits_per_region_keys[region].size()) { cur_wl_vectors.push_back(fabric_bits_per_region_keys[region][ikey]); cur_bl_vectors.push_back(fabric_bits_per_region[region].at(fabric_bits_per_region_keys[region][ikey])); } else { - cur_wl_vectors.push_back(std::string(max_blwl_sizes_per_region[region].second, '0')); - cur_bl_vectors.push_back(std::string(max_blwl_sizes_per_region[region].first, '0')); + cur_wl_vectors.push_back(std::string(max_blwl_sizes_per_region[region].second, dont_care_bit)); + cur_bl_vectors.push_back(std::string(max_blwl_sizes_per_region[region].first, dont_care_bit)); } } /* Add the pair to std map */ @@ -398,8 +399,9 @@ std::vector reshape_bitstream_vectors_to_first_element(const std::v MemoryBankShiftRegisterFabricBitstream build_memory_bank_shift_register_fabric_bitstream(const FabricBitstream& fabric_bitstream, const bool& fast_configuration, //const std::array& blwl_sr_banks, - const bool& bit_value_to_skip) { - MemoryBankFlattenFabricBitstream raw_fabric_bits = build_memory_bank_flatten_fabric_bitstream(fabric_bitstream, fast_configuration, bit_value_to_skip); + const bool& bit_value_to_skip, + const char& dont_care_bit) { + MemoryBankFlattenFabricBitstream raw_fabric_bits = build_memory_bank_flatten_fabric_bitstream(fabric_bitstream, fast_configuration, bit_value_to_skip, dont_care_bit); MemoryBankShiftRegisterFabricBitstream fabric_bits; /* Iterate over each word */ @@ -408,7 +410,7 @@ MemoryBankShiftRegisterFabricBitstream build_memory_bank_shift_register_fabric_b MemoryBankShiftRegisterFabricBitstreamWordId word_id = fabric_bits.create_word(); - std::vector reshaped_bl_vectors = reshape_bitstream_vectors_to_first_element(bl_vec, '0'); + std::vector reshaped_bl_vectors = reshape_bitstream_vectors_to_first_element(bl_vec, dont_care_bit); /* 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 */ @@ -416,7 +418,7 @@ MemoryBankShiftRegisterFabricBitstream build_memory_bank_shift_register_fabric_b fabric_bits.add_bl_vectors(word_id, reshaped_bl_vec); } - std::vector reshaped_wl_vectors = reshape_bitstream_vectors_to_first_element(wl_vec, '0'); + std::vector reshaped_wl_vectors = reshape_bitstream_vectors_to_first_element(wl_vec, dont_care_bit); /* 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 */ diff --git a/openfpga/src/utils/fabric_bitstream_utils.h b/openfpga/src/utils/fabric_bitstream_utils.h index b45db0c0d..ff822802e 100644 --- a/openfpga/src/utils/fabric_bitstream_utils.h +++ b/openfpga/src/utils/fabric_bitstream_utils.h @@ -63,7 +63,8 @@ size_t find_frame_based_fast_configuration_fabric_bitstream_size(const FabricBit *******************************************************************/ MemoryBankFlattenFabricBitstream build_memory_bank_flatten_fabric_bitstream(const FabricBitstream& fabric_bitstream, const bool& fast_configuration, - const bool& bit_value_to_skip); + const bool& bit_value_to_skip, + const char& dont_care_bit = 'x'); /******************************************************************** * @ brief Reorganize the fabric bitstream for memory banks which use shift register to manipulate BL and WLs @@ -96,7 +97,8 @@ MemoryBankFlattenFabricBitstream build_memory_bank_flatten_fabric_bitstream(cons MemoryBankShiftRegisterFabricBitstream build_memory_bank_shift_register_fabric_bitstream(const FabricBitstream& fabric_bitstream, const bool& fast_configuration, //const std::array& blwl_sr_banks, - const bool& bit_value_to_skip); + const bool& bit_value_to_skip, + const char& dont_care_bit = 'x'); /* Alias to a specific organization of bitstreams for memory bank configuration protocol */ typedef std::map, std::vector> MemoryBankFabricBitstream; diff --git a/openfpga_flow/openfpga_shell_scripts/write_full_testbench_dont_care_bits_example_script.openfpga b/openfpga_flow/openfpga_shell_scripts/write_full_testbench_dont_care_bits_example_script.openfpga new file mode 100644 index 000000000..88e97bcbc --- /dev/null +++ b/openfpga_flow/openfpga_shell_scripts/write_full_testbench_dont_care_bits_example_script.openfpga @@ -0,0 +1,74 @@ +# Run VPR for the 'and' design +#--write_rr_graph example_rr_graph.xml +vpr ${VPR_ARCH_FILE} ${VPR_TESTBENCH_BLIF} --clock_modeling route ${OPENFPGA_VPR_DEVICE_LAYOUT} + +# Read OpenFPGA architecture definition +read_openfpga_arch -f ${OPENFPGA_ARCH_FILE} + +# Read OpenFPGA simulation settings +read_openfpga_simulation_setting -f ${OPENFPGA_SIM_SETTING_FILE} + +# Annotate the OpenFPGA architecture to VPR data base +# to debug use --verbose options +link_openfpga_arch --activity_file ${ACTIVITY_FILE} --sort_gsb_chan_node_in_edges + +# Check and correct any naming conflicts in the BLIF netlist +check_netlist_naming_conflict --fix --report ./netlist_renaming.xml + +# Apply fix-up to clustering nets based on routing results +pb_pin_fixup --verbose + +# Apply fix-up to Look-Up Table truth tables based on packing results +lut_truth_table_fixup + +# Build the module graph +# - Enabled compression on routing architecture modules +# - Enable pin duplication on grid modules +build_fabric --compress_routing #--verbose + +# Write the fabric hierarchy of module graph to a file +# This is used by hierarchical PnR flows +write_fabric_hierarchy --file ./fabric_hierarchy.txt + +# Repack the netlist to physical pbs +# This must be done before bitstream generator and testbench generation +# Strongly recommend it is done after all the fix-up have been applied +repack #--verbose + +# Build the bitstream +# - Output the fabric-independent bitstream to a file +build_architecture_bitstream --verbose --write_file fabric_independent_bitstream.xml + +# Build fabric-dependent bitstream +build_fabric_bitstream --verbose + +# Write fabric-dependent bitstream +write_fabric_bitstream --file fabric_bitstream.bit --format plain_text ${OPENFPGA_FAST_CONFIGURATION} --keep_dont_care_bits + +# Write the Verilog netlist for FPGA fabric +# - Enable the use of explicit port mapping in Verilog netlist +write_fabric_verilog --file ./SRC --explicit_port_mapping --include_timing --print_user_defined_template --verbose + +# Write the Verilog testbench for FPGA fabric +# - We suggest the use of same output directory as fabric Verilog netlists +# - Must specify the reference benchmark file if you want to output any testbenches +# - Enable top-level testbench which is a full verification including programming circuit and core logic of FPGA +# - Enable pre-configured top-level testbench which is a fast verification skipping programming phase +# - Simulation ini file is optional and is needed only when you need to interface different HDL simulators using openfpga flow-run scripts +write_full_testbench --file ./SRC --reference_benchmark_file_path ${REFERENCE_VERILOG_TESTBENCH} --include_signal_init --explicit_port_mapping --bitstream fabric_bitstream.bit ${OPENFPGA_FAST_CONFIGURATION} + +# Write the SDC files for PnR backend +# - Turn on every options here +write_pnr_sdc --file ./SDC + +# Write SDC to disable timing for configure ports +write_sdc_disable_timing_configure_ports --file ./SDC/disable_configure_ports.sdc + +# Write the SDC to run timing analysis for a mapped FPGA fabric +write_analysis_sdc --file ./SDC_analysis + +# Finish and exit OpenFPGA +exit + +# Note : +# To run verification at the end of the flow maintain source in ./SRC directory 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 58858e0b9..9fa5001b2 100755 --- a/openfpga_flow/regression_test_scripts/fpga_bitstream_reg_test.sh +++ b/openfpga_flow/regression_test_scripts/fpga_bitstream_reg_test.sh @@ -32,3 +32,7 @@ run-task fpga_bitstream/write_io_mapping --debug --show_thread_logs echo -e "Testing report bitstream distribution to file"; run-task fpga_bitstream/report_bitstream_distribution/default_depth --debug --show_thread_logs run-task fpga_bitstream/report_bitstream_distribution/custom_depth --debug --show_thread_logs + +echo -e "Testing bitstream file with don't care bits"; +run-task fpga_bitstream/dont_care_bits/ql_memory_bank_flatten --debug --show_thread_logs +run-task fpga_bitstream/dont_care_bits/ql_memory_bank_shift_register --debug --show_thread_logs diff --git a/openfpga_flow/tasks/fpga_bitstream/dont_care_bits/ql_memory_bank_flatten/config/task.conf b/openfpga_flow/tasks/fpga_bitstream/dont_care_bits/ql_memory_bank_flatten/config/task.conf new file mode 100644 index 000000000..791a8150e --- /dev/null +++ b/openfpga_flow/tasks/fpga_bitstream/dont_care_bits/ql_memory_bank_flatten/config/task.conf @@ -0,0 +1,44 @@ +# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +# Configuration file for running experiments +# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +# timeout_each_job : FPGA Task script splits fpga flow into multiple jobs +# Each job execute fpga_flow script on combination of architecture & benchmark +# timeout_each_job is timeout for each job +# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + +[GENERAL] +run_engine=openfpga_shell +power_tech_file = ${PATH:OPENFPGA_PATH}/openfpga_flow/tech/PTM_45nm/45nm.xml +power_analysis = true +spice_output=false +verilog_output=true +timeout_each_job = 20*60 +fpga_flow=yosys_vpr + +[OpenFPGA_SHELL] +openfpga_shell_template=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_shell_scripts/write_full_testbench_dont_care_bits_example_script.openfpga +openfpga_arch_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_arch/k4_N4_40nm_qlbankflatten_openfpga.xml +openfpga_sim_setting_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_simulation_settings/auto_sim_openfpga.xml +openfpga_vpr_device_layout= +openfpga_fast_configuration= + +[ARCHITECTURES] +arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/vpr_arch/k4_N4_tileable_40nm.xml + +[BENCHMARKS] +bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2/and2.v +bench1=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/or2/or2.v +bench2=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2_latch/and2_latch.v + +[SYNTHESIS_PARAM] +bench0_top = and2 +bench0_chan_width = 300 + +bench1_top = or2 +bench1_chan_width = 300 + +bench2_top = and2_latch +bench2_chan_width = 300 + +[SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH] +end_flow_with_test= diff --git a/openfpga_flow/tasks/fpga_bitstream/dont_care_bits/ql_memory_bank_shift_register/config/task.conf b/openfpga_flow/tasks/fpga_bitstream/dont_care_bits/ql_memory_bank_shift_register/config/task.conf new file mode 100644 index 000000000..30f89b9b9 --- /dev/null +++ b/openfpga_flow/tasks/fpga_bitstream/dont_care_bits/ql_memory_bank_shift_register/config/task.conf @@ -0,0 +1,45 @@ +# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +# Configuration file for running experiments +# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +# timeout_each_job : FPGA Task script splits fpga flow into multiple jobs +# Each job execute fpga_flow script on combination of architecture & benchmark +# timeout_each_job is timeout for each job +# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + +[GENERAL] +run_engine=openfpga_shell +power_tech_file = ${PATH:OPENFPGA_PATH}/openfpga_flow/tech/PTM_45nm/45nm.xml +power_analysis = true +spice_output=false +verilog_output=true +timeout_each_job = 20*60 +fpga_flow=yosys_vpr + +[OpenFPGA_SHELL] +openfpga_shell_template=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_shell_scripts/write_full_testbench_dont_care_bits_example_script.openfpga +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/auto_shift_register_sim_openfpga.xml + +openfpga_vpr_device_layout= +openfpga_fast_configuration= + +[ARCHITECTURES] +arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/vpr_arch/k4_N4_tileable_40nm.xml + +[BENCHMARKS] +bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2/and2.v +bench1=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/or2/or2.v +bench2=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2_latch/and2_latch.v + +[SYNTHESIS_PARAM] +bench0_top = and2 +bench0_chan_width = 300 + +bench1_top = or2 +bench1_chan_width = 300 + +bench2_top = and2_latch +bench2_chan_width = 300 + +[SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH] +end_flow_with_test=