예제 #1
0
def 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,
    memory_addr_width,
    min_hard_mult_size,
    min_hard_adder_size,
):
    """initializing the raw yosys script file"""
    # specify the input files type
    for circuit in circuit_list:
        file_extension = os.path.splitext(circuit)[-1]
        if file_extension not in FILE_TYPES:
            raise vtr.VtrError(
                "Inavlid input file type '{}'".format(file_extension))

    # Update the config file
    vtr.file_replace(
        yosys_script_full_path,
        {
            "XXX": circuit_list[0],
            "YYY": "./" + YOSYS_LIB_FILES["YSMDL"],
            "SSS": "./" + YOSYS_LIB_FILES["SPRAM"],
            "DDD": "./" + YOSYS_LIB_FILES["DPRAM"],
            "SSR": "./" + YOSYS_LIB_FILES["SPRAMR"],
            "DDR": "./" + YOSYS_LIB_FILES["DPRAMR"],
            "TTT": str(vtr.paths.yosys_lib_path),
            "ZZZ": output_netlist,
        },
    )

    # Update the config file
    vtr.file_replace(
        yosys_models_full_path,
        {
            "PPP": memory_addr_width,
            "MMM": min_hard_mult_size,
            "AAA": min_hard_adder_size
        },
    )

    # Update the config file files
    vtr.file_replace(yosys_spram_full_path, {"PPP": memory_addr_width})
    vtr.file_replace(yosys_dpram_full_path, {"PPP": memory_addr_width})
    vtr.file_replace(yosys_spram_rename_full_path, {"PPP": memory_addr_width})
    vtr.file_replace(yosys_dpram_rename_full_path, {"PPP": memory_addr_width})
예제 #2
0
def process_unknown_args(unknown_args):
    """
    We convert the unknown_args into a dictionary, which is eventually
    used to generate arguments for VPR
    """
    vpr_args = OrderedDict()
    while len(unknown_args) > 0:
        # Get the first argument
        arg = unknown_args.pop(0)

        if arg == "":
            continue

        if not arg.startswith("-"):
            raise vtr.VtrError(
                "Extra argument '{}' intended for VPR does not start with '-'".
                format(arg))

        # To make it a valid kwargs dictionary we trim the initial '-' or '--' from the
        # argument name
        assert len(arg) >= 2
        if arg[1] == "-":
            # Double-dash prefix
            arg = arg[2:]
        else:
            # Single-dash prefix
            arg = arg[1:]

        # Determine if there is a value associated with this argument
        if len(unknown_args) == 0 or (unknown_args[0].startswith("-")
                                      and arg != "target_ext_pin_util"):
            # Single value argument, we place these with value 'True'
            # in vpr_args
            vpr_args[arg] = True
        else:
            # Multivalue argument
            val = unknown_args.pop(0)
            if len(unknown_args) != 0 and not unknown_args[0].startswith("-"):
                temp = val
                val = []
                val.append(temp)
            while len(unknown_args) != 0 and not unknown_args[0].startswith(
                    "-"):
                val.append(unknown_args.pop(0))
            vpr_args[arg] = val

    return vpr_args
예제 #3
0
def init_config_file(
    odin_config_full_path,
    circuit_list,
    architecture_file,
    output_netlist,
    memory_addr_width,
    min_hard_mult_size,
    min_hard_adder_size,
):
    """initializing the raw odin config file"""
    # specify the input files type
    file_extension = os.path.splitext(circuit_list[0])[-1]
    if file_extension not in FILE_TYPES:
        raise vtr.VtrError(
            "Inavlid input file type '{}'".format(file_extension))
    input_file_type = FILE_TYPES[file_extension]

    # Update the config file
    vtr.file_replace(
        odin_config_full_path,
        {
            "YYY": architecture_file,
            "TTT": input_file_type,
            "ZZZ": output_netlist,
            "PPP": memory_addr_width,
            "MMM": min_hard_mult_size,
            "AAA": min_hard_adder_size,
        },
    )

    # loading the given config file
    config_file = ET.parse(odin_config_full_path)
    root = config_file.getroot()

    # based on the base config file
    verilog_files_tag = root.find("inputs")
    # remove the template line XXX, verilog_files_tag [1] is a comment
    verilog_files_tag.remove(verilog_files_tag[1])
    for circuit in circuit_list:
        verilog_file = ET.SubElement(verilog_files_tag, "input_path_and_name")
        verilog_file.tail = "\n\n\t" if (circuit
                                         == circuit_list[-1]) else "\n\n\t\t"
        verilog_file.text = circuit

    # update the config file with new values
    config_file.write(odin_config_full_path)
def run(
    architecture_file,
    circuit_file,
    power_tech_file=None,
    start_stage=VtrStage.odin,
    end_stage=VtrStage.vpr,
    command_runner=vtr.CommandRunner(),
    temp_dir=Path("./temp"),
    odin_args=None,
    abc_args=None,
    vpr_args=None,
    keep_intermediate_files=True,
    keep_result_files=True,
    odin_config=None,
    min_hard_mult_size=3,
    min_hard_adder_size=1,
    check_equivalent=False,
    check_incremental_sta_consistency=False,
    use_old_abc_script=False,
    relax_w_factor=1.3,
    check_route=False,
    check_place=False,
):
    """
    Runs the VTR CAD flow to map the specified circuit_file onto the target architecture_file

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

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

        circuit_file     :
            Circuit to implement

    Other Parameters
    ----------------
        power_tech_file  :
            Technology power file.  Enables power analysis and runs ace

        start_stage      :
            Stage of the flow to start at

        end_stage        :
            Stage of the flow to finish at

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

        command_runner   :
            A CommandRunner object used to run system commands

        verbosity        :
            whether to output error description or not

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

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

        vpr_args         :
            A dictionary of keyword arguments to pass on to VPR

        keep_intermediate_files :
            Determines if intermediate files are kept or deleted

        keep_result_files :
            Determines if the result files are kept or deleted

        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).

        check_equivalent  :
            Enables Logical Equivalence Checks

        use_old_abc_script :
            Enables the use of the old ABC script

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

        check_incremental_sta_consistency :
            Do a second-run of the incremental analysis to compare the result files

        check_route:
            Check first placement and routing by enabling VPR analysis

        check_place:
            Route existing placement by enabling VPR routing.
    """

    #
    # Initial setup
    #
    vpr_args = OrderedDict() if not vpr_args else vpr_args
    odin_args = OrderedDict() if not odin_args else odin_args
    abc_args = OrderedDict() if not abc_args else abc_args

    # Verify that files are Paths or convert them to Paths and check that they exist
    architecture_file = vtr.util.verify_file(architecture_file, "Architecture")
    circuit_file = vtr.util.verify_file(circuit_file, "Circuit")
    if architecture_file.suffix != ".xml":
        raise vtr.VtrError(
            "Expected Architecture file as second argument (was {})".format(
                architecture_file.name))
    power_tech_file = vtr.util.verify_file(
        power_tech_file, "Power") if power_tech_file else None
    temp_dir = Path(temp_dir)
    temp_dir.mkdir(parents=True, exist_ok=True)
    netlist_ext = ".blif" if ".eblif" not in circuit_file.suffixes else ".eblif"

    # Define useful filenames
    post_odin_netlist = temp_dir / (circuit_file.stem + ".odin" + netlist_ext)
    post_abc_netlist = temp_dir / (circuit_file.stem + ".abc" + netlist_ext)
    post_ace_netlist = temp_dir / (circuit_file.stem + ".ace" + netlist_ext)
    post_ace_activity_file = temp_dir / (circuit_file.stem + ".act")
    pre_vpr_netlist = temp_dir / (circuit_file.stem + ".pre-vpr" + netlist_ext)

    # If the user provided a .blif or .eblif netlist, we use that as the baseline for LEC
    # (ABC can't LEC behavioural verilog)
    lec_base_netlist = circuit_file.name if "blif" in circuit_file.suffixes else None
    # Reference netlist for LEC

    gen_postsynthesis_netlist = temp_dir / (circuit_file.stem +
                                            "_post_synthesis" + netlist_ext)

    # Copy the circuit and architecture
    circuit_copy = temp_dir / circuit_file.name
    architecture_copy = temp_dir / architecture_file.name
    shutil.copy(str(circuit_file), str(circuit_copy))
    shutil.copy(str(architecture_file), str(architecture_copy))

    # There are multiple potential paths for the netlist to reach a tool
    # We initialize it here to the user specified circuit and let downstream
    # stages update it
    next_stage_netlist = circuit_copy

    #
    # RTL Elaboration & Synthesis
    #
    if should_run_stage(VtrStage.odin, start_stage,
                        end_stage) and circuit_file.suffixes != ".blif":
        vtr.odin.run(
            architecture_copy,
            next_stage_netlist,
            output_netlist=post_odin_netlist,
            command_runner=command_runner,
            temp_dir=temp_dir,
            odin_args=odin_args,
            odin_config=odin_config,
            min_hard_mult_size=min_hard_mult_size,
            min_hard_adder_size=min_hard_adder_size,
        )

        next_stage_netlist = post_odin_netlist

        lec_base_netlist = post_odin_netlist if not lec_base_netlist else lec_base_netlist

    #
    # Logic Optimization & Technology Mapping
    #
    if should_run_stage(VtrStage.abc, start_stage, end_stage):
        vtr.abc.run(
            architecture_copy,
            next_stage_netlist,
            output_netlist=post_abc_netlist,
            command_runner=command_runner,
            temp_dir=temp_dir,
            abc_args=abc_args,
            keep_intermediate_files=keep_intermediate_files,
            use_old_abc_script=use_old_abc_script,
        )

        next_stage_netlist = post_abc_netlist
        lec_base_netlist = post_abc_netlist if not lec_base_netlist else lec_base_netlist

    #
    # Power Activity Estimation
    #
    if power_tech_file:
        # The user provided a tech file, so do power analysis

        if should_run_stage(VtrStage.ace, start_stage, end_stage):
            vtr.ace.run(
                next_stage_netlist,
                old_netlist=post_odin_netlist,
                output_netlist=post_ace_netlist,
                output_activity_file=post_ace_activity_file,
                command_runner=command_runner,
                temp_dir=temp_dir,
            )

        if not keep_intermediate_files:
            next_stage_netlist.unlink()
            post_odin_netlist.unlink()

        # Use ACE's output netlist
        next_stage_netlist = post_ace_netlist
        lec_base_netlist = post_ace_netlist if not lec_base_netlist else lec_base_netlist

        # Enable power analysis in VPR
        vpr_args["power"] = True
        vpr_args["tech_properties"] = str(power_tech_file.resolve())

    #
    # Pack/Place/Route
    #
    if should_run_stage(VtrStage.vpr, start_stage, end_stage):
        # Copy the input netlist for input to vpr
        shutil.copyfile(str(next_stage_netlist), str(pre_vpr_netlist))
        route_fixed_w = "route_chan_width" in vpr_args
        if (check_route or check_place) and not route_fixed_w:
            vpr_args["route_chan_width"] = 300
            route_fixed_w = True

        if route_fixed_w:
            # The User specified a fixed channel width
            do_second_run = False
            second_run_args = vpr_args

            if "write_rr_graph" in vpr_args or "analysis" in vpr_args or "route" in vpr_args:
                do_second_run = True

            vtr.vpr.run(
                architecture_copy,
                pre_vpr_netlist,
                circuit_copy.stem,
                command_runner=command_runner,
                temp_dir=temp_dir,
                vpr_args=vpr_args,
            )
            if do_second_run:
                # Run vpr again with additional parameters.
                # This is used to ensure that files generated by VPR can be re-loaded by it
                rr_graph_ext = (Path(second_run_args["write_rr_graph"]).suffix
                                if "write_rr_graph" in second_run_args else
                                ".xml")
                if check_place:
                    second_run_args["route"] = True
                if check_route:
                    second_run_args["analysis"] = True
                vtr.vpr.run_second_time(
                    architecture_copy,
                    pre_vpr_netlist,
                    circuit_copy.stem,
                    command_runner=command_runner,
                    temp_dir=temp_dir,
                    second_run_args=second_run_args,
                    rr_graph_ext=rr_graph_ext,
                )
        else:
            # First find minW and then re-route at a relaxed W
            vtr.vpr.run_relax_w(
                architecture_copy,
                pre_vpr_netlist,
                circuit_copy.stem,
                command_runner=command_runner,
                relax_w_factor=relax_w_factor,
                temp_dir=temp_dir,
                vpr_args=vpr_args,
            )
        lec_base_netlist = pre_vpr_netlist if not lec_base_netlist else lec_base_netlist

    #
    # Logical Equivalence Checks (LEC)
    #
    if check_equivalent:
        for file in Path(temp_dir).iterdir():
            if "post_synthesis.blif" in str(file):
                gen_postsynthesis_netlist = file.name
                break
        vtr.abc.run_lec(
            lec_base_netlist,
            gen_postsynthesis_netlist,
            command_runner=command_runner,
            temp_dir=temp_dir,
        )

    # Do a second-run of the incremental analysis to compare the result files
    if check_incremental_sta_consistency:
        vtr.vpr.cmp_full_vs_incr_sta(
            architecture_copy,
            pre_vpr_netlist,
            circuit_copy.stem,
            command_runner=command_runner,
            vpr_args=vpr_args,
            temp_dir=temp_dir,
        )

    if not keep_intermediate_files:
        delete_intermediate_files(
            next_stage_netlist,
            post_ace_activity_file,
            keep_result_files,
            temp_dir,
            power_tech_file,
        )