From a355977420ac6372840a325b84595fd80bdf5eab Mon Sep 17 00:00:00 2001 From: Aram Kostanyan Date: Fri, 29 Oct 2021 18:34:27 +0500 Subject: [PATCH] Adding Yosys+Verific support. --- .../manual/openfpga_flow/run_fpga_flow.rst | 16 ++- .../manual/openfpga_flow/run_fpga_task.rst | 69 +++++++++- openfpga_flow/scripts/run_fpga_flow.py | 121 ++++++++++++++---- openfpga_flow/scripts/run_fpga_task.py | 3 + 4 files changed, 181 insertions(+), 28 deletions(-) diff --git a/docs/source/manual/openfpga_flow/run_fpga_flow.rst b/docs/source/manual/openfpga_flow/run_fpga_flow.rst index c73ebbdb9..b3dedb86f 100755 --- a/docs/source/manual/openfpga_flow/run_fpga_flow.rst +++ b/docs/source/manual/openfpga_flow/run_fpga_flow.rst @@ -109,8 +109,20 @@ General Arguments .. option:: --yosys_tmpl - This option allows the user to provide a custom Yosys template - While running a yosys_vpr flow. Default template is stored in a directory ``open_fpga_flow\misc\ys_tmpl_yosys_vpr_flow.ys``. Yosys template script supports ``TOP_MODULE`` ``READ_VERILOG_FILE`` ``LUT_SIZE`` & ``OUTPUT_BLIF`` variables, which can be used as ``${var_name}``. Alternately, user can create a copy and modify according to their need. + This option allows the user to provide a custom Yosys template while running a yosys_vpr flow. Default template is stored in a directory ``open_fpga_flow\misc\ys_tmpl_yosys_vpr_flow.ys``. Alternately, user can create a copy and modify according to their need. Yosys template script supports ``TOP_MODULE`` ``READ_VERILOG_FILE`` ``LUT_SIZE`` & ``OUTPUT_BLIF`` variables. In case if ``--verific`` option is provided then ``ADD_INCLUDE_DIR``, ``ADD_LIBRARY_DIR``, ``ADD_BLACKBOX_MODULES``, ``READ_HDL_FILE`` (should be used instead of ``READ_VERILOG_FILE``) and ``READ_LIBRARY`` additional varialbes are supported. The variables can be used as ``${var_name}``. + +.. option:: --ys_rewrite_tmpl + + This option allows the user to provide an alternate Yosys template to rewrite Verilog netlist while running a yosys_vpr flow. The alternate Yosys template script supports all of the main Yosys template script variables. + +.. option:: --verific + + This option specifies to use Verific as a frontend for Yosys while running a yosys_vpr flow. + The following standards are used by default for reading input HDL files: + * Verilog - ``vlog95`` + * System Verilog - ``sv2012`` + * VHDL - ``vhdl2008`` + The option should be used only with custom Yosys template containing Verific commands. .. option:: --debug diff --git a/docs/source/manual/openfpga_flow/run_fpga_task.rst b/docs/source/manual/openfpga_flow/run_fpga_task.rst index 7e14c9d1f..afb2ccdbd 100644 --- a/docs/source/manual/openfpga_flow/run_fpga_task.rst +++ b/docs/source/manual/openfpga_flow/run_fpga_task.rst @@ -94,7 +94,7 @@ Declaring all the above sections are mandatory. General Section ^^^^^^^^^^^^^^^ -.. option:: fpga_flow== +.. option:: fpga_flow= This option defines which OpenFPGA flow to run. By default ``yosys_vpr`` is executed. @@ -118,7 +118,72 @@ General Section .. option:: timeout_each_job= - Specifies the timeout for each :ref:`run_fpga_flow` execution. Default is set to ``20 min. `` + Specifies the timeout for each :ref:`run_fpga_flow` execution. Default is set to ``20 min.`` + +.. option:: verific= + + Specifies to use Verific as a frontend for Yosys while running a yosys_vpr flow. + The following standards are used by default for reading input HDL files: + * Verilog - ``vlog95`` + * System Verilog - ``sv2012`` + * VHDL - ``vhdl2008`` + The option should be used only with custom Yosys template containing Verific commands. + + +OpenFPGA_SHELL Sections +^^^^^^^^^^^^^^^^^^^^^^^ + + User can specify OpenFPGA_SHELL options in this section. + +.. option:: verific_include_dir= + + The ``include_dir`` is path to the Verilog/VHDL include directory. If there are multiple paths then they can be + provided as a comma separated list. + +.. option:: verific_library_dir= + + The ``library_dir`` is path to the Verilog/VHDL library directory. Verific will search in this directory to + find undefined modules. If there are multiple paths then they can be provided as a comma separated list. + +.. option:: verific_verilog_standard=<-vlog95|-vlog2k> + + The option specifies Verilog language standard to be used while reading the Verilog files. + +.. option:: verific_systemverilog_standard=<-sv2005|-sv2009|-sv2012> + + The option specifies SystemVerilog language standard to be used while reading the SystemVerilog files. + +.. option:: verific_vhdl_standard=<-vhdl87|-vhdl93|-vhdl2k|-vhdl2008> + + The option specifies VHDL language standard to be used while reading the VHDL files. + +.. option:: verific_read_lib_name= + + The option specifies library name where Verilog/SystemVerilog/VHDL files specified by ``verific_read_lib_src`` option will be loaded. This option should be used only with ``verific_read_lib_src`` option. + +.. option:: verific_read_lib_src= + + The option specifies Verilog/SystemVerilog/VHDL files to be loaded into library specified by ``verific_read_lib_name`` option. The ``library_src_files`` should be the source files names separated by commas. This option should be used only with ``verific_read_lib_name`` option. + +.. option:: verific_search_lib= + + The option specifies library name from where will look up for external definitions while reading HDL files. + +.. option:: yosys_cell_sim_verilog= + + The option specifies Verilog files which should be separated by comma. + +.. option:: yosys_cell_sim_systemverilog= + + The option specifies SystemVerilog files which should be separated by comma. + +.. option:: yosys_cell_sim_vhdl= + + The option specifies VHDL files which should be separated by comma. + +.. option:: yosys_blackbox_modules= + + The option specifies blackbox modules names which should be separated by comma (usually these are the modules defined in files specified with yosys_cell_sim_ option). Architectures Sections diff --git a/openfpga_flow/scripts/run_fpga_flow.py b/openfpga_flow/scripts/run_fpga_flow.py index 93883d330..08e33b0c7 100644 --- a/openfpga_flow/scripts/run_fpga_flow.py +++ b/openfpga_flow/scripts/run_fpga_flow.py @@ -101,6 +101,8 @@ 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('--verific', action="store_true", + help="Run yosys with verific enabled") parser.add_argument('--disp', action="store_true", help="Open display while running VPR") parser.add_argument('--debug', action="store_true", @@ -465,11 +467,7 @@ def clean_up_and_exit(msg, clean=False): logger.error("Exiting . . . . . .") exit(1) - -def run_yosys_with_abc(): - """ - Execute yosys with ABC and optional blackbox support - """ +def create_yosys_params(): tree = ET.parse(args.arch_file) root = tree.getroot() try: @@ -484,18 +482,105 @@ def run_yosys_with_abc(): args.K = lut_size # Yosys script parameter mapping ys_params = script_env_vars["PATH"] - ys_params["READ_VERILOG_FILE"] = " \n".join([ + + for indx in range(0, len(OpenFPGAArgs), 2): + tmpVar = OpenFPGAArgs[indx][2:].upper() + ys_params[tmpVar] = OpenFPGAArgs[indx+1] + + if not args.verific: + ys_params["READ_VERILOG_FILE"] = " \n".join([ "read_verilog -nolatches " + shlex.quote(eachfile) for eachfile in args.benchmark_files]) + else: + if "ADD_INCLUDE_DIR" not in ys_params: + ys_params["ADD_INCLUDE_DIR"] = "" + if "ADD_LIBRARY_DIR" not in ys_params: + ys_params["ADD_LIBRARY_DIR"] = "" + if "ADD_BLACKBOX_MODULES" not in ys_params: + ys_params["ADD_BLACKBOX_MODULES"] = "" + if "READ_HDL_FILE" not in ys_params: + ys_params["READ_HDL_FILE"] = "" + if "READ_LIBRARY" not in ys_params: + ys_params["READ_LIBRARY"] = "" + if "VERIFIC_VERILOG_STANDARD" not in ys_params: + ys_params["VERIFIC_VERILOG_STANDARD"] = "-vlog2k" + if "VERIFIC_SYSTEMVERILOG_STANDARD" not in ys_params: + ys_params["VERIFIC_SYSTEMVERILOG_STANDARD"] = "-sv" + if "VERIFIC_VHDL_STANDARD" not in ys_params: + ys_params["VERIFIC_VHDL_STANDARD"] = "-vhdl" + ext_to_standard_map = { + ".v" : ys_params["VERIFIC_VERILOG_STANDARD"], + ".vh" : ys_params["VERIFIC_VERILOG_STANDARD"], + ".verilog" : ys_params["VERIFIC_VERILOG_STANDARD"], + ".vlg" : ys_params["VERIFIC_VERILOG_STANDARD"], + ".sv" : ys_params["VERIFIC_SYSTEMVERILOG_STANDARD"], + ".svh" : ys_params["VERIFIC_SYSTEMVERILOG_STANDARD"], + ".vhd" : ys_params["VERIFIC_VHDL_STANDARD"], + ".vhdl" : ys_params["VERIFIC_VHDL_STANDARD"] + } + lib_files = [] + include_dirs = set([os.path.dirname(eachfile) for eachfile in args.benchmark_files]) + if "VERIFIC_INCLUDE_DIR" in ys_params: + include_dirs.update(ys_params["VERIFIC_INCLUDE_DIR"].split(",")) + if include_dirs and not ys_params["ADD_INCLUDE_DIR"]: + ys_params["ADD_INCLUDE_DIR"] = "\n".join(["verific -vlog-incdir " + + shlex.quote(eachdir) for eachdir in include_dirs]) + if "VERIFIC_LIBRARY_DIR" in ys_params: + ys_params["ADD_LIBRARY_DIR"] = "\n".join(["verific -vlog-libdir " + + shlex.quote(eachdir) for eachdir in ys_params["VERIFIC_LIBRARY_DIR"].split(",")]) + try: + if "VERIFIC_READ_LIB_NAME" in ys_params and "VERIFIC_READ_LIB_SRC" in ys_params: + for name in ys_params["VERIFIC_READ_LIB_SRC"].split(","): + for eachfile in args.benchmark_files: + if name in eachfile: + lib_files.append(eachfile) + break + if not lib_files: + clean_up_and_exit("Failed to locate verific library files") + filename, file_extension = os.path.splitext(lib_files[0]) + ys_params["READ_LIBRARY"] = " ".join(["verific -work", + ys_params["VERIFIC_READ_LIB_NAME"], ext_to_standard_map[file_extension]] + + [shlex.quote(eachfile) for eachfile in lib_files]) + for eachfile in args.benchmark_files: + if eachfile in lib_files: + continue + filename, file_extension = os.path.splitext(eachfile) + ys_params["READ_HDL_FILE"] += " ".join(["verific", + "-L " + ys_params["VERIFIC_SEARCH_LIB"] if "VERIFIC_SEARCH_LIB" in ys_params else "", + ext_to_standard_map[file_extension], + shlex.quote(eachfile), "\n"]) + except: + logger.exception("Failed to determine design file type") + clean_up_and_exit("") + if "YOSYS_CELL_SIM_VERILOG" in ys_params: + ys_params["READ_HDL_FILE"] += " ".join(["verific", + ys_params["VERIFIC_VERILOG_STANDARD"], + ys_params["YOSYS_CELL_SIM_VERILOG"], "\n"]) + if "YOSYS_CELL_SIM_SYSTEMVERILOG" in ys_params: + ys_params["READ_HDL_FILE"] += " ".join(["verific", + ys_params["VERIFIC_SYSTEMVERILOG_STANDARD"], + ys_params["YOSYS_CELL_SIM_SYSTEMVERILOG"], "\n"]) + if "YOSYS_CELL_SIM_VHDL" in ys_params: + ys_params["READ_HDL_FILE"] += " ".join(["verific", + ys_params["VERIFIC_VHDL_STANDARD"], + ys_params["YOSYS_CELL_SIM_VHDL"], "\n"]) + if "YOSYS_BLACKBOX_MODULES" in ys_params: + ys_params["ADD_BLACKBOX_MODULES"] = ("blackbox " + + " ".join(["\\" + mod for mod in ys_params["YOSYS_BLACKBOX_MODULES"].split(",")])) + ys_params["TOP_MODULE"] = args.top_module ys_params["LUT_SIZE"] = lut_size ys_params["OUTPUT_BLIF"] = args.top_module+"_yosys_out.blif" ys_params["OUTPUT_VERILOG"] = args.top_module+"_output_verilog.v" - for indx in range(0, len(OpenFPGAArgs), 2): - tmpVar = OpenFPGAArgs[indx][2:].upper() - ys_params[tmpVar] = OpenFPGAArgs[indx+1] - + return ys_params + + +def run_yosys_with_abc(): + """ + Execute yosys with ABC and optional blackbox support + """ + ys_params = create_yosys_params() 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()) @@ -705,19 +790,7 @@ def run_rewrite_verilog(): 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] + ys_rewrite_params = create_yosys_params() # Split a series of scripts by delim ';' # And execute the scripts serially @@ -726,7 +799,7 @@ def run_rewrite_verilog(): 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", + run_command("Run yosys", "yosys_rewrite_output_" + str(iteration_idx) + ".log", [cad_tools["yosys_path"], "yosys_rewrite_" + str(iteration_idx) + ".ys"]) diff --git a/openfpga_flow/scripts/run_fpga_task.py b/openfpga_flow/scripts/run_fpga_task.py index c1ced3ccb..b257526bb 100644 --- a/openfpga_flow/scripts/run_fpga_task.py +++ b/openfpga_flow/scripts/run_fpga_task.py @@ -398,6 +398,9 @@ def create_run_command(curr_job_dir, archfile, benchmark_obj, param, task_conf): if task_gc.get("fpga_flow"): command += ["--fpga_flow", task_gc.get("fpga_flow")] + if task_gc.getboolean("verific"): + command += ["--verific"] + if task_gc.get("run_engine") == "openfpga_shell": for eachKey in task_OFPGAc.keys(): command += [f"--{eachKey}",