Beispiel #1
0
def get_sdc_file(sdc_file, prog):
    """
        takes in the sdc_file and returns a path to that file if it exists.
    """
    if not Path(sdc_file).exists():
        if sdc_file.startswith("/"):
            sdc_file = Path(str(Path(prog).parent.parent) + sdc_file)
        else:
            sdc_file = Path(prog).parent.parent / sdc_file

    return str(vtr.verify_file(sdc_file, "sdc file"))
Beispiel #2
0
def create_circuits_list(main_circuit, include_files):
    """Create a list of all (.v) and (.vh) files"""
    circuit_list = []
    # Check include files exist
    if include_files:
        # Verify that files are Paths or convert them to Paths + check that they exist
        for include in include_files:
            include_file = vtr.verify_file(include, "Circuit")
            circuit_list.append(include_file.name)

    # Append the main circuit design as the last one
    circuit_list.append(main_circuit.name)

    return circuit_list
def create_circuits_list(main_circuit, include_files):
    """Create a list of supported HDL files"""
    circuit_list = []
    # Check include files exist
    if include_files:
        # Verify that files are Paths or convert them to Paths + check that they exist
        for include in include_files:
            file_extension = os.path.splitext(include)[-1]
            # if the include file is not in the supported HDLs, we drop it
            # NOTE: the include file is already copied to the temp folder
            if file_extension not in FILE_TYPES:
                continue

            include_file = vtr.verify_file(include, "Circuit")
            circuit_list.append(include_file.name)

    # Append the main circuit design as the last one
    circuit_list.append(main_circuit.name)

    return circuit_list
Beispiel #4
0
def run(
        circuit_file,
        old_netlist,
        output_netlist,
        output_activity_file,
        command_runner=CommandRunner(),
        temp_dir=Path("."),
        log_filename="ace.out",
        ace_exec=None,
        ace_seed=1,
):
    """
    Runs ACE for activity estimation

    .. note :: Usage: vtr.ace.run(<circuit_file>,<output_netlist>,<output_activity_file>,[OPTIONS])

    Arguments
    =========
        circuit_file :
            Circuit file to optimize

        old_netlist :
            netlist to be anylized

        output_netlist :
            File name to output the resulting circuit to

        output_activity_file :
            The output activity file

    Other Parameters
    ----------------
        command_runner :
            A CommandRunner object used to run system commands

        temp_dir :
            Directory to run in (created if non-existent)

        log_filename :
            File to log result to

        ace_exec :
            ACE executable to be run

        ace_seed :
            The ACE seed
    """
    temp_dir = Path(temp_dir) if not isinstance(temp_dir, Path) else temp_dir
    # Verify that files are Paths or convert them to Paths and check that they exist
    circuit_file = verify_file(circuit_file, "Circuit")
    old_netlist = verify_file(old_netlist, "Previous netlist")
    output_netlist = verify_file(output_netlist,
                                 "Output netlist",
                                 should_exist=False)
    output_activity_file = verify_file(output_activity_file,
                                       "Output activity",
                                       should_exist=False)

    ace_clk_file = temp_dir / "ace_clk.txt"
    ace_raw = temp_dir / (circuit_file.with_suffix("").stem + ".raw.ace.blif")
    if ace_exec is None:
        ace_exec = find_vtr_file("ace")

    cmd = [
        find_vtr_file("extract_clk_from_blif.py"), ace_clk_file.name,
        circuit_file.name
    ]
    command_runner.run_system_command(cmd,
                                      temp_dir=temp_dir,
                                      log_filename="ace_clk_extraction.out",
                                      indent_depth=1)
    ace_clk = ""
    with ace_clk_file.open("r") as file:
        ace_clk = file.readline().strip("\n")
    cmd = [
        ace_exec,
        "-b",
        circuit_file.name,
        "-c",
        ace_clk,
        "-n",
        ace_raw.name,
        "-o",
        output_activity_file.name,
        "-s",
        str(ace_seed),
    ]

    command_runner.run_system_command(cmd,
                                      temp_dir=temp_dir,
                                      log_filename=log_filename,
                                      indent_depth=1)

    clock_script = find_vtr_file("restore_multiclock_latch.pl")

    cmd = [clock_script, old_netlist.name, ace_raw.name, output_netlist.name]
    command_runner.run_system_command(cmd,
                                      temp_dir=temp_dir,
                                      log_filename="ace_clk_restore.out",
                                      indent_depth=1)
Beispiel #5
0
def run(
    architecture_file,
    circuit_file,
    output_netlist,
    command_runner=CommandRunner(),
    temp_dir=Path("."),
    log_filename="abc.out",
    abc_exec=None,
    abc_script=None,
    abc_rc=None,
    use_old_abc_script=False,
    abc_args=None,
    keep_intermediate_files=True,
):
    """
    Runs ABC to optimize specified file.

    .. note :: Usage: vtr.abc.run(<architecture_file>,<circuit_file>,<output_netlist>,[OPTIONS])

    Arguments
    =========
        architecture_file :
            Architecture file to target

        circuit_file :
            Circuit file to optimize

        output_netlist :
            File name to output the resulting circuit to

    Other Parameters
    ----------------
        command_runner :
            A CommandRunner object used to run system commands

        temp_dir :
            Directory to run in (created if non-existent)

        log_filename :
            File to log result to

        abc_exec :
            ABC executable to be run

        abc_script :
            The script to be run on abc

        abc_rc :
            The ABC rc file

        use_old_abc_script :
            Enables the use of the old ABC script

        abc_args :
            A dictionary of keyword arguments to pass on to ABC

        keep_intermediate_files :
            Determines if intermediate files are kept or deleted

    """
    temp_dir = Path(temp_dir) if not isinstance(temp_dir, Path) else temp_dir
    temp_dir.mkdir(parents=True, exist_ok=True)

    abc_args = OrderedDict() if abc_args is None else abc_args

    # Verify that files are Paths or convert them to Paths and check that they exist
    architecture_file = verify_file(architecture_file, "Architecture")
    circuit_file = verify_file(circuit_file, "Circuit")
    output_netlist = verify_file(output_netlist,
                                 "Output netlist",
                                 should_exist=False)

    blackbox_latches_script = str(paths.blackbox_latches_script_path)
    clk_list = []
    #
    # Parse arguments
    #
    (
        abc_args,
        abc_flow_type,
        lut_size,
        abc_run_args,
        use_old_latches_restoration_script,
    ) = parse_abc_args(abc_args)

    lut_size = determine_lut_size(
        str(architecture_file)) if lut_size is None else lut_size

    populate_clock_list(circuit_file, blackbox_latches_script, clk_list,
                        command_runner, temp_dir)

    abc_exec = str(paths.abc_exe_path) if abc_exec is None else abc_exec
    abc_rc = str(paths.abc_rc_path) if abc_rc is None else abc_rc

    shutil.copyfile(str(abc_rc), str(temp_dir / "abc.rc"))

    iterations = len(clk_list)
    iterations = 1 if iterations == 0 or abc_flow_type != "iterative_bb" else iterations

    original_script = abc_script
    input_file = circuit_file.name
    for i in range(0, iterations):
        pre_abc_blif = temp_dir / (str(i) + "_" + circuit_file.name)
        post_abc_blif = temp_dir / (str(i) + "_" + output_netlist.name)
        post_abc_raw_blif = temp_dir / (str(i) + "_" +
                                        output_netlist.with_suffix("").stem +
                                        ".raw.abc.blif")
        if abc_flow_type == "blanket_bb":
            command_runner.run_system_command(
                [
                    blackbox_latches_script,
                    "--input",
                    input_file,
                    "--output",
                    pre_abc_blif.name,
                ],
                temp_dir=temp_dir,
                log_filename=str(i) + "_blackboxing_latch.out",
                indent_depth=1,
            )

        elif len(clk_list) > i:
            command_runner.run_system_command(
                [
                    blackbox_latches_script,
                    "--clk_list",
                    clk_list[i],
                    "--input",
                    input_file,
                    "--output",
                    pre_abc_blif.name,
                ],
                temp_dir=temp_dir,
                log_filename=str(i) + "_blackboxing_latch.out",
                indent_depth=1,
            )
        else:
            pre_abc_blif = input_file

        abc_script = ("; ".join([
            'echo ""',
            'echo "Load Netlist"',
            'echo "============"',
            "read {pre_abc_blif}".format(pre_abc_blif=pre_abc_blif.name),
            "time",
            'echo ""',
            'echo "Circuit Info"',
            'echo "=========="',
            "print_stats",
            "print_latch",
            "time",
            'echo ""',
            'echo "LUT Costs"',
            'echo "========="',
            "print_lut",
            "time",
            'echo ""',
            'echo "Logic Opt + Techmap"',
            'echo "==================="',
            "strash",
            "ifraig -v",
            "scorr -v",
            "dc2 -v",
            "dch -f",
            "if -K {lut_size} -v".format(lut_size=lut_size),
            "mfs2 -v",
            "print_stats",
            "time",
            'echo ""',
            'echo "Output Netlist"',
            'echo "=============="',
            "write_hie {pre_abc_blif} {post_abc_raw_blif}".format(
                pre_abc_blif=pre_abc_blif.name,
                post_abc_raw_blif=post_abc_raw_blif.name,
            ),
            "time;",
        ]) if abc_script is None else "; ".join([
            "read {pre_abc_blif}".format(pre_abc_blif=pre_abc_blif.name),
            "time",
            "resyn",
            "resyn2",
            "if -K {lut_size}".format(lut_size=lut_size),
            "time",
            "scleanup",
            "write_hie {pre_abc_blif} {post_abc_raw_blif}".format(
                pre_abc_blif=pre_abc_blif.name,
                post_abc_raw_blif=post_abc_raw_blif.name,
            ),
            "print_stats",
        ]) if use_old_abc_script else abc_script)

        cmd = [abc_exec, "-c", abc_script]
        if abc_run_args:
            cmd.append(abc_run_args)

        command_runner.run_system_command(
            cmd,
            temp_dir=temp_dir,
            log_filename=Path(log_filename).stem + str(i) +
            Path(log_filename).suffix,
            indent_depth=1,
        )

        if abc_flow_type != "blanket_bb" and len(clk_list) > i:
            command_runner.run_system_command(
                [
                    blackbox_latches_script,
                    "--restore",
                    clk_list[i],
                    "--input",
                    post_abc_raw_blif.name,
                    "--output",
                    post_abc_blif.name,
                ],
                temp_dir=temp_dir,
                log_filename="restore_latch" + str(i) + ".out",
                indent_depth=1,
            )
        else:
            restore_multiclock_info_script = (
                str(paths.restore_multiclock_latch_old_script_path)
                if use_old_latches_restoration_script else str(
                    paths.restore_multiclock_latch_script_path))
            command_runner.run_system_command(
                [
                    restore_multiclock_info_script,
                    pre_abc_blif.name,
                    post_abc_raw_blif.name,
                    post_abc_blif.name,
                ],
                temp_dir=temp_dir,
                log_filename="restore_latch" + str(i) + ".out",
                indent_depth=1,
            )
        if abc_flow_type != "iterative_bb":
            break

        abc_script = original_script
        input_file = post_abc_blif.name

    command_runner.run_system_command(
        [
            blackbox_latches_script,
            "--input",
            post_abc_blif.name,
            "--output",
            output_netlist.name,
            "--vanilla",
        ],
        temp_dir=temp_dir,
        log_filename="restore_latch" + str(i) + ".out",
        indent_depth=1,
    )
    if not keep_intermediate_files:
        for file in temp_dir.iterdir():
            if file.suffix in (".dot", ".v", ".rc"):
                file.unlink()
Beispiel #6
0
def run(
    architecture_file,
    circuit_file,
    include_files,
    output_netlist,
    command_runner=vtr.CommandRunner(),
    temp_dir=Path("."),
    odin_args="--adder_type default",
    log_filename="odin.out",
    odin_exec=None,
    odin_config=None,
    min_hard_mult_size=3,
    min_hard_adder_size=1,
):
    """
    Runs ODIN II on the specified architecture file and circuit file

    .. note :: Usage: vtr.odin.run(<architecture_file>,<circuit_file>,<output_netlist>,[OPTIONS])

    Arguments
    =========
        architecture_file :
            Architecture file to target

        circuit_file :
            Circuit file to optimize

        output_netlist :
            File name to output the resulting circuit to

    Other Parameters
    ----------------
        command_runner :
            A CommandRunner object used to run system commands

        temp_dir :
            Directory to run in (created if non-existent)

        odin_args:
            A dictionary of keyword arguments to pass on to ODIN II

        log_filename :
            File to log result to

        odin_exec:
            ODIN II executable to be run

        odin_config:
            The ODIN II configuration file

        min_hard_mult_size :
            Tells ODIN II the minimum multiplier size that should be implemented using
            hard multiplier (if available)

        min_hard_adder_size :
            Tells ODIN II the minimum adder size that should be implemented
            using hard adder (if available).

    """
    temp_dir = Path(temp_dir) if not isinstance(temp_dir, Path) else temp_dir
    temp_dir.mkdir(parents=True, exist_ok=True)

    if odin_args is None:
        odin_args = OrderedDict()

    # Verify that files are Paths or convert them to Paths and check that they exist
    architecture_file = vtr.verify_file(architecture_file, "Architecture")
    circuit_file = vtr.verify_file(circuit_file, "Circuit")
    output_netlist = vtr.verify_file(output_netlist, "Output netlist", False)

    if odin_exec is None:
        odin_exec = str(vtr.paths.odin_exe_path)

    if odin_config is None:
        odin_base_config = str(vtr.paths.odin_cfg_path)
    else:
        odin_base_config = str(Path(odin_config).resolve())

    # Copy the config file
    odin_config = "odin_config.xml"
    odin_config_full_path = str(temp_dir / odin_config)
    shutil.copyfile(odin_base_config, odin_config_full_path)

    # Create a list showing all (.v) and (.vh) files
    circuit_list = create_circuits_list(circuit_file, include_files)

    init_config_file(
        odin_config_full_path,
        circuit_list,
        architecture_file.name,
        output_netlist.name,
        vtr.determine_memory_addr_width(str(architecture_file)),
        min_hard_mult_size,
        min_hard_adder_size,
    )

    cmd = [odin_exec]
    use_odin_simulation = False

    if "use_odin_simulation" in odin_args:
        use_odin_simulation = True
        del odin_args["use_odin_simulation"]

    for arg, value in odin_args.items():
        if isinstance(value, bool) and value:
            cmd += ["--" + arg]
        elif isinstance(value, (str, int, float)):
            cmd += ["--" + arg, str(value)]
        else:
            pass

    cmd += ["-U0"]

    if "disable_odin_xml" in odin_args:
        del odin_args["disable_odin_xml"]
        cmd += [
            "-a",
            architecture_file.name,
            "-V",
            circuit_list,
            "-o",
            output_netlist.name,
        ]
    else:
        cmd += ["-c", odin_config]

    command_runner.run_system_command(cmd,
                                      temp_dir=temp_dir,
                                      log_filename=log_filename,
                                      indent_depth=1)

    if use_odin_simulation:
        sim_dir = temp_dir / "simulation_init"
        sim_dir.mkdir()
        cmd = [
            odin_exec,
            "-b",
            output_netlist.name,
            "-a",
            architecture_file.name,
            "-sim_dir",
            str(sim_dir),
            "-g",
            "100",
            "--best_coverage",
            "-U0",
        ]
        command_runner.run_system_command(
            cmd,
            temp_dir=temp_dir,
            log_filename="sim_produce_vector.out",
            indent_depth=1,
        )
Beispiel #7
0
def cmp_full_vs_incr_sta(
                architecture,
                circuit,
                circuit_name=None,
                command_runner=CommandRunner(),
                vpr_args=None,
                temp_dir=Path("."),
                vpr_exec=None,
):
    """
    Sanity check that full STA and the incremental STA produce the same *.net, *.place, *.route
    files as well as identical timing report files

    .. note :: Use: vtr.vpr.cmp_full_vs_incr_sta(<architecture>,<circuit_name>,<circuit>,[OPTIONS])

    Arguments
    =========
        architecture:
            Architecture file

        circuit:
            Input circuit file

    Other Parameters
    ----------------
        circuit_name:
            Name of the circuit file

        command_runner:
            CommandRunner object

        temp_dir:
            Directory to run in

        vpr_exec:
            Path to the VPR executable

        vpr_args:
            Extra arguments for VPR
    """

    # Verify that files are Paths or convert them to Paths and check that they exist
    architecture = verify_file(architecture, "Architecture")
    circuit = verify_file(circuit, "Circuit")
    if not circuit_name:
        circuit_name = circuit.stem
    default_output_filenames = [
        "{}.net".format(circuit_name),
        "{}.place".format(circuit_name),
        "{}.route".format(circuit_name),
        "report_timing.setup.rpt",
        "report_timing.hold.rpt",
        "report_unconstrained_timing.setup.rpt",
        "report_unconstrained_timing.hold.rpt",
    ]

    # The full STA flow should have already been run
    # directly rename the output files
    for filename in default_output_filenames:
        cmd = ["mv", filename, "full_sta_{}".format(filename)]
        command_runner.run_system_command(
            cmd, temp_dir=temp_dir, log_filename="move.out", indent_depth=1
        )

    # run incremental STA flow
    incremental_vpr_args = vpr_args
    incremental_vpr_args["timing_update_type"] = "incremental"

    run(
        architecture,
        circuit,
        circuit_name,
        command_runner,
        temp_dir,
        log_filename="vpr.incr_sta.out",
        vpr_exec=vpr_exec,
        vpr_args=incremental_vpr_args,
    )

    # Rename the incremental STA output files
    for filename in default_output_filenames:
        cmd = ["mv", filename, "incremental_sta_{}".format(filename)]
        command_runner.run_system_command(
            cmd, temp_dir=temp_dir, log_filename="move.out", indent_depth=1
        )

    failed_msg = "Failed with these files (not identical):"
    identical = True

    for filename in default_output_filenames:
        cmd = [
            "diff",
            "full_sta_{}".format(filename),
            "incremental_sta_{}".format(filename),
        ]
        _, cmd_return_code = command_runner.run_system_command(
            cmd, temp_dir=temp_dir, log_filename="diff.out", indent_depth=1
        )
        if cmd_return_code:
            identical = False
            failed_msg += " {}".format(filename)

    if not identical:
        raise InspectError(failed_msg)
Beispiel #8
0
def run_relax_w(
        architecture,
        circuit,
        circuit_name=None,
        command_runner=CommandRunner(),
        temp_dir=Path("."),
        relax_w_factor=1.3,
        vpr_exec=None,
        logfile_base="vpr",
        vpr_args=None,
):
    """
    Runs VPR twice:

      1st: To find the minimum channel width

      2nd: At relaxed channel width (e.g. for critical path delay)

    .. note :: Use: vtr.vpr.run_relax_w(<architecture_file>,<circuit_file>,[OPTIONS])

    Arguments
    =========
        architecture:
            Architecture file

        circuit:
            Input circuit netlist

    Other Parameters
    ----------------
        circuit_name:
            Name of the circuit file

        command_runner:
            CommandRunner object

        temp_dir:
            Directory to run in

        relax_w_factor:
            Factor by which to relax minimum channel width for critical path delay routing

        vpr_exec:
            Path to the VPR executable

        logfile_base:
            Base name for log files (e.g. "vpr" produces vpr.min_w.out, vpr.relaxed_w.out)

        vpr_args:
            Extra arguments for VPR
    """
    if vpr_args is None:
        vpr_args = OrderedDict()
    temp_dir = Path(temp_dir) if not isinstance(temp_dir, Path) else temp_dir
    temp_dir.mkdir(parents=True, exist_ok=True)

    # Verify that files are Paths or convert them to Paths and check that they exist
    architecture = verify_file(architecture, "Architecture")
    circuit = verify_file(circuit, "Circuit")

    vpr_min_w_log = ".".join([logfile_base, "out"])
    vpr_relaxed_w_log = ".".join([logfile_base, "crit_path", "out"])
    max_router_iterations = None

    if "max_router_iterations" in vpr_args:
        max_router_iterations = vpr_args["max_router_iterations"]
        del vpr_args["max_router_iterations"]

    if "write_rr_graph" in vpr_args:
        del vpr_args["write_rr_graph"]

    if "analysis" in vpr_args:
        del vpr_args["analysis"]

    if "route" in vpr_args:
        del vpr_args["route"]

    if vpr_exec is None:
        vpr_exec = find_vtr_file("vpr", is_executable=True)

    run(
        architecture,
        circuit,
        circuit_name,
        command_runner,
        temp_dir,
        log_filename=vpr_min_w_log,
        vpr_exec=vpr_exec,
        vpr_args=vpr_args,
    )

    if ("pack" in vpr_args or "place" in vpr_args) and "route" not in vpr_args:
        # Don't look for min W if routing was not run
        return
    if max_router_iterations:
        vpr_args["max_router_iterations"] = max_router_iterations
    min_w = determine_min_w(str(temp_dir / vpr_min_w_log))

    relaxed_w = relax_w(min_w, relax_w_factor)

    vpr_args["route"] = True  # Re-route only
    vpr_args["route_chan_width"] = relaxed_w  # At a fixed channel width

    # VPR does not support performing routing when fixed pins
    # are specified, and placement is not run; so remove the option

    run(
        architecture,
        circuit,
        circuit_name,
        command_runner,
        temp_dir,
        log_filename=vpr_relaxed_w_log,
        vpr_exec=vpr_exec,
        vpr_args=vpr_args,
    )
Beispiel #9
0
def run(
        architecture,
        circuit,
        circuit_name=None,
        command_runner=CommandRunner(),
        temp_dir=Path("."),
        log_filename="vpr.out",
        vpr_exec=None,
        vpr_args=None,
):
    """
    Runs VPR with the specified configuration

    .. note :: Usage: vtr.vpr.run(<architecture>,<circuit>,[OPTIONS])

    Arguments
    =========
        architecture:
            Architecture file

        circuit:
            Input circuit file

    Other Parameters
    ----------------
        circuit_name:
            Name of the circuit file

        command_runner:
            CommandRunner object

        temp_dir:
            Directory to run in

        log_filename :
            File to log result to

        vpr_exec:
            Path to the VPR executable

        vpr_args:
            Extra arguments for VPR


    """

    if vpr_args is None:
        vpr_args = OrderedDict()
    temp_dir = Path(temp_dir) if not isinstance(temp_dir, Path) else temp_dir
    temp_dir.mkdir(parents=True, exist_ok=True)

    if vpr_exec is None:
        vpr_exec = find_vtr_file("vpr", is_executable=True)

    # Verify that files are Paths or convert them to Paths and check that they exist
    architecture = verify_file(architecture, "Architecture")
    circuit = verify_file(circuit, "Circuit")
    cmd = []
    if circuit_name:
        cmd = [
            vpr_exec,
            architecture.name,
            circuit_name,
            "--circuit_file",
            circuit.name,
        ]
    else:
        cmd = [vpr_exec, architecture.name, circuit.name]

    # Translate arbitrary keyword arguments into options for VPR

    for arg, value in vpr_args.items():
        if isinstance(value, bool):
            if not value:
                pass
            cmd += ["--" + arg]
        else:
            if isinstance(value, list):
                cmd += ["--" + arg]
                for item in value:
                    cmd += [str(item)]
            else:
                cmd += ["--" + arg, str(value)]

    command_runner.run_system_command(
        cmd, temp_dir=temp_dir, log_filename=log_filename, indent_depth=1
    )
Beispiel #10
0
def run(
    architecture,
    circuit,
    circuit_name=None,
    command_runner=CommandRunner(),
    temp_dir=Path("."),
    log_filename="vpr.out",
    vpr_exec=None,
    vpr_args=None,
):
    """
    Runs VPR with the specified configuration

    .. note :: Usage: vtr.vpr.run(<architecture>,<circuit>,[OPTIONS])

    Arguments
    =========
        architecture:
            Architecture file

        circuit:
            Input circuit file

    Other Parameters
    ----------------
        circuit_name:
            Name of the circuit file

        command_runner:
            CommandRunner object

        temp_dir:
            Directory to run in

        log_filename :
            File to log result to

        vpr_exec:
            Path to the VPR executable

        vpr_args:
            Extra arguments for VPR


    """

    if vpr_args is None:
        vpr_args = OrderedDict()
    temp_dir = Path(temp_dir) if not isinstance(temp_dir, Path) else temp_dir
    temp_dir.mkdir(parents=True, exist_ok=True)

    if vpr_exec is None:
        vpr_exec = find_vtr_file("vpr", is_executable=True)

    # Verify that files are Paths or convert them to Paths and check that they exist
    architecture = verify_file(architecture, "Architecture")
    circuit = verify_file(circuit, "Circuit")
    cmd = []
    if circuit_name:
        cmd = [
            vpr_exec,
            architecture.name,
            circuit_name,
            "--circuit_file",
            circuit.name,
        ]
    else:
        cmd = [vpr_exec, architecture.name, circuit.name]

    # Translate arbitrary keyword arguments into options for VPR

    for arg, value in vpr_args.items():
        if isinstance(value, bool):
            if not value:
                pass
            cmd += ["--" + arg]
        else:
            if isinstance(value, list):
                cmd += ["--" + arg]
                for item in value:
                    cmd += [str(item)]
            else:
                cmd += ["--" + arg, str(value)]

    # Extra options to fine-tune LeakSanitizer (LSAN) behaviour.
    # Note that if VPR was compiled without LSAN these have no effect
    # 'suppressions=...' Add the LeakSanitizer (LSAN) suppression file
    # 'exitcode=12' Use a consistent exitcode
    # (on some systems LSAN don't use the default exit code of 23)
    # 'fast_unwind_on_malloc=0' Provide more accurate leak stack traces

    environ[
        "LSAN_OPTIONS"] = "suppressions={} exitcode=23 fast_unwind_on_malloc=0".format(
            find_vtr_file("lsan.supp"))

    command_runner.run_system_command(cmd,
                                      temp_dir=temp_dir,
                                      log_filename=log_filename,
                                      indent_depth=1)
Beispiel #11
0
def run(
    architecture_file,
    circuit_file,
    include_files,
    output_netlist,
    command_runner=vtr.CommandRunner(),
    temp_dir=Path("."),
    yosys_args="",
    log_filename="yosys.out",
    yosys_exec=None,
    yosys_script=None,
    min_hard_mult_size=3,
    min_hard_adder_size=1,
):
    """
    Runs YOSYS on the specified architecture file and circuit file

    .. note :: Usage: vtr.yosys.run(<architecture_file>,<circuit_file>,<output_netlist>,[OPTIONS])

    Arguments
    =========
        architecture_file :
            Architecture file to target

        circuit_file :
            Circuit file to optimize

        output_netlist :
            File name to output the resulting circuit to

    Other Parameters
    ----------------
        command_runner :
            A CommandRunner object used to run system commands

        temp_dir :
            Directory to run in (created if non-existent)

        yosys_args:
            A dictionary of keyword arguments to pass on to YOSYS

        log_filename :
            File to log result to

        yosys_exec:
            YOSYS executable to be run

        yosys_script:
            The YOSYS script file

    """
    temp_dir = Path(temp_dir) if not isinstance(temp_dir, Path) else temp_dir
    temp_dir.mkdir(parents=True, exist_ok=True)

    if yosys_args is None:
        yosys_args = OrderedDict()

    # Verify that files are Paths or convert them to Paths and check that they exist
    architecture_file = vtr.verify_file(architecture_file, "Architecture")
    circuit_file = vtr.verify_file(circuit_file, "Circuit")
    output_netlist = vtr.verify_file(output_netlist, "Output netlist", False)

    if yosys_exec is None:
        yosys_exec = str(vtr.paths.yosys_exe_path)

    if yosys_script is None:
        yosys_base_script = str(vtr.paths.yosys_script_path)
    else:
        yosys_base_script = str(Path(yosys_script).resolve())

    # Copy the script file
    yosys_script = "synthesis.ys"
    yosys_script_full_path = str(temp_dir / yosys_script)
    shutil.copyfile(yosys_base_script, yosys_script_full_path)

    # Copy the yosys models file
    yosys_models = YOSYS_LIB_FILES["YSMDL"]
    yosys_base_models = str(vtr.paths.yosys_lib_path /
                            YOSYS_LIB_FILES["YSMDL"])
    yosys_models_full_path = str(temp_dir / yosys_models)
    shutil.copyfile(yosys_base_models, yosys_models_full_path)

    # Copy the VTR memory blocks file
    yosys_spram = YOSYS_LIB_FILES["SPRAM"]
    yosys_dpram = YOSYS_LIB_FILES["DPRAM"]
    yosys_spram_rename = YOSYS_LIB_FILES["SPRAMR"]
    yosys_dpram_rename = YOSYS_LIB_FILES["DPRAMR"]
    yosys_base_spram = str(vtr.paths.yosys_lib_path / YOSYS_LIB_FILES["SPRAM"])
    yosys_base_dpram = str(vtr.paths.yosys_lib_path / YOSYS_LIB_FILES["DPRAM"])
    yosys_base_spram_rename = str(vtr.paths.yosys_lib_path /
                                  YOSYS_LIB_FILES["SPRAMR"])
    yosys_base_dpram_rename = str(vtr.paths.yosys_lib_path /
                                  YOSYS_LIB_FILES["DPRAMR"])
    yosys_spram_full_path = str(temp_dir / yosys_spram)
    yosys_dpram_full_path = str(temp_dir / yosys_dpram)
    yosys_spram_rename_full_path = str(temp_dir / yosys_spram_rename)
    yosys_dpram_rename_full_path = str(temp_dir / yosys_dpram_rename)
    shutil.copyfile(yosys_base_spram, yosys_spram_full_path)
    shutil.copyfile(yosys_base_dpram, yosys_dpram_full_path)
    shutil.copyfile(yosys_base_spram_rename, yosys_spram_rename_full_path)
    shutil.copyfile(yosys_base_dpram_rename, yosys_dpram_rename_full_path)

    # Create a list showing all (.v) and (.vh) files
    circuit_list = create_circuits_list(circuit_file, include_files)

    init_script_file(
        yosys_script_full_path,
        yosys_models_full_path,
        yosys_spram_full_path,
        yosys_dpram_full_path,
        yosys_spram_rename_full_path,
        yosys_dpram_rename_full_path,
        circuit_list,
        output_netlist.name,
        vtr.determine_memory_addr_width(str(architecture_file)),
        min_hard_mult_size,
        min_hard_adder_size,
    )

    cmd = [yosys_exec]

    for arg, value in yosys_args.items():
        if isinstance(value, bool) and value:
            cmd += ["--" + arg]
        elif isinstance(value, (str, int, float)):
            cmd += ["--" + arg, str(value)]
        else:
            pass

    cmd += ["-s", yosys_script]

    command_runner.run_system_command(cmd,
                                      temp_dir=temp_dir,
                                      log_filename=log_filename,
                                      indent_depth=1)