From 67cd9a69b71e6d520e1fea533902d8d8ed046d24 Mon Sep 17 00:00:00 2001 From: Ganesh Gore Date: Mon, 8 Mar 2021 00:21:07 -0700 Subject: [PATCH 01/24] [Flow] Extended yosys variable subtitution --- openfpga_flow/scripts/run_fpga_flow.py | 26 ++++++++++++++++++++------ openfpga_flow/scripts/run_fpga_task.py | 7 ++++++- 2 files changed, 26 insertions(+), 7 deletions(-) diff --git a/openfpga_flow/scripts/run_fpga_flow.py b/openfpga_flow/scripts/run_fpga_flow.py index 66472e3c8..75fef5685 100644 --- a/openfpga_flow/scripts/run_fpga_flow.py +++ b/openfpga_flow/scripts/run_fpga_flow.py @@ -99,6 +99,8 @@ parser.add_argument('--arch_variable_file', type=str, default=None, # help="Key file for shell") parser.add_argument('--yosys_tmpl', type=str, default=None, help="Alternate yosys template, generates top_module.blif") +parser.add_argument('--ys_rewrite_tmpl', type=str, default=None, + help="Alternate yosys template, to rewrite verilog netlist") parser.add_argument('--disp', action="store_true", help="Open display while running VPR") parser.add_argument('--debug', action="store_true", @@ -260,7 +262,7 @@ def main(): if args.power: run_ace2() run_pro_blif_3arg() - else: + else: # Make a copy of the blif file to be compatible with vpr flow shutil.copy(args.top_module+'_yosys_out.blif', args.top_module+".blif") @@ -489,6 +491,9 @@ def run_yosys_with_abc(): "LUT_SIZE": lut_size, "OUTPUT_BLIF": args.top_module+"_yosys_out.blif", } + for indx in range(0, len(OpenFPGAArgs), 2): + tmpVar = OpenFPGAArgs[indx][2:].upper() + ys_params[tmpVar] = OpenFPGAArgs[indx+1] yosys_template = args.yosys_tmpl if args.yosys_tmpl else os.path.join( cad_tools["misc_dir"], "ys_tmpl_yosys_vpr_flow.ys") tmpl = Template(open(yosys_template, encoding='utf-8').read()) @@ -687,11 +692,20 @@ def extract_vpr_stats(logfile, r_filename="vpr_stat", parse_section="vpr"): def run_rewrite_verilog(): # Rewrite the verilog after optimization - script_cmd = [ - "read_blif %s" % args.top_module+".blif", - "write_verilog %s" % args.top_module+"_output_verilog.v" - ] - command = [cad_tools["yosys_path"], "-p", "; ".join(script_cmd)] + if not args.ys_rewrite_tmpl: + script_cmd = [ + "read_blif %s" % args.top_module+".blif", + "write_verilog %s" % args.top_module+"_output_verilog.v" + ] + command = [cad_tools["yosys_path"], "-p", "; ".join(script_cmd)] + else: + ys_rewrite_params = { + "INPUT_BLIF": args.top_module+".blif", + "OUTPUT_VERILOG": args.top_module+"_output_verilog.v" + } + for indx in range(0, len(OpenFPGAArgs), 2): + tmpVar = OpenFPGAArgs[indx][2:].upper() + ys_rewrite_params[tmpVar] = OpenFPGAArgs[indx+1] run_command("Yosys", "yosys_rewrite.log", command) diff --git a/openfpga_flow/scripts/run_fpga_task.py b/openfpga_flow/scripts/run_fpga_task.py index fa297932e..f7c658b2f 100644 --- a/openfpga_flow/scripts/run_fpga_task.py +++ b/openfpga_flow/scripts/run_fpga_task.py @@ -175,7 +175,7 @@ def generate_each_task_actions(taskname): curr_task_dir = repo_tasks else: clean_up_and_exit("Task directory [%s] not found" % curr_task_dir) - + os.chdir(curr_task_dir) curr_task_conf_file = os.path.join(curr_task_dir, "config", "task.conf") @@ -263,6 +263,8 @@ def generate_each_task_actions(taskname): fallback="top") CurrBenchPara["ys_script"] = SynthSection.get(bech_name+"_yosys", fallback=ys_for_task_common) + CurrBenchPara["ys_rewrite_script"] = SynthSection.get(bech_name+"_yosys_rewrite", + fallback=ys_for_task_common) CurrBenchPara["chan_width"] = SynthSection.get(bech_name+"_chan_width", fallback=chan_width_common) @@ -381,6 +383,9 @@ def create_run_command(curr_job_dir, archfile, benchmark_obj, param, task_conf): if benchmark_obj.get("ys_script"): command += ["--yosys_tmpl", benchmark_obj["ys_script"]] + if benchmark_obj.get("ys_rewrite_script"): + command += ["--ys_rewrite_tmpl", benchmark_obj["ys_rewrite_script"]] + if task_gc.getboolean("power_analysis"): command += ["--power"] command += ["--power_tech", task_gc.get("power_tech_file")] From 7a35811430bc6ed3d9e67cebcf95675879fe8fe3 Mon Sep 17 00:00:00 2001 From: Ganesh Gore Date: Mon, 8 Mar 2021 00:35:47 -0700 Subject: [PATCH 02/24] [Flow] Yosys rewrite support --- openfpga_flow/scripts/run_fpga_flow.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/openfpga_flow/scripts/run_fpga_flow.py b/openfpga_flow/scripts/run_fpga_flow.py index 75fef5685..10721b14f 100644 --- a/openfpga_flow/scripts/run_fpga_flow.py +++ b/openfpga_flow/scripts/run_fpga_flow.py @@ -698,6 +698,7 @@ def run_rewrite_verilog(): "write_verilog %s" % args.top_module+"_output_verilog.v" ] command = [cad_tools["yosys_path"], "-p", "; ".join(script_cmd)] + run_command("Yosys", "yosys_rewrite.log", command) else: ys_rewrite_params = { "INPUT_BLIF": args.top_module+".blif", @@ -705,8 +706,13 @@ def run_rewrite_verilog(): } for indx in range(0, len(OpenFPGAArgs), 2): tmpVar = OpenFPGAArgs[indx][2:].upper() - ys_rewrite_params[tmpVar] = OpenFPGAArgs[indx+1] - run_command("Yosys", "yosys_rewrite.log", command) + ys_rewrite_params[tmpVar] = OpenFPGAArgs[indx + 1] + tmpl = Template(open(args.ys_rewrite_tmpl, encoding='utf-8').read()) + with open("yosys_rewrite.ys", 'w') as archfile: + archfile.write(tmpl.safe_substitute(ys_params)) + run_command("Run yosys", "yosys_rewrite_output.log", + [cad_tools["yosys_path"], 'yosys_rewrite.ys']) + def run_netlists_verification(exit_if_fail=True): From b860722893e80eb535a9d2e9af12b298185db85a Mon Sep 17 00:00:00 2001 From: ganeshgore Date: Mon, 8 Mar 2021 10:34:39 -0700 Subject: [PATCH 03/24] Fixed parameter ys_rewrite_params name bug --- openfpga_flow/scripts/run_fpga_flow.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openfpga_flow/scripts/run_fpga_flow.py b/openfpga_flow/scripts/run_fpga_flow.py index 678c91047..d4426a9fa 100644 --- a/openfpga_flow/scripts/run_fpga_flow.py +++ b/openfpga_flow/scripts/run_fpga_flow.py @@ -711,7 +711,7 @@ def run_rewrite_verilog(): ys_rewrite_params[tmpVar] = OpenFPGAArgs[indx + 1] tmpl = Template(open(args.ys_rewrite_tmpl, encoding='utf-8').read()) with open("yosys_rewrite.ys", 'w') as archfile: - archfile.write(tmpl.safe_substitute(ys_params)) + archfile.write(tmpl.safe_substitute(ys_rewrite_params)) run_command("Run yosys", "yosys_rewrite_output.log", [cad_tools["yosys_path"], 'yosys_rewrite.ys']) From 131643dcc04267f77620823f726839c0364b14dd Mon Sep 17 00:00:00 2001 From: tangxifan Date: Mon, 8 Mar 2021 21:08:55 -0700 Subject: [PATCH 04/24] [Flow] Bug fix for yosys rewrite function in openfpga flow-run script --- openfpga_flow/scripts/run_fpga_flow.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/openfpga_flow/scripts/run_fpga_flow.py b/openfpga_flow/scripts/run_fpga_flow.py index d4426a9fa..61a5835ba 100644 --- a/openfpga_flow/scripts/run_fpga_flow.py +++ b/openfpga_flow/scripts/run_fpga_flow.py @@ -694,6 +694,8 @@ def extract_vpr_stats(logfile, r_filename="vpr_stat", parse_section="vpr"): def run_rewrite_verilog(): # Rewrite the verilog after optimization + # If there is no template script provided, use a default template + # If there is a template script provided, replace parameters from configuration if not args.ys_rewrite_tmpl: script_cmd = [ "read_blif %s" % args.top_module+".blif", @@ -702,10 +704,17 @@ def run_rewrite_verilog(): command = [cad_tools["yosys_path"], "-p", "; ".join(script_cmd)] run_command("Yosys", "yosys_rewrite.log", command) else: + # Yosys script parameter mapping ys_rewrite_params = { + "READ_VERILOG_FILE": " \n".join([ + "read_verilog -nolatches " + shlex.quote(eachfile) + for eachfile in args.benchmark_files]), + "TOP_MODULE": args.top_module, + "OUTPUT_BLIF": args.top_module+"_yosys_out.blif", "INPUT_BLIF": args.top_module+".blif", "OUTPUT_VERILOG": args.top_module+"_output_verilog.v" } + for indx in range(0, len(OpenFPGAArgs), 2): tmpVar = OpenFPGAArgs[indx][2:].upper() ys_rewrite_params[tmpVar] = OpenFPGAArgs[indx + 1] From c53c41b7a5c48b54d028d3f859779208a7fd1ddc Mon Sep 17 00:00:00 2001 From: tangxifan Date: Mon, 8 Mar 2021 21:09:23 -0700 Subject: [PATCH 05/24] [Script] Fine-tune quicklogic yosys script to output correct post-synthesis verilog file --- openfpga_flow/misc/qlf_yosys.ys | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openfpga_flow/misc/qlf_yosys.ys b/openfpga_flow/misc/qlf_yosys.ys index c90b8c5ac..e0b530564 100644 --- a/openfpga_flow/misc/qlf_yosys.ys +++ b/openfpga_flow/misc/qlf_yosys.ys @@ -4,4 +4,4 @@ ${READ_VERILOG_FILE} synth_quicklogic -blif ${OUTPUT_BLIF} -top ${TOP_MODULE} ${YOSYS_ARGS} -write_verilog -noattr -nohex ${TOP_MODULE}.v \ No newline at end of file +write_verilog -noattr -nohex ${OUTPUT_VERILOG}.v From 37aa42d305e5dfe84e7b5db6748520520c5750d5 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Mon, 8 Mar 2021 21:38:51 -0700 Subject: [PATCH 06/24] [Test] Patch task configuration file for lut_adder_test to use correct rewrite script --- .../tasks/quicklogic_tests/lut_adder_test/config/task.conf | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/openfpga_flow/tasks/quicklogic_tests/lut_adder_test/config/task.conf b/openfpga_flow/tasks/quicklogic_tests/lut_adder_test/config/task.conf index 6f711649b..8f69e98b6 100644 --- a/openfpga_flow/tasks/quicklogic_tests/lut_adder_test/config/task.conf +++ b/openfpga_flow/tasks/quicklogic_tests/lut_adder_test/config/task.conf @@ -30,8 +30,9 @@ arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/vpr_arch/k4_frac_N8_tileable_reset_sof bench1=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/adder_8/adder_8.v [SYNTHESIS_PARAM] +bench_yosys_common=${PATH:OPENFPGA_PATH}/openfpga_flow/misc/qlf_yosys.ys + bench1_top = adder_8 -bench1_yosys=${PATH:OPENFPGA_PATH}/openfpga_flow/misc/qlf_yosys.ys [SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH] ########################## From 812d8c950eb3864a4de620c45c6e9e85bd76bfee Mon Sep 17 00:00:00 2001 From: tangxifan Date: Mon, 8 Mar 2021 21:39:44 -0700 Subject: [PATCH 07/24] [Script] Update quicklogic's script to output correct verilog file name --- openfpga_flow/misc/qlf_yosys.ys | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openfpga_flow/misc/qlf_yosys.ys b/openfpga_flow/misc/qlf_yosys.ys index e0b530564..587769941 100644 --- a/openfpga_flow/misc/qlf_yosys.ys +++ b/openfpga_flow/misc/qlf_yosys.ys @@ -4,4 +4,4 @@ ${READ_VERILOG_FILE} synth_quicklogic -blif ${OUTPUT_BLIF} -top ${TOP_MODULE} ${YOSYS_ARGS} -write_verilog -noattr -nohex ${OUTPUT_VERILOG}.v +write_verilog -noattr -nohex ${OUTPUT_VERILOG} From 2daa770319ba4ec87fe3653f28e757167bc1c439 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Mon, 8 Mar 2021 21:40:29 -0700 Subject: [PATCH 08/24] [Arch] Update openfpga architecture to include quicklogic cell sim --- ...r_scan_chain_caravel_io_skywater130nm_fdhd_cc_openfpga.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openfpga_flow/openfpga_arch/k4_frac_N8_reset_softadderSuperLUT_register_scan_chain_caravel_io_skywater130nm_fdhd_cc_openfpga.xml b/openfpga_flow/openfpga_arch/k4_frac_N8_reset_softadderSuperLUT_register_scan_chain_caravel_io_skywater130nm_fdhd_cc_openfpga.xml index d40e7bea2..fbf6a05f0 100644 --- a/openfpga_flow/openfpga_arch/k4_frac_N8_reset_softadderSuperLUT_register_scan_chain_caravel_io_skywater130nm_fdhd_cc_openfpga.xml +++ b/openfpga_flow/openfpga_arch/k4_frac_N8_reset_softadderSuperLUT_register_scan_chain_caravel_io_skywater130nm_fdhd_cc_openfpga.xml @@ -206,9 +206,9 @@ - + From aafd87c3f9d396c37f1e24fa855765a5d7817995 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Wed, 10 Mar 2021 11:36:29 -0700 Subject: [PATCH 09/24] [Flow] Update flow-run to support custom yosys rewrite scripts --- openfpga_flow/scripts/run_fpga_flow.py | 1 + openfpga_flow/scripts/run_fpga_task.py | 6 +++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/openfpga_flow/scripts/run_fpga_flow.py b/openfpga_flow/scripts/run_fpga_flow.py index 61a5835ba..499d1bc44 100644 --- a/openfpga_flow/scripts/run_fpga_flow.py +++ b/openfpga_flow/scripts/run_fpga_flow.py @@ -490,6 +490,7 @@ def run_yosys_with_abc(): "TOP_MODULE": args.top_module, "LUT_SIZE": lut_size, "OUTPUT_BLIF": args.top_module+"_yosys_out.blif", + "OUTPUT_VERILOG": args.top_module+"_output_verilog.v" } for indx in range(0, len(OpenFPGAArgs), 2): diff --git a/openfpga_flow/scripts/run_fpga_task.py b/openfpga_flow/scripts/run_fpga_task.py index f7c658b2f..e8543a402 100644 --- a/openfpga_flow/scripts/run_fpga_task.py +++ b/openfpga_flow/scripts/run_fpga_task.py @@ -254,7 +254,11 @@ def generate_each_task_actions(taskname): # Read provided benchmark configurations # Common configurations + # - All the benchmarks may share the same yosys synthesis template script + # - All the benchmarks may share the same rewrite yosys template script, which converts post-synthesis .v netlist to be compatible with .blif port definition. This is required for correct verification at the end of flows + # - All the benchmarks may share the same routing channel width in VPR runs. This is designed to enable architecture evaluations for a fixed device model ys_for_task_common = SynthSection.get("bench_yosys_common") + ys_rewrite_for_task_common = SynthSection.get("bench_yosys_rewrite_common") chan_width_common = SynthSection.get("bench_chan_width_common") # Individual benchmark configuration @@ -264,7 +268,7 @@ def generate_each_task_actions(taskname): CurrBenchPara["ys_script"] = SynthSection.get(bech_name+"_yosys", fallback=ys_for_task_common) CurrBenchPara["ys_rewrite_script"] = SynthSection.get(bech_name+"_yosys_rewrite", - fallback=ys_for_task_common) + fallback=ys_rewrite_for_task_common) CurrBenchPara["chan_width"] = SynthSection.get(bech_name+"_chan_width", fallback=chan_width_common) From 5d46537b5b3192ed05271265ddf196f61b1d0a10 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Wed, 10 Mar 2021 11:45:55 -0700 Subject: [PATCH 10/24] [Script] Allow users to specify custom post-synthesis verilog for simulation --- openfpga_flow/scripts/run_fpga_task.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/openfpga_flow/scripts/run_fpga_task.py b/openfpga_flow/scripts/run_fpga_task.py index e8543a402..9f93daa82 100644 --- a/openfpga_flow/scripts/run_fpga_task.py +++ b/openfpga_flow/scripts/run_fpga_task.py @@ -279,12 +279,13 @@ def generate_each_task_actions(taskname): "for vpr_blif flow") CurrBenchPara["activity_file"] = SynthSection.get(bech_name+"_act") - # Check if base verilog file exists - if not SynthSection.get(bech_name+"_verilog"): - clean_up_and_exit("Missing argument %s for vpr_blif flow" % - (bech_name+"_verilog")) - CurrBenchPara["verilog_file"] = SynthSection.get( - bech_name+"_verilog") + # Allow user to specify a post-synthesis verilog file for simulation usage + # Check if base verilog file exists + if not SynthSection.get(bech_name+"_verilog"): + clean_up_and_exit("Missing argument %s for vpr_blif flow" % + (bech_name+"_verilog")) + CurrBenchPara["verilog_file"] = SynthSection.get( + bech_name+"_verilog") # Add script parameter list in current benchmark ScriptSections = [x for x in TaskFileSections if "SCRIPT_PARAM" in x] From 035043d0d8fb2f1458b4d680af1ce2d3571d8e7f Mon Sep 17 00:00:00 2001 From: tangxifan Date: Wed, 10 Mar 2021 13:36:11 -0700 Subject: [PATCH 11/24] [Script] Revert to the state that post synthesis verilog is not required for yosys_vpr --- openfpga_flow/scripts/run_fpga_task.py | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/openfpga_flow/scripts/run_fpga_task.py b/openfpga_flow/scripts/run_fpga_task.py index 9f93daa82..e8543a402 100644 --- a/openfpga_flow/scripts/run_fpga_task.py +++ b/openfpga_flow/scripts/run_fpga_task.py @@ -279,13 +279,12 @@ def generate_each_task_actions(taskname): "for vpr_blif flow") CurrBenchPara["activity_file"] = SynthSection.get(bech_name+"_act") - # Allow user to specify a post-synthesis verilog file for simulation usage - # Check if base verilog file exists - if not SynthSection.get(bech_name+"_verilog"): - clean_up_and_exit("Missing argument %s for vpr_blif flow" % - (bech_name+"_verilog")) - CurrBenchPara["verilog_file"] = SynthSection.get( - bech_name+"_verilog") + # Check if base verilog file exists + if not SynthSection.get(bech_name+"_verilog"): + clean_up_and_exit("Missing argument %s for vpr_blif flow" % + (bech_name+"_verilog")) + CurrBenchPara["verilog_file"] = SynthSection.get( + bech_name+"_verilog") # Add script parameter list in current benchmark ScriptSections = [x for x in TaskFileSections if "SCRIPT_PARAM" in x] From 7adb78b1594fcaa8929ffd23a5398d0c28706acf Mon Sep 17 00:00:00 2001 From: tangxifan Date: Wed, 10 Mar 2021 13:40:31 -0700 Subject: [PATCH 12/24] [Script] Add a template yosys script with rewriting at the end --- .../ys_tmpl_yosys_vpr_flow_with_rewrite.ys | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 openfpga_flow/misc/ys_tmpl_yosys_vpr_flow_with_rewrite.ys diff --git a/openfpga_flow/misc/ys_tmpl_yosys_vpr_flow_with_rewrite.ys b/openfpga_flow/misc/ys_tmpl_yosys_vpr_flow_with_rewrite.ys new file mode 100644 index 000000000..6da1a7987 --- /dev/null +++ b/openfpga_flow/misc/ys_tmpl_yosys_vpr_flow_with_rewrite.ys @@ -0,0 +1,30 @@ +# Yosys synthesis script for ${TOP_MODULE} +# Read verilog files +${READ_VERILOG_FILE} + +# Technology mapping +hierarchy -top ${TOP_MODULE} +proc +techmap -D NO_LUT -map +/adff2dff.v + +# Synthesis +synth -top ${TOP_MODULE} -flatten +clean + +# LUT mapping +abc -lut ${LUT_SIZE} + +# Check +synth -run check + +# Clean and output blif +opt_clean -purge +write_blif ${OUTPUT_BLIF} + +# Clear all the designs +design -reset + +# Rewrite the .blif to Verilog +# so that the pin sequence matches +read_blif ${OUTPUT_BLIF} +write_verilog ${OUTPUT_VERILOG} From 0e772bc3b4810cecc3e6e87702010ae9b9844d50 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Wed, 10 Mar 2021 13:47:30 -0700 Subject: [PATCH 13/24] [Script] Patch the yosys rewrite script to avoid existing blif outputs --- openfpga_flow/misc/ys_tmpl_yosys_vpr_flow_with_rewrite.ys | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openfpga_flow/misc/ys_tmpl_yosys_vpr_flow_with_rewrite.ys b/openfpga_flow/misc/ys_tmpl_yosys_vpr_flow_with_rewrite.ys index 6da1a7987..b3faf9605 100644 --- a/openfpga_flow/misc/ys_tmpl_yosys_vpr_flow_with_rewrite.ys +++ b/openfpga_flow/misc/ys_tmpl_yosys_vpr_flow_with_rewrite.ys @@ -19,12 +19,12 @@ synth -run check # Clean and output blif opt_clean -purge -write_blif ${OUTPUT_BLIF} +write_blif rewritten_${OUTPUT_BLIF} # Clear all the designs design -reset # Rewrite the .blif to Verilog # so that the pin sequence matches -read_blif ${OUTPUT_BLIF} +read_blif rewritten_${OUTPUT_BLIF} write_verilog ${OUTPUT_VERILOG} From d21909ad6cfdfaf0f27a04cd891fef5b4d7eac7d Mon Sep 17 00:00:00 2001 From: tangxifan Date: Wed, 10 Mar 2021 13:48:20 -0700 Subject: [PATCH 14/24] [Test] Use custom rewriting script in lut_adder test --- .../tasks/quicklogic_tests/lut_adder_test/config/task.conf | 1 + 1 file changed, 1 insertion(+) diff --git a/openfpga_flow/tasks/quicklogic_tests/lut_adder_test/config/task.conf b/openfpga_flow/tasks/quicklogic_tests/lut_adder_test/config/task.conf index 8f69e98b6..a82abfd59 100644 --- a/openfpga_flow/tasks/quicklogic_tests/lut_adder_test/config/task.conf +++ b/openfpga_flow/tasks/quicklogic_tests/lut_adder_test/config/task.conf @@ -31,6 +31,7 @@ bench1=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/adder_8/ad [SYNTHESIS_PARAM] bench_yosys_common=${PATH:OPENFPGA_PATH}/openfpga_flow/misc/qlf_yosys.ys +bench_yosys_rewrite_common=${PATH:OPENFPGA_PATH}/openfpga_flow/misc/ys_tmpl_yosys_vpr_flow_with_rewrite.ys bench1_top = adder_8 From 90a00da1dfb71f4b6474489286330f2e9d935a4f Mon Sep 17 00:00:00 2001 From: tangxifan Date: Wed, 10 Mar 2021 13:56:35 -0700 Subject: [PATCH 15/24] [Script] Split rewrite yosys scripts into two runs because yosys cannot output consistent verilog files using 'design -reset' --- openfpga_flow/misc/ys_tmpl_rewrite_flow.ys | 4 ++++ openfpga_flow/misc/ys_tmpl_yosys_vpr_flow_with_rewrite.ys | 8 -------- 2 files changed, 4 insertions(+), 8 deletions(-) create mode 100644 openfpga_flow/misc/ys_tmpl_rewrite_flow.ys diff --git a/openfpga_flow/misc/ys_tmpl_rewrite_flow.ys b/openfpga_flow/misc/ys_tmpl_rewrite_flow.ys new file mode 100644 index 000000000..b53746aab --- /dev/null +++ b/openfpga_flow/misc/ys_tmpl_rewrite_flow.ys @@ -0,0 +1,4 @@ +# Rewrite the .blif to Verilog +# so that the pin sequence matches +read_blif rewritten_${OUTPUT_BLIF} +write_verilog ${OUTPUT_VERILOG} diff --git a/openfpga_flow/misc/ys_tmpl_yosys_vpr_flow_with_rewrite.ys b/openfpga_flow/misc/ys_tmpl_yosys_vpr_flow_with_rewrite.ys index b3faf9605..edcce4c23 100644 --- a/openfpga_flow/misc/ys_tmpl_yosys_vpr_flow_with_rewrite.ys +++ b/openfpga_flow/misc/ys_tmpl_yosys_vpr_flow_with_rewrite.ys @@ -20,11 +20,3 @@ synth -run check # Clean and output blif opt_clean -purge write_blif rewritten_${OUTPUT_BLIF} - -# Clear all the designs -design -reset - -# Rewrite the .blif to Verilog -# so that the pin sequence matches -read_blif rewritten_${OUTPUT_BLIF} -write_verilog ${OUTPUT_VERILOG} From b42541d84e8bc65f847728e5b22981fe81594cff Mon Sep 17 00:00:00 2001 From: tangxifan Date: Wed, 10 Mar 2021 14:10:35 -0700 Subject: [PATCH 16/24] [Flow] Support multiple iterations in rewriting yosys scripts --- openfpga_flow/scripts/run_fpga_flow.py | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/openfpga_flow/scripts/run_fpga_flow.py b/openfpga_flow/scripts/run_fpga_flow.py index 499d1bc44..d59594b9d 100644 --- a/openfpga_flow/scripts/run_fpga_flow.py +++ b/openfpga_flow/scripts/run_fpga_flow.py @@ -719,11 +719,16 @@ def run_rewrite_verilog(): for indx in range(0, len(OpenFPGAArgs), 2): tmpVar = OpenFPGAArgs[indx][2:].upper() ys_rewrite_params[tmpVar] = OpenFPGAArgs[indx + 1] - tmpl = Template(open(args.ys_rewrite_tmpl, encoding='utf-8').read()) - with open("yosys_rewrite.ys", 'w') as archfile: - archfile.write(tmpl.safe_substitute(ys_rewrite_params)) - run_command("Run yosys", "yosys_rewrite_output.log", - [cad_tools["yosys_path"], 'yosys_rewrite.ys']) + + # Split a series of scripts by delim ';' + # And execute the scripts serially + for iteration_idx, curr_rewrite_tmpl in enumerate(args.ys_rewrite_tmpl.split(";")): + tmpl = Template(open(curr_rewrite_tmpl, encoding='utf-8').read()) + logger.info("Yosys rewrite iteration: " + str(iteration_idx)) + with open("yosys_rewrite_" + str(iteration_idx) + ".ys", 'w') as archfile: + archfile.write(tmpl.safe_substitute(ys_rewrite_params)) + run_command("Run yosys", "yosys_rewrite_output.log", + [cad_tools["yosys_path"], "yosys_rewrite_" + str(iteration_idx) + ".ys"]) From 7d07f5d8cb88fcad29545e732382a848c1977188 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Wed, 10 Mar 2021 15:34:53 -0700 Subject: [PATCH 17/24] [Test] Update bitstream setting example with mode bit overwriting --- .../lut_adder_test/config/bitstream_annotation.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/openfpga_flow/tasks/quicklogic_tests/lut_adder_test/config/bitstream_annotation.xml b/openfpga_flow/tasks/quicklogic_tests/lut_adder_test/config/bitstream_annotation.xml index 735d45c23..52e7347f2 100644 --- a/openfpga_flow/tasks/quicklogic_tests/lut_adder_test/config/bitstream_annotation.xml +++ b/openfpga_flow/tasks/quicklogic_tests/lut_adder_test/config/bitstream_annotation.xml @@ -1,3 +1,4 @@ + From a6186db3156ad62c643d6ffaee563c8bf15ea7f3 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Wed, 10 Mar 2021 20:45:17 -0700 Subject: [PATCH 18/24] [Test] Update bitstream annotation with new syntax --- .../lut_adder_test/config/bitstream_annotation.xml | 2 +- .../tasks/quicklogic_tests/lut_adder_test/config/task.conf | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/openfpga_flow/tasks/quicklogic_tests/lut_adder_test/config/bitstream_annotation.xml b/openfpga_flow/tasks/quicklogic_tests/lut_adder_test/config/bitstream_annotation.xml index 52e7347f2..b02afba78 100644 --- a/openfpga_flow/tasks/quicklogic_tests/lut_adder_test/config/bitstream_annotation.xml +++ b/openfpga_flow/tasks/quicklogic_tests/lut_adder_test/config/bitstream_annotation.xml @@ -1,4 +1,4 @@ - + diff --git a/openfpga_flow/tasks/quicklogic_tests/lut_adder_test/config/task.conf b/openfpga_flow/tasks/quicklogic_tests/lut_adder_test/config/task.conf index a82abfd59..8d8a16eb6 100644 --- a/openfpga_flow/tasks/quicklogic_tests/lut_adder_test/config/task.conf +++ b/openfpga_flow/tasks/quicklogic_tests/lut_adder_test/config/task.conf @@ -31,7 +31,7 @@ bench1=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/adder_8/ad [SYNTHESIS_PARAM] bench_yosys_common=${PATH:OPENFPGA_PATH}/openfpga_flow/misc/qlf_yosys.ys -bench_yosys_rewrite_common=${PATH:OPENFPGA_PATH}/openfpga_flow/misc/ys_tmpl_yosys_vpr_flow_with_rewrite.ys +bench_yosys_rewrite_common=${PATH:OPENFPGA_PATH}/openfpga_flow/misc/ys_tmpl_yosys_vpr_flow_with_rewrite.ys;${PATH:OPENFPGA_PATH}/openfpga_flow/misc/ys_tmpl_rewrite_flow.ys bench1_top = adder_8 From 85640a74036227b73481ca7c258ecb2e0b0cf26e Mon Sep 17 00:00:00 2001 From: tangxifan Date: Wed, 10 Mar 2021 20:45:48 -0700 Subject: [PATCH 19/24] [Tool] Extend bitstream setting to support mode bits overload from eblif file --- .../libarchopenfpga/src/bitstream_setting.cpp | 25 +++++++++++ .../libarchopenfpga/src/bitstream_setting.h | 10 +++++ .../src/read_xml_bitstream_setting.cpp | 17 ++++--- .../src/write_xml_bitstream_setting.cpp | 2 + .../annotation/vpr_bitstream_annotation.cpp | 45 +++++++++++++++++++ .../src/annotation/vpr_bitstream_annotation.h | 15 +++++++ .../fpga_bitstream/build_grid_bitstream.cpp | 33 ++++++++++++-- openfpga/src/repack/physical_pb.cpp | 37 +++++++++++++++ openfpga/src/repack/physical_pb.h | 13 ++++++ openfpga/src/utils/physical_pb_utils.cpp | 21 ++++++++- 10 files changed, 209 insertions(+), 9 deletions(-) diff --git a/libopenfpga/libarchopenfpga/src/bitstream_setting.cpp b/libopenfpga/libarchopenfpga/src/bitstream_setting.cpp index 924e96c0e..f7a773dad 100644 --- a/libopenfpga/libarchopenfpga/src/bitstream_setting.cpp +++ b/libopenfpga/libarchopenfpga/src/bitstream_setting.cpp @@ -51,6 +51,17 @@ std::string BitstreamSetting::pb_type_bitstream_content(const BitstreamPbTypeSet return pb_type_bitstream_contents_[pb_type_setting_id]; } +bool BitstreamSetting::is_mode_select_bitstream(const BitstreamPbTypeSettingId& pb_type_setting_id) const { + VTR_ASSERT(true == valid_bitstream_pb_type_setting_id(pb_type_setting_id)); + return is_mode_select_bitstreams_[pb_type_setting_id]; +} + +size_t BitstreamSetting::bitstream_offset(const BitstreamPbTypeSettingId& pb_type_setting_id) const { + VTR_ASSERT(true == valid_bitstream_pb_type_setting_id(pb_type_setting_id)); + return bitstream_offsets_[pb_type_setting_id]; +} + + /************************************************************************ * Public Mutators ***********************************************************************/ @@ -66,10 +77,24 @@ BitstreamPbTypeSettingId BitstreamSetting::add_bitstream_pb_type_setting(const s parent_mode_names_.push_back(parent_mode_names); pb_type_bitstream_sources_.push_back(bitstream_source); pb_type_bitstream_contents_.push_back(bitstream_content); + is_mode_select_bitstreams_.push_back(false); + bitstream_offsets_.push_back(0); return pb_type_setting_id; } +void BitstreamSetting::set_mode_select_bitstream(const BitstreamPbTypeSettingId& pb_type_setting_id, + const bool& is_mode_select_bitstream) { + VTR_ASSERT(true == valid_bitstream_pb_type_setting_id(pb_type_setting_id)); + is_mode_select_bitstreams_[pb_type_setting_id] = is_mode_select_bitstream; +} + +void BitstreamSetting::set_bitstream_offset(const BitstreamPbTypeSettingId& pb_type_setting_id, + const size_t& offset) { + VTR_ASSERT(true == valid_bitstream_pb_type_setting_id(pb_type_setting_id)); + bitstream_offsets_[pb_type_setting_id] = offset; +} + /************************************************************************ * Public Validators ***********************************************************************/ diff --git a/libopenfpga/libarchopenfpga/src/bitstream_setting.h b/libopenfpga/libarchopenfpga/src/bitstream_setting.h index d42ebe430..a972bb6c4 100644 --- a/libopenfpga/libarchopenfpga/src/bitstream_setting.h +++ b/libopenfpga/libarchopenfpga/src/bitstream_setting.h @@ -39,12 +39,18 @@ class BitstreamSetting { std::vector parent_mode_names(const BitstreamPbTypeSettingId& pb_type_setting_id) const; std::string pb_type_bitstream_source(const BitstreamPbTypeSettingId& pb_type_setting_id) const; std::string pb_type_bitstream_content(const BitstreamPbTypeSettingId& pb_type_setting_id) const; + bool is_mode_select_bitstream(const BitstreamPbTypeSettingId& pb_type_setting_id) const; + size_t bitstream_offset(const BitstreamPbTypeSettingId& pb_type_setting_id) const; public: /* Public Mutators */ BitstreamPbTypeSettingId add_bitstream_pb_type_setting(const std::string& pb_type_name, const std::vector& parent_pb_type_names, const std::vector& parent_mode_names, const std::string& bitstream_source, const std::string& bitstream_content); + void set_mode_select_bitstream(const BitstreamPbTypeSettingId& pb_type_setting_id, + const bool& is_mode_select_bitstream); + void set_bitstream_offset(const BitstreamPbTypeSettingId& pb_type_setting_id, + const size_t& offset); public: /* Public Validators */ bool valid_bitstream_pb_type_setting_id(const BitstreamPbTypeSettingId& pb_type_setting_id) const; private: /* Internal data */ @@ -54,6 +60,10 @@ class BitstreamSetting { vtr::vector> parent_mode_names_; vtr::vector pb_type_bitstream_sources_; vtr::vector pb_type_bitstream_contents_; + /* Indicate if the bitstream is applied to mode selection bits of a pb_type */ + vtr::vector is_mode_select_bitstreams_; + /* The offset that the bitstream is applied to the original bitstream of a pb_type */ + vtr::vector bitstream_offsets_; }; } /* namespace openfpga ends */ diff --git a/libopenfpga/libarchopenfpga/src/read_xml_bitstream_setting.cpp b/libopenfpga/libarchopenfpga/src/read_xml_bitstream_setting.cpp index 02f257ffe..75a6ae6d8 100644 --- a/libopenfpga/libarchopenfpga/src/read_xml_bitstream_setting.cpp +++ b/libopenfpga/libarchopenfpga/src/read_xml_bitstream_setting.cpp @@ -36,11 +36,18 @@ void read_xml_bitstream_pb_type_setting(pugi::xml_node& xml_pb_type, openfpga::PbParser operating_pb_parser(name_attr); /* Add to bitstream setting */ - bitstream_setting.add_bitstream_pb_type_setting(operating_pb_parser.leaf(), - operating_pb_parser.parents(), - operating_pb_parser.modes(), - source_attr, - content_attr); + BitstreamPbTypeSettingId bitstream_pb_type_id = bitstream_setting.add_bitstream_pb_type_setting(operating_pb_parser.leaf(), + operating_pb_parser.parents(), + operating_pb_parser.modes(), + source_attr, + content_attr); + + /* Parse if the bitstream overwritting is applied to mode bits of a pb_type */ + const bool& is_mode_select_bitstream = get_attribute(xml_pb_type, "is_mode_select_bitstream", loc_data).as_bool(false); + bitstream_setting.set_mode_select_bitstream(bitstream_pb_type_id, is_mode_select_bitstream); + + const int& offset = get_attribute(xml_pb_type, "bitstream_offset", loc_data).as_int(0); + bitstream_setting.set_bitstream_offset(bitstream_pb_type_id, offset); } /******************************************************************** diff --git a/libopenfpga/libarchopenfpga/src/write_xml_bitstream_setting.cpp b/libopenfpga/libarchopenfpga/src/write_xml_bitstream_setting.cpp index 1273f083a..51600cf4f 100644 --- a/libopenfpga/libarchopenfpga/src/write_xml_bitstream_setting.cpp +++ b/libopenfpga/libarchopenfpga/src/write_xml_bitstream_setting.cpp @@ -57,6 +57,8 @@ void write_xml_bitstream_pb_type_setting(std::fstream& fp, write_xml_attribute(fp, "source", bitstream_setting.pb_type_bitstream_source(bitstream_pb_type_setting_id).c_str()); write_xml_attribute(fp, "content", bitstream_setting.pb_type_bitstream_content(bitstream_pb_type_setting_id).c_str()); + write_xml_attribute(fp, "is_mode_select_bitstream", bitstream_setting.is_mode_select_bitstream(bitstream_pb_type_setting_id)); + write_xml_attribute(fp, "bitstream_offset", bitstream_setting.bitstream_offset(bitstream_pb_type_setting_id)); fp << "/>" << "\n"; } diff --git a/openfpga/src/annotation/vpr_bitstream_annotation.cpp b/openfpga/src/annotation/vpr_bitstream_annotation.cpp index fdb66048c..5a221c7d4 100644 --- a/openfpga/src/annotation/vpr_bitstream_annotation.cpp +++ b/openfpga/src/annotation/vpr_bitstream_annotation.cpp @@ -38,6 +38,36 @@ std::string VprBitstreamAnnotation::pb_type_bitstream_content(t_pb_type* pb_type return std::string(); } +bool VprBitstreamAnnotation::pb_type_contain_mode_select_bitstream(t_pb_type* pb_type) const { + auto result = contain_mode_select_bitstreams_.find(pb_type); + if (result != contain_mode_select_bitstreams_.end()) { + return result->second; + } + + /* Not found, return false as default */ + return false; +} + +size_t VprBitstreamAnnotation::pb_type_bitstream_offset(t_pb_type* pb_type) const { + auto result = bitstream_offsets_.find(pb_type); + if (result != bitstream_offsets_.end()) { + return result->second; + } + + /* Not found, return an zero offset */ + return 0; +} + +size_t VprBitstreamAnnotation::pb_type_mode_select_bitstream_offset(t_pb_type* pb_type) const { + auto result = mode_select_bitstream_offsets_.find(pb_type); + if (result != mode_select_bitstream_offsets_.end()) { + return result->second; + } + + /* Not found, return an zero offset */ + return 0; +} + /************************************************************************ * Public mutators ***********************************************************************/ @@ -45,10 +75,25 @@ void VprBitstreamAnnotation::set_pb_type_bitstream_source(t_pb_type* pb_type, const e_bitstream_source_type& bitstream_source) { bitstream_sources_[pb_type] = bitstream_source; } + void VprBitstreamAnnotation::set_pb_type_bitstream_content(t_pb_type* pb_type, const std::string& bitstream_content) { bitstream_contents_[pb_type] = bitstream_content; } +void VprBitstreamAnnotation::set_pb_type_contain_mode_select_bitstream(t_pb_type* pb_type, + const bool& contain_mode_select_bitstream) { + contain_mode_select_bitstreams_[pb_type] = contain_mode_select_bitstream; +} + +void VprBitstreamAnnotation::set_pb_type_bitstream_offset(t_pb_type* pb_type, + const size_t& offset) { + bitstream_offsets_[pb_type] = offset; +} + +void VprBitstreamAnnotation::set_pb_type_mode_select_bitstream_offset(t_pb_type* pb_type, + const size_t& offset) { + mode_select_bitstream_offsets_[pb_type] = offset; +} } /* End namespace openfpga*/ diff --git a/openfpga/src/annotation/vpr_bitstream_annotation.h b/openfpga/src/annotation/vpr_bitstream_annotation.h index c8d4102a0..f12dbc44d 100644 --- a/openfpga/src/annotation/vpr_bitstream_annotation.h +++ b/openfpga/src/annotation/vpr_bitstream_annotation.h @@ -33,16 +33,31 @@ class VprBitstreamAnnotation { public: /* Public accessors */ e_bitstream_source_type pb_type_bitstream_source(t_pb_type* pb_type) const; std::string pb_type_bitstream_content(t_pb_type* pb_type) const; + bool pb_type_contain_mode_select_bitstream(t_pb_type* pb_type) const; + size_t pb_type_bitstream_offset(t_pb_type* pb_type) const; + size_t pb_type_mode_select_bitstream_offset(t_pb_type* pb_type) const; public: /* Public mutators */ void set_pb_type_bitstream_source(t_pb_type* pb_type, const e_bitstream_source_type& bitstream_source); void set_pb_type_bitstream_content(t_pb_type* pb_type, const std::string& bitstream_content); + void set_pb_type_contain_mode_select_bitstream(t_pb_type* pb_type, + const bool& contain_mode_select_bitstream); + void set_pb_type_bitstream_offset(t_pb_type* pb_type, + const size_t& offset); + void set_pb_type_mode_select_bitstream_offset(t_pb_type* pb_type, + const size_t& offset); private: /* Internal data */ /* A look up for pb type to find bitstream source type */ std::map bitstream_sources_; /* Binding from pb type to bitstream content */ std::map bitstream_contents_; + /* A flag to identify if the pb_type has an external mode-select bitstream */ + std::map contain_mode_select_bitstreams_; + /* Offset to be applied to bitstream */ + std::map bitstream_offsets_; + /* Offset to be applied to mode-select bitstream */ + std::map mode_select_bitstream_offsets_; }; } /* End namespace openfpga*/ diff --git a/openfpga/src/fpga_bitstream/build_grid_bitstream.cpp b/openfpga/src/fpga_bitstream/build_grid_bitstream.cpp index c7eca7aee..668ed8e08 100644 --- a/openfpga/src/fpga_bitstream/build_grid_bitstream.cpp +++ b/openfpga/src/fpga_bitstream/build_grid_bitstream.cpp @@ -448,15 +448,19 @@ void build_lut_bitstream(BitstreamManager& bitstream_manager, /* If the physical pb contains fixed bitstream, overload here */ if (false == physical_pb.fixed_bitstream(lut_pb_id).empty()) { std::string fixed_bitstream = physical_pb.fixed_bitstream(lut_pb_id); + size_t start_index = physical_pb.fixed_bitstream_offset(lut_pb_id); /* Ensure the length matches!!! */ - if (lut_bitstream.size() != fixed_bitstream.size()) { + if (lut_bitstream.size() - start_index != fixed_bitstream.size()) { VTR_LOG_ERROR("Unmatched length of fixed bitstream %s!Expected to be %ld bits\n", fixed_bitstream.c_str(), lut_bitstream.size()); exit(1); } - /* Overload here */ - lut_bitstream.clear(); + /* Overload here + * - if there is a non-zero offset, we just erase part of the bitstream + * - otherwise, overwrite the whole bitstream + */ + lut_bitstream.erase(lut_bitstream.begin() + start_index, lut_bitstream.end()); for (const char& fixed_bit : fixed_bitstream) { VTR_ASSERT('0' == fixed_bit || '1' == fixed_bit); lut_bitstream.push_back('1' == fixed_bit); @@ -472,6 +476,29 @@ void build_lut_bitstream(BitstreamManager& bitstream_manager, } else { /* get default mode_bits */ mode_select_bitstream = generate_mode_select_bitstream(device_annotation.pb_type_mode_bits(lut_pb_type)); } + + /* If the physical pb contains fixed mode-select bitstream, overload here */ + if (false == physical_pb.fixed_mode_select_bitstream(lut_pb_id).empty()) { + std::string fixed_mode_select_bitstream = physical_pb.fixed_mode_select_bitstream(lut_pb_id); + size_t mode_bits_start_index = physical_pb.fixed_mode_select_bitstream_offset(lut_pb_id); + /* Ensure the length matches!!! */ + if (mode_select_bitstream.size() - mode_bits_start_index != fixed_mode_select_bitstream.size()) { + VTR_LOG_ERROR("Unmatched length of fixed mode_select_bitstream %s!Expected to be %ld bits\n", + fixed_mode_select_bitstream.c_str(), + mode_select_bitstream.size()); + exit(1); + } + /* Overload here + * - if there is a non-zero offset, we just erase part of the bitstream + * - otherwise, overwrite the whole bitstream + */ + mode_select_bitstream.erase(mode_select_bitstream.begin() + mode_bits_start_index, mode_select_bitstream.end()); + for (const char& fixed_bit : fixed_mode_select_bitstream) { + VTR_ASSERT('0' == fixed_bit || '1' == fixed_bit); + mode_select_bitstream.push_back('1' == fixed_bit); + } + } + /* Conjunct the mode-select bitstream to the lut bitstream */ for (const bool& bit : mode_select_bitstream) { lut_bitstream.push_back(bit); diff --git a/openfpga/src/repack/physical_pb.cpp b/openfpga/src/repack/physical_pb.cpp index c64f05f07..a614d128a 100644 --- a/openfpga/src/repack/physical_pb.cpp +++ b/openfpga/src/repack/physical_pb.cpp @@ -107,6 +107,21 @@ std::string PhysicalPb::fixed_bitstream(const PhysicalPbId& pb) const { return fixed_bitstreams_[pb]; } +size_t PhysicalPb::fixed_bitstream_offset(const PhysicalPbId& pb) const { + VTR_ASSERT(true == valid_pb_id(pb)); + return fixed_bitstream_offsets_[pb]; +} + +std::string PhysicalPb::fixed_mode_select_bitstream(const PhysicalPbId& pb) const { + VTR_ASSERT(true == valid_pb_id(pb)); + return fixed_mode_select_bitstreams_[pb]; +} + +size_t PhysicalPb::fixed_mode_select_bitstream_offset(const PhysicalPbId& pb) const { + VTR_ASSERT(true == valid_pb_id(pb)); + return fixed_mode_select_bitstream_offsets_[pb]; +} + /****************************************************************************** * Private Mutators ******************************************************************************/ @@ -133,7 +148,11 @@ PhysicalPbId PhysicalPb::create_pb(const t_pb_graph_node* pb_graph_node) { truth_tables_.emplace_back(); mode_bits_.emplace_back(); + fixed_bitstreams_.emplace_back(); + fixed_bitstream_offsets_.push_back(0); + fixed_mode_select_bitstreams_.emplace_back(); + fixed_mode_select_bitstream_offsets_.push_back(0); /* Register in the name2id map */ type2id_map_[pb_graph_node] = pb; @@ -218,6 +237,24 @@ void PhysicalPb::set_fixed_bitstream(const PhysicalPbId& pb, fixed_bitstreams_[pb] = fixed_bitstream; } +void PhysicalPb::set_fixed_bitstream_offset(const PhysicalPbId& pb, + const size_t& offset) { + VTR_ASSERT(true == valid_pb_id(pb)); + fixed_bitstream_offsets_[pb] = offset; +} + +void PhysicalPb::set_fixed_mode_select_bitstream(const PhysicalPbId& pb, + const std::string& fixed_bitstream) { + VTR_ASSERT(true == valid_pb_id(pb)); + fixed_mode_select_bitstreams_[pb] = fixed_bitstream; +} + +void PhysicalPb::set_fixed_mode_select_bitstream_offset(const PhysicalPbId& pb, + const size_t& offset) { + VTR_ASSERT(true == valid_pb_id(pb)); + fixed_mode_select_bitstream_offsets_[pb] = offset; +} + /****************************************************************************** * Private validators/invalidators ******************************************************************************/ diff --git a/openfpga/src/repack/physical_pb.h b/openfpga/src/repack/physical_pb.h index 078cc6bc9..7ce42a3c8 100644 --- a/openfpga/src/repack/physical_pb.h +++ b/openfpga/src/repack/physical_pb.h @@ -55,6 +55,9 @@ class PhysicalPb { std::map truth_tables(const PhysicalPbId& pb) const; std::vector mode_bits(const PhysicalPbId& pb) const; std::string fixed_bitstream(const PhysicalPbId& pb) const; + size_t fixed_bitstream_offset(const PhysicalPbId& pb) const; + std::string fixed_mode_select_bitstream(const PhysicalPbId& pb) const; + size_t fixed_mode_select_bitstream_offset(const PhysicalPbId& pb) const; public: /* Public mutators */ PhysicalPbId create_pb(const t_pb_graph_node* pb_graph_node); void add_child(const PhysicalPbId& parent, @@ -75,6 +78,12 @@ class PhysicalPb { const bool& wire_lut_output); void set_fixed_bitstream(const PhysicalPbId& pb, const std::string& fixed_bitstream); + void set_fixed_bitstream_offset(const PhysicalPbId& pb, + const size_t& offset); + void set_fixed_mode_select_bitstream(const PhysicalPbId& pb, + const std::string& fixed_bitstream); + void set_fixed_mode_select_bitstream_offset(const PhysicalPbId& pb, + const size_t& offset); public: /* Public validators/invalidators */ bool valid_pb_id(const PhysicalPbId& pb_id) const; bool empty() const; @@ -98,6 +107,10 @@ class PhysicalPb { vtr::vector> mode_bits_; vtr::vector fixed_bitstreams_; + vtr::vector fixed_bitstream_offsets_; + + vtr::vector fixed_mode_select_bitstreams_; + vtr::vector fixed_mode_select_bitstream_offsets_; /* Fast lookup */ std::map type2id_map_; diff --git a/openfpga/src/utils/physical_pb_utils.cpp b/openfpga/src/utils/physical_pb_utils.cpp index adecd847c..9b2668d13 100644 --- a/openfpga/src/utils/physical_pb_utils.cpp +++ b/openfpga/src/utils/physical_pb_utils.cpp @@ -313,16 +313,35 @@ void rec_update_physical_pb_from_operating_pb(PhysicalPb& phy_pb, std::vector tokens = tokenizer.split(" "); /* FIXME: The token-level check should be done much earlier!!! */ VTR_ASSERT(2 == tokens.size()); + /* The token is typically organized as <.param|.attr> */ if (std::string(".param") == tokens[0]) { for (const auto& param_search : atom_ctx.nlist.block_params(atom_blk)) { - if (param_search.first == tokens[1]) { + /* Bypass unmatched parameter identifier */ + if (param_search.first != tokens[1]) { + continue; + } + if (false == bitstream_annotation.pb_type_contain_mode_select_bitstream(pb_type)) { phy_pb.set_fixed_bitstream(physical_pb, param_search.second); + phy_pb.set_fixed_bitstream_offset(physical_pb, bitstream_annotation.pb_type_bitstream_offset(pb_type)); + } else { + VTR_ASSERT_SAFE(true == bitstream_annotation.pb_type_contain_mode_select_bitstream(pb_type)); + phy_pb.set_fixed_mode_select_bitstream(physical_pb, param_search.second); + phy_pb.set_fixed_mode_select_bitstream_offset(physical_pb, bitstream_annotation.pb_type_mode_select_bitstream_offset(pb_type)); } } } else if (std::string(".attr") == tokens[0]) { for (const auto& attr_search : atom_ctx.nlist.block_attrs(atom_blk)) { + /* Bypass unmatched parameter identifier */ if (attr_search.first == tokens[1]) { + continue; + } + if (false == bitstream_annotation.pb_type_contain_mode_select_bitstream(pb_type)) { phy_pb.set_fixed_bitstream(physical_pb, attr_search.second); + phy_pb.set_fixed_bitstream_offset(physical_pb, bitstream_annotation.pb_type_bitstream_offset(pb_type)); + } else { + VTR_ASSERT_SAFE(true == bitstream_annotation.pb_type_contain_mode_select_bitstream(pb_type)); + phy_pb.set_fixed_mode_select_bitstream(physical_pb, attr_search.second); + phy_pb.set_fixed_mode_select_bitstream_offset(physical_pb, bitstream_annotation.pb_type_mode_select_bitstream_offset(pb_type)); } } } From d877a02534e99cacc53a8ddb3c853859b9ffb063 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Wed, 10 Mar 2021 21:28:09 -0700 Subject: [PATCH 20/24] [Tool] Patch the extended bitstream setting support on mode-select bits --- .../src/read_xml_bitstream_setting.cpp | 4 +- .../annotation/annotate_bitstream_setting.cpp | 21 +++++-- .../annotation/vpr_bitstream_annotation.cpp | 45 +++++++++----- .../src/annotation/vpr_bitstream_annotation.h | 20 +++++-- .../fpga_bitstream/build_grid_bitstream.cpp | 59 ++++++++----------- openfpga/src/utils/physical_pb_utils.cpp | 53 +++++++++++------ 6 files changed, 126 insertions(+), 76 deletions(-) diff --git a/libopenfpga/libarchopenfpga/src/read_xml_bitstream_setting.cpp b/libopenfpga/libarchopenfpga/src/read_xml_bitstream_setting.cpp index 75a6ae6d8..181ee531c 100644 --- a/libopenfpga/libarchopenfpga/src/read_xml_bitstream_setting.cpp +++ b/libopenfpga/libarchopenfpga/src/read_xml_bitstream_setting.cpp @@ -43,10 +43,10 @@ void read_xml_bitstream_pb_type_setting(pugi::xml_node& xml_pb_type, content_attr); /* Parse if the bitstream overwritting is applied to mode bits of a pb_type */ - const bool& is_mode_select_bitstream = get_attribute(xml_pb_type, "is_mode_select_bitstream", loc_data).as_bool(false); + const bool& is_mode_select_bitstream = get_attribute(xml_pb_type, "is_mode_select_bitstream", loc_data, pugiutil::ReqOpt::OPTIONAL).as_bool(false); bitstream_setting.set_mode_select_bitstream(bitstream_pb_type_id, is_mode_select_bitstream); - const int& offset = get_attribute(xml_pb_type, "bitstream_offset", loc_data).as_int(0); + const int& offset = get_attribute(xml_pb_type, "bitstream_offset", loc_data, pugiutil::ReqOpt::OPTIONAL).as_int(0); bitstream_setting.set_bitstream_offset(bitstream_pb_type_id, offset); } diff --git a/openfpga/src/annotation/annotate_bitstream_setting.cpp b/openfpga/src/annotation/annotate_bitstream_setting.cpp index fbcb92cf0..48002a08b 100644 --- a/openfpga/src/annotation/annotate_bitstream_setting.cpp +++ b/openfpga/src/annotation/annotate_bitstream_setting.cpp @@ -56,17 +56,30 @@ int annotate_bitstream_setting(const BitstreamSetting& bitstream_setting, if (nullptr == target_pb_type) { continue; } + /* Found one, build annotation */ - if (std::string("eblif") == bitstream_setting.pb_type_bitstream_source(bitstream_pb_type_setting_id)) { - vpr_bitstream_annotation.set_pb_type_bitstream_source(target_pb_type, VprBitstreamAnnotation::e_bitstream_source_type::BITSTREAM_SOURCE_EBLIF); - } else { + if (std::string("eblif") != bitstream_setting.pb_type_bitstream_source(bitstream_pb_type_setting_id)) { /* Invalid source, error out! */ VTR_LOG_ERROR("Invalid bitstream source '%s' for pb_type '%s' which is defined in bitstream setting\n", bitstream_setting.pb_type_bitstream_source(bitstream_pb_type_setting_id).c_str(), target_pb_type_names[0].c_str()); return CMD_EXEC_FATAL_ERROR; } - vpr_bitstream_annotation.set_pb_type_bitstream_content(target_pb_type, bitstream_setting.pb_type_bitstream_content(bitstream_pb_type_setting_id)); + + /* Depending on the bitstream type, annotate through different entrances + * - For regular bitstream, set bitstream content, flags etc. + * - For mode-select bitstream, set mode-select bitstream content, flags etc. + */ + if (false == bitstream_setting.is_mode_select_bitstream(bitstream_pb_type_setting_id)) { + vpr_bitstream_annotation.set_pb_type_bitstream_source(target_pb_type, VprBitstreamAnnotation::e_bitstream_source_type::BITSTREAM_SOURCE_EBLIF); + vpr_bitstream_annotation.set_pb_type_bitstream_content(target_pb_type, bitstream_setting.pb_type_bitstream_content(bitstream_pb_type_setting_id)); + vpr_bitstream_annotation.set_pb_type_bitstream_offset(target_pb_type, bitstream_setting.bitstream_offset(bitstream_pb_type_setting_id)); + } else { + VTR_ASSERT_SAFE(false == bitstream_setting.is_mode_select_bitstream(bitstream_pb_type_setting_id)); + vpr_bitstream_annotation.set_pb_type_mode_select_bitstream_source(target_pb_type, VprBitstreamAnnotation::e_bitstream_source_type::BITSTREAM_SOURCE_EBLIF); + vpr_bitstream_annotation.set_pb_type_mode_select_bitstream_content(target_pb_type, bitstream_setting.pb_type_bitstream_content(bitstream_pb_type_setting_id)); + vpr_bitstream_annotation.set_pb_type_mode_select_bitstream_offset(target_pb_type, bitstream_setting.bitstream_offset(bitstream_pb_type_setting_id)); + } link_success = true; } diff --git a/openfpga/src/annotation/vpr_bitstream_annotation.cpp b/openfpga/src/annotation/vpr_bitstream_annotation.cpp index 5a221c7d4..3361d598c 100644 --- a/openfpga/src/annotation/vpr_bitstream_annotation.cpp +++ b/openfpga/src/annotation/vpr_bitstream_annotation.cpp @@ -38,16 +38,6 @@ std::string VprBitstreamAnnotation::pb_type_bitstream_content(t_pb_type* pb_type return std::string(); } -bool VprBitstreamAnnotation::pb_type_contain_mode_select_bitstream(t_pb_type* pb_type) const { - auto result = contain_mode_select_bitstreams_.find(pb_type); - if (result != contain_mode_select_bitstreams_.end()) { - return result->second; - } - - /* Not found, return false as default */ - return false; -} - size_t VprBitstreamAnnotation::pb_type_bitstream_offset(t_pb_type* pb_type) const { auto result = bitstream_offsets_.find(pb_type); if (result != bitstream_offsets_.end()) { @@ -58,6 +48,26 @@ size_t VprBitstreamAnnotation::pb_type_bitstream_offset(t_pb_type* pb_type) cons return 0; } +VprBitstreamAnnotation::e_bitstream_source_type VprBitstreamAnnotation::pb_type_mode_select_bitstream_source(t_pb_type* pb_type) const { + auto result = mode_select_bitstream_sources_.find(pb_type); + if (result != mode_select_bitstream_sources_.end()) { + return result->second; + } + + /* Not found, return an invalid type*/ + return NUM_BITSTREAM_SOURCE_TYPES; +} + +std::string VprBitstreamAnnotation::pb_type_mode_select_bitstream_content(t_pb_type* pb_type) const { + auto result = mode_select_bitstream_contents_.find(pb_type); + if (result != mode_select_bitstream_contents_.end()) { + return result->second; + } + + /* Not found, return an invalid type */ + return std::string(); +} + size_t VprBitstreamAnnotation::pb_type_mode_select_bitstream_offset(t_pb_type* pb_type) const { auto result = mode_select_bitstream_offsets_.find(pb_type); if (result != mode_select_bitstream_offsets_.end()) { @@ -81,16 +91,21 @@ void VprBitstreamAnnotation::set_pb_type_bitstream_content(t_pb_type* pb_type, bitstream_contents_[pb_type] = bitstream_content; } -void VprBitstreamAnnotation::set_pb_type_contain_mode_select_bitstream(t_pb_type* pb_type, - const bool& contain_mode_select_bitstream) { - contain_mode_select_bitstreams_[pb_type] = contain_mode_select_bitstream; -} - void VprBitstreamAnnotation::set_pb_type_bitstream_offset(t_pb_type* pb_type, const size_t& offset) { bitstream_offsets_[pb_type] = offset; } +void VprBitstreamAnnotation::set_pb_type_mode_select_bitstream_source(t_pb_type* pb_type, + const e_bitstream_source_type& bitstream_source) { + mode_select_bitstream_sources_[pb_type] = bitstream_source; +} + +void VprBitstreamAnnotation::set_pb_type_mode_select_bitstream_content(t_pb_type* pb_type, + const std::string& bitstream_content) { + mode_select_bitstream_contents_[pb_type] = bitstream_content; +} + void VprBitstreamAnnotation::set_pb_type_mode_select_bitstream_offset(t_pb_type* pb_type, const size_t& offset) { mode_select_bitstream_offsets_[pb_type] = offset; diff --git a/openfpga/src/annotation/vpr_bitstream_annotation.h b/openfpga/src/annotation/vpr_bitstream_annotation.h index f12dbc44d..c562e4aa2 100644 --- a/openfpga/src/annotation/vpr_bitstream_annotation.h +++ b/openfpga/src/annotation/vpr_bitstream_annotation.h @@ -33,29 +33,39 @@ class VprBitstreamAnnotation { public: /* Public accessors */ e_bitstream_source_type pb_type_bitstream_source(t_pb_type* pb_type) const; std::string pb_type_bitstream_content(t_pb_type* pb_type) const; - bool pb_type_contain_mode_select_bitstream(t_pb_type* pb_type) const; size_t pb_type_bitstream_offset(t_pb_type* pb_type) const; + + e_bitstream_source_type pb_type_mode_select_bitstream_source(t_pb_type* pb_type) const; + std::string pb_type_mode_select_bitstream_content(t_pb_type* pb_type) const; size_t pb_type_mode_select_bitstream_offset(t_pb_type* pb_type) const; public: /* Public mutators */ void set_pb_type_bitstream_source(t_pb_type* pb_type, const e_bitstream_source_type& bitstream_source); void set_pb_type_bitstream_content(t_pb_type* pb_type, const std::string& bitstream_content); - void set_pb_type_contain_mode_select_bitstream(t_pb_type* pb_type, - const bool& contain_mode_select_bitstream); void set_pb_type_bitstream_offset(t_pb_type* pb_type, const size_t& offset); + + void set_pb_type_mode_select_bitstream_source(t_pb_type* pb_type, + const e_bitstream_source_type& bitstream_source); + void set_pb_type_mode_select_bitstream_content(t_pb_type* pb_type, + const std::string& bitstream_content); void set_pb_type_mode_select_bitstream_offset(t_pb_type* pb_type, const size_t& offset); private: /* Internal data */ + /* For regular bitstreams */ /* A look up for pb type to find bitstream source type */ std::map bitstream_sources_; /* Binding from pb type to bitstream content */ std::map bitstream_contents_; - /* A flag to identify if the pb_type has an external mode-select bitstream */ - std::map contain_mode_select_bitstreams_; /* Offset to be applied to bitstream */ std::map bitstream_offsets_; + + /* For mode-select bitstreams */ + /* A look up for pb type to find bitstream source type */ + std::map mode_select_bitstream_sources_; + /* Binding from pb type to bitstream content */ + std::map mode_select_bitstream_contents_; /* Offset to be applied to mode-select bitstream */ std::map mode_select_bitstream_offsets_; }; diff --git a/openfpga/src/fpga_bitstream/build_grid_bitstream.cpp b/openfpga/src/fpga_bitstream/build_grid_bitstream.cpp index 668ed8e08..f0cfab7dd 100644 --- a/openfpga/src/fpga_bitstream/build_grid_bitstream.cpp +++ b/openfpga/src/fpga_bitstream/build_grid_bitstream.cpp @@ -450,20 +450,16 @@ void build_lut_bitstream(BitstreamManager& bitstream_manager, std::string fixed_bitstream = physical_pb.fixed_bitstream(lut_pb_id); size_t start_index = physical_pb.fixed_bitstream_offset(lut_pb_id); /* Ensure the length matches!!! */ - if (lut_bitstream.size() - start_index != fixed_bitstream.size()) { - VTR_LOG_ERROR("Unmatched length of fixed bitstream %s!Expected to be %ld bits\n", + if (lut_bitstream.size() - start_index < fixed_bitstream.size()) { + VTR_LOG_ERROR("Unmatched length of fixed bitstream %s!Expected to be less than %ld bits\n", fixed_bitstream.c_str(), - lut_bitstream.size()); + lut_bitstream.size() - start_index); exit(1); } - /* Overload here - * - if there is a non-zero offset, we just erase part of the bitstream - * - otherwise, overwrite the whole bitstream - */ - lut_bitstream.erase(lut_bitstream.begin() + start_index, lut_bitstream.end()); - for (const char& fixed_bit : fixed_bitstream) { - VTR_ASSERT('0' == fixed_bit || '1' == fixed_bit); - lut_bitstream.push_back('1' == fixed_bit); + /* Overload the bitstream here */ + for (size_t bit_index = 0; bit_index < lut_bitstream.size(); ++bit_index) { + VTR_ASSERT('0' == fixed_bitstream[bit_index] || '1' == fixed_bitstream[bit_index]); + lut_bitstream[bit_index + start_index] = ('1' == fixed_bitstream[bit_index]); } } } @@ -473,32 +469,29 @@ void build_lut_bitstream(BitstreamManager& bitstream_manager, std::vector mode_select_bitstream; if (true == physical_pb.valid_pb_id(lut_pb_id)) { mode_select_bitstream = generate_mode_select_bitstream(physical_pb.mode_bits(lut_pb_id)); + + /* If the physical pb contains fixed mode-select bitstream, overload here */ + if (false == physical_pb.fixed_mode_select_bitstream(lut_pb_id).empty()) { + std::string fixed_mode_select_bitstream = physical_pb.fixed_mode_select_bitstream(lut_pb_id); + size_t mode_bits_start_index = physical_pb.fixed_mode_select_bitstream_offset(lut_pb_id); + /* Ensure the length matches!!! */ + if (mode_select_bitstream.size() - mode_bits_start_index < fixed_mode_select_bitstream.size()) { + VTR_LOG_ERROR("Unmatched length of fixed mode_select_bitstream %s!Expected to be less than %ld bits\n", + fixed_mode_select_bitstream.c_str(), + mode_select_bitstream.size() - mode_bits_start_index); + exit(1); + } + /* Overload the bitstream here */ + for (size_t bit_index = 0; bit_index < fixed_mode_select_bitstream.size(); ++bit_index) { + VTR_ASSERT('0' == fixed_mode_select_bitstream[bit_index] || '1' == fixed_mode_select_bitstream[bit_index]); + mode_select_bitstream[bit_index + mode_bits_start_index] = ('1' == fixed_mode_select_bitstream[bit_index]); + } + + } } else { /* get default mode_bits */ mode_select_bitstream = generate_mode_select_bitstream(device_annotation.pb_type_mode_bits(lut_pb_type)); } - /* If the physical pb contains fixed mode-select bitstream, overload here */ - if (false == physical_pb.fixed_mode_select_bitstream(lut_pb_id).empty()) { - std::string fixed_mode_select_bitstream = physical_pb.fixed_mode_select_bitstream(lut_pb_id); - size_t mode_bits_start_index = physical_pb.fixed_mode_select_bitstream_offset(lut_pb_id); - /* Ensure the length matches!!! */ - if (mode_select_bitstream.size() - mode_bits_start_index != fixed_mode_select_bitstream.size()) { - VTR_LOG_ERROR("Unmatched length of fixed mode_select_bitstream %s!Expected to be %ld bits\n", - fixed_mode_select_bitstream.c_str(), - mode_select_bitstream.size()); - exit(1); - } - /* Overload here - * - if there is a non-zero offset, we just erase part of the bitstream - * - otherwise, overwrite the whole bitstream - */ - mode_select_bitstream.erase(mode_select_bitstream.begin() + mode_bits_start_index, mode_select_bitstream.end()); - for (const char& fixed_bit : fixed_mode_select_bitstream) { - VTR_ASSERT('0' == fixed_bit || '1' == fixed_bit); - mode_select_bitstream.push_back('1' == fixed_bit); - } - } - /* Conjunct the mode-select bitstream to the lut bitstream */ for (const bool& bit : mode_select_bitstream) { lut_bitstream.push_back(bit); diff --git a/openfpga/src/utils/physical_pb_utils.cpp b/openfpga/src/utils/physical_pb_utils.cpp index 9b2668d13..2b366c305 100644 --- a/openfpga/src/utils/physical_pb_utils.cpp +++ b/openfpga/src/utils/physical_pb_utils.cpp @@ -304,7 +304,7 @@ void rec_update_physical_pb_from_operating_pb(PhysicalPb& phy_pb, VTR_ASSERT(atom_blk); phy_pb.add_atom_block(physical_pb, atom_blk); - + /* if the operating pb type has bitstream annotation, * bind the bitstream value from atom block to the physical pb */ @@ -320,14 +320,8 @@ void rec_update_physical_pb_from_operating_pb(PhysicalPb& phy_pb, if (param_search.first != tokens[1]) { continue; } - if (false == bitstream_annotation.pb_type_contain_mode_select_bitstream(pb_type)) { - phy_pb.set_fixed_bitstream(physical_pb, param_search.second); - phy_pb.set_fixed_bitstream_offset(physical_pb, bitstream_annotation.pb_type_bitstream_offset(pb_type)); - } else { - VTR_ASSERT_SAFE(true == bitstream_annotation.pb_type_contain_mode_select_bitstream(pb_type)); - phy_pb.set_fixed_mode_select_bitstream(physical_pb, param_search.second); - phy_pb.set_fixed_mode_select_bitstream_offset(physical_pb, bitstream_annotation.pb_type_mode_select_bitstream_offset(pb_type)); - } + phy_pb.set_fixed_bitstream(physical_pb, param_search.second); + phy_pb.set_fixed_bitstream_offset(physical_pb, bitstream_annotation.pb_type_bitstream_offset(pb_type)); } } else if (std::string(".attr") == tokens[0]) { for (const auto& attr_search : atom_ctx.nlist.block_attrs(atom_blk)) { @@ -335,14 +329,39 @@ void rec_update_physical_pb_from_operating_pb(PhysicalPb& phy_pb, if (attr_search.first == tokens[1]) { continue; } - if (false == bitstream_annotation.pb_type_contain_mode_select_bitstream(pb_type)) { - phy_pb.set_fixed_bitstream(physical_pb, attr_search.second); - phy_pb.set_fixed_bitstream_offset(physical_pb, bitstream_annotation.pb_type_bitstream_offset(pb_type)); - } else { - VTR_ASSERT_SAFE(true == bitstream_annotation.pb_type_contain_mode_select_bitstream(pb_type)); - phy_pb.set_fixed_mode_select_bitstream(physical_pb, attr_search.second); - phy_pb.set_fixed_mode_select_bitstream_offset(physical_pb, bitstream_annotation.pb_type_mode_select_bitstream_offset(pb_type)); - } + phy_pb.set_fixed_bitstream(physical_pb, attr_search.second); + phy_pb.set_fixed_bitstream_offset(physical_pb, bitstream_annotation.pb_type_bitstream_offset(pb_type)); + } + } + } + + + /* if the operating pb type has mode-select bitstream annotation, + * bind the bitstream value from atom block to the physical pb + */ + if (VprBitstreamAnnotation::e_bitstream_source_type::BITSTREAM_SOURCE_EBLIF == bitstream_annotation.pb_type_mode_select_bitstream_source(pb_type)) { + StringToken tokenizer = bitstream_annotation.pb_type_mode_select_bitstream_content(pb_type); + std::vector tokens = tokenizer.split(" "); + /* FIXME: The token-level check should be done much earlier!!! */ + VTR_ASSERT(2 == tokens.size()); + /* The token is typically organized as <.param|.attr> */ + if (std::string(".param") == tokens[0]) { + for (const auto& param_search : atom_ctx.nlist.block_params(atom_blk)) { + /* Bypass unmatched parameter identifier */ + if (param_search.first != tokens[1]) { + continue; + } + phy_pb.set_fixed_mode_select_bitstream(physical_pb, param_search.second); + phy_pb.set_fixed_mode_select_bitstream_offset(physical_pb, bitstream_annotation.pb_type_mode_select_bitstream_offset(pb_type)); + } + } else if (std::string(".attr") == tokens[0]) { + for (const auto& attr_search : atom_ctx.nlist.block_attrs(atom_blk)) { + /* Bypass unmatched parameter identifier */ + if (attr_search.first == tokens[1]) { + continue; + } + phy_pb.set_fixed_mode_select_bitstream(physical_pb, attr_search.second); + phy_pb.set_fixed_mode_select_bitstream_offset(physical_pb, bitstream_annotation.pb_type_mode_select_bitstream_offset(pb_type)); } } } From ff0faeb2855e0403cf43ec617b65eb2719aac1dc Mon Sep 17 00:00:00 2001 From: tangxifan Date: Wed, 10 Mar 2021 21:41:59 -0700 Subject: [PATCH 21/24] [Doc] Update documentation about the extended bitstream setting --- docs/source/manual/arch_lang/annotate_vpr_arch.rst | 2 ++ .../manual/file_formats/bitstream_setting.rst | 14 ++++++++++++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/docs/source/manual/arch_lang/annotate_vpr_arch.rst b/docs/source/manual/arch_lang/annotate_vpr_arch.rst index ea128cb1c..239d10dfb 100644 --- a/docs/source/manual/arch_lang/annotate_vpr_arch.rst +++ b/docs/source/manual/arch_lang/annotate_vpr_arch.rst @@ -136,6 +136,8 @@ When a global port, e.g., ``clk``, is defined in ``tile_annotation`` using the f Clock port ``clk`` of each ``clb`` tile will be connected to a common clock port of the top module, while local clock network is customizable through VPR's architecture description language. For instance, the local clock network can be a programmable clock network. +.. _annotate_vpr_arch_pb_type_annotation: + Primitive Blocks inside Multi-mode Configurable Logic Blocks ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/docs/source/manual/file_formats/bitstream_setting.rst b/docs/source/manual/file_formats/bitstream_setting.rst index b21bd0c25..d5d4649b4 100644 --- a/docs/source/manual/file_formats/bitstream_setting.rst +++ b/docs/source/manual/file_formats/bitstream_setting.rst @@ -9,7 +9,7 @@ This can define a hard-coded bitstream for a reconfigurable resource in FPGA fab .. code-block:: xml - + .. option:: pb_type="" @@ -24,4 +24,14 @@ This can define a hard-coded bitstream for a reconfigurable resource in FPGA fab The content of the ``pb_type`` bitstream, which could be a keyword in a ``.eblif`` file. For example, ``content=".attr LUT"`` means that the bitstream will be extracted from the ``.attr LUT`` line which is defined under the ``.blif model`` (that is defined under the ``pb_type`` in VPR architecture file). -.. warning:: Bitstream is a feature for power-users. It may cause wrong bitstream to be generated. For example, the hard-coded bitstream is not compatible with LUTs whose nets may be swapped during routing stage (cause a change on the truth table as well as bitstream). It is users's responsibility to ensure correct bitstream. + +.. option:: is_mode_select_bitstream="" + + Can be either ``true`` or ``false``. When set ``true``, the bitstream is considered as mode-selection bitstream, which may overwrite ``mode_bits`` definition in ``pb_type_annotation`` of OpenFPGA architecture description. (See details in :ref:`annotate_vpr_arch_pb_type_annotation`) + +.. option:: bitstream_offset="" + + Specify the offset to be applied when overloading the bitstream to a target. For example, a LUT may have a 16-bit bitstream. When ``offset=1``, bitstream overloading will skip the first bit and start from the second bit of the 16-bit bitstream. + +.. warning:: Bitstream setting is a feature for power-users. It may cause wrong bitstream to be generated. For example, the hard-coded bitstream is not compatible with LUTs whose nets may be swapped during routing stage (cause a change on the truth table as well as bitstream). It is users's responsibility to ensure correct bitstream. + From baf162e401d901e4aa782dabd1080755b57375c7 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Wed, 10 Mar 2021 22:45:19 -0700 Subject: [PATCH 22/24] [Arch] Comment out dummy circuit model for adder_lut model in QL's cell sim library. which is no longer used in verification --- ...r_scan_chain_caravel_io_skywater130nm_fdhd_cc_openfpga.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openfpga_flow/openfpga_arch/k4_frac_N8_reset_softadderSuperLUT_register_scan_chain_caravel_io_skywater130nm_fdhd_cc_openfpga.xml b/openfpga_flow/openfpga_arch/k4_frac_N8_reset_softadderSuperLUT_register_scan_chain_caravel_io_skywater130nm_fdhd_cc_openfpga.xml index fbf6a05f0..796f9974d 100644 --- a/openfpga_flow/openfpga_arch/k4_frac_N8_reset_softadderSuperLUT_register_scan_chain_caravel_io_skywater130nm_fdhd_cc_openfpga.xml +++ b/openfpga_flow/openfpga_arch/k4_frac_N8_reset_softadderSuperLUT_register_scan_chain_caravel_io_skywater130nm_fdhd_cc_openfpga.xml @@ -206,9 +206,9 @@ - + From bb2a02c9ad46cf2e3fa1b270a542dbd69cc22374 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Thu, 11 Mar 2021 15:23:14 -0700 Subject: [PATCH 23/24] [HDL] Patch the superLUT HDL code to be consistent with (qlf_k4n8_sim.v)[https://github.com/lnsharma/yosys/blob/add_qlf_k4n8_dev/techlibs/quicklogic/qlf_k4n8_cells_sim.v] --- openfpga_flow/openfpga_cell_library/verilog/frac_lut4_arith.v | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openfpga_flow/openfpga_cell_library/verilog/frac_lut4_arith.v b/openfpga_flow/openfpga_cell_library/verilog/frac_lut4_arith.v index 0b5461615..d5410b5bf 100644 --- a/openfpga_flow/openfpga_cell_library/verilog/frac_lut4_arith.v +++ b/openfpga_flow/openfpga_cell_library/verilog/frac_lut4_arith.v @@ -63,7 +63,7 @@ wire [0:0] sky130_fd_sc_hd__or2_1_0_X; .A(in[1]), .Y(sky130_fd_sc_hd__inv_1_1_Y[0])); - assign arith_in2 = mode[0] ? in[2] : cin; + assign arith_in2 = mode[0] ? cin : in[2]; sky130_fd_sc_hd__inv_1 sky130_fd_sc_hd__inv_1_2_ ( .A(arith_in2), @@ -82,7 +82,7 @@ wire [0:0] sky130_fd_sc_hd__or2_1_0_X; .X(sky130_fd_sc_hd__buf_2_1_X[0])); sky130_fd_sc_hd__buf_2 sky130_fd_sc_hd__buf_2_2_ ( - .A(in[2]), + .A(arith_in2), .X(sky130_fd_sc_hd__buf_2_2_X[0])); sky130_fd_sc_hd__buf_2 sky130_fd_sc_hd__buf_2_3_ ( From 366bec232cd430027ef5a0005997cf5acbf97ff6 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Thu, 11 Mar 2021 15:25:48 -0700 Subject: [PATCH 24/24] [Test] Now lut_adder_test passed end-of-flow verification; Deploy it to CI --- .../tasks/quicklogic_tests/lut_adder_test/config/task.conf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openfpga_flow/tasks/quicklogic_tests/lut_adder_test/config/task.conf b/openfpga_flow/tasks/quicklogic_tests/lut_adder_test/config/task.conf index 8d8a16eb6..9ef0f4f94 100644 --- a/openfpga_flow/tasks/quicklogic_tests/lut_adder_test/config/task.conf +++ b/openfpga_flow/tasks/quicklogic_tests/lut_adder_test/config/task.conf @@ -40,5 +40,5 @@ bench1_top = adder_8 # The output verilog of yosys is not synthesizable!!! # Turn off verification for now # SHOULD focus on fixing the Verilog problem and run verification at the end of the flow -#end_flow_with_test= -#vpr_fpga_verilog_formal_verification_top_netlist= +end_flow_with_test= +vpr_fpga_verilog_formal_verification_top_netlist=