示例#1
0
文件: __init__.py 项目: zxh0717/finn
    def prepare_rtlsim(self):
        """Creates a Verilator emulation library for the RTL code generated
        for this node, sets the rtlsim_so attribute to its path and returns
        a PyVerilator wrapper around it."""

        if PyVerilator is None:
            raise ImportError("Installation of PyVerilator is required.")
        # ensure that code is generated
        code_gen_dir = self.get_nodeattr("code_gen_dir_ipgen")
        assert (code_gen_dir != ""), """Node attribute "code_gen_dir_ipgen" is
        not set. Please run HLSSynthIP first."""
        verilog_file = self.get_verilog_top_filename()
        assert os.path.isfile(
            verilog_file), "Cannot find top-level Verilog file."
        # build the Verilator emu library
        sim = PyVerilator.build(
            verilog_file,
            build_dir=make_build_dir("pyverilator_" + self.onnx_node.name +
                                     "_"),
            verilog_path=[
                "{}/project_{}/sol1/impl/verilog/".format(
                    code_gen_dir, self.onnx_node.name)
            ],
            trace_depth=get_rtlsim_trace_depth(),
        )
        # save generated lib filename in attribute
        self.set_nodeattr("rtlsim_so", sim.lib._name)
        return sim
示例#2
0
def pyverilate_stitched_ip(model):
    "Given a model with stitched IP, return a PyVerilator sim object."
    if PyVerilator is None:
        raise ImportError("Installation of PyVerilator is required.")

    vivado_stitch_proj_dir = model.get_metadata_prop("vivado_stitch_proj")
    with open(vivado_stitch_proj_dir + "/all_verilog_srcs.txt", "r") as f:
        all_verilog_srcs = f.read().split()

    def file_to_dir(x):
        return os.path.dirname(os.path.realpath(x))

    def file_to_basename(x):
        return os.path.basename(os.path.realpath(x))

    all_verilog_dirs = list(map(file_to_dir, all_verilog_srcs))
    all_verilog_files = list(
        set(
            filter(
                lambda x: x.endswith(".v"),
                list(map(file_to_basename, all_verilog_srcs)),
            )))
    top_module_name = model.get_metadata_prop("wrapper_filename")
    top_module_name = file_to_basename(top_module_name).strip(".v")
    build_dir = make_build_dir("pyverilator_ipstitched_")
    sim = PyVerilator.build(
        all_verilog_files,
        verilog_path=all_verilog_dirs,
        build_dir=build_dir,
        trace_depth=get_rtlsim_trace_depth(),
        top_module_name=top_module_name,
        auto_eval=False,
    )
    return sim
示例#3
0
def step_measure_rtlsim_performance(model: ModelWrapper, cfg: DataflowBuildConfig):
    """Measure performance + latency of stitched-IP model in rtlsim (pyverilator).
    Depends on the DataflowOutputType.STITCHED_IP output product.
    """

    if DataflowOutputType.RTLSIM_PERFORMANCE in cfg.generate_outputs:
        assert (
            DataflowOutputType.STITCHED_IP in cfg.generate_outputs
        ), "rtlsim_perf needs stitched IP"
        report_dir = cfg.output_dir + "/report"
        os.makedirs(report_dir, exist_ok=True)
        # prepare ip-stitched rtlsim
        rtlsim_model = deepcopy(model)
        rtlsim_model = prepare_for_stitched_ip_rtlsim(rtlsim_model, cfg)
        # run with single input to get latency
        orig_rtlsim_trace_depth = get_rtlsim_trace_depth()
        rtlsim_bs = int(cfg.rtlsim_batch_size)
        assert rtlsim_bs > 0, "rtlsim batch size must be >0"
        if cfg.verify_save_rtlsim_waveforms:
            # set depth to 3 for layer-by-layer visibility
            os.environ["RTLSIM_TRACE_DEPTH"] = "3"
            rtlsim_model.set_metadata_prop(
                "rtlsim_trace", "%s/rtlsim_perf_batch_%d.vcd" % (report_dir, rtlsim_bs)
            )
        rtlsim_model.set_metadata_prop("extra_verilator_args", str(["-CFLAGS", "-O3"]))
        rtlsim_perf_dict = throughput_test_rtlsim(rtlsim_model, rtlsim_bs)
        rtlsim_latency = rtlsim_perf_dict["cycles"]
        rtlsim_perf_dict["latency_cycles"] = rtlsim_latency
        with open(report_dir + "/rtlsim_performance.json", "w") as f:
            json.dump(rtlsim_perf_dict, f, indent=2)
        if cfg.verify_save_rtlsim_waveforms:
            # restore original trace depth
            os.environ["RTLSIM_TRACE_DEPTH"] = str(orig_rtlsim_trace_depth)

    return model
示例#4
0
    def prepare_rtlsim(self):
        """Creates a Verilator emulation library for the RTL code generated
        for this node, sets the rtlsim_so attribute to its path and returns
        a PyVerilator wrapper around it."""

        if PyVerilator is None:
            raise ImportError("Installation of PyVerilator is required.")
        verilog_paths = self.get_all_verilog_paths()
        verilog_files = self.get_all_verilog_filenames()
        # build the Verilator emu library
        sim = PyVerilator.build(
            verilog_files,
            build_dir=make_build_dir("pyverilator_" + self.onnx_node.name + "_"),
            verilog_path=verilog_paths,
            trace_depth=get_rtlsim_trace_depth(),
            top_module_name=self.get_verilog_top_module_name(),
        )
        # save generated lib filename in attribute
        self.set_nodeattr("rtlsim_so", sim.lib._name)
        return sim
示例#5
0
def pyverilate_stitched_ip(model):
    "Given a model with stitched IP, return a PyVerilator sim object."
    if PyVerilator is None:
        raise ImportError("Installation of PyVerilator is required.")

    vivado_stitch_proj_dir = model.get_metadata_prop("vivado_stitch_proj")
    with open(vivado_stitch_proj_dir + "/all_verilog_srcs.txt", "r") as f:
        all_verilog_srcs = f.read().split()

    def file_to_dir(x):
        return os.path.dirname(os.path.realpath(x))

    all_verilog_dirs = list(map(file_to_dir, all_verilog_srcs))
    top_verilog = model.get_metadata_prop("wrapper_filename")
    build_dir = make_build_dir("pyverilator_ipstitched_")
    sim = PyVerilator.build(
        top_verilog,
        verilog_path=all_verilog_dirs,
        build_dir=build_dir,
        trace_depth=get_rtlsim_trace_depth(),
    )
    return sim
示例#6
0
def pyverilate_stitched_ip(model, read_internal_signals=True):
    """Given a model with stitched IP, return a PyVerilator sim object.
    If read_internal_signals is True, it will be possible to examine the
    internal (not only port) signals of the Verilog module, but this may
    slow down compilation and emulation.
    Trace depth is also controllable, see get_rtlsim_trace_depth()
    """
    if PyVerilator is None:
        raise ImportError("Installation of PyVerilator is required.")

    vivado_stitch_proj_dir = model.get_metadata_prop("vivado_stitch_proj")
    with open(vivado_stitch_proj_dir + "/all_verilog_srcs.txt", "r") as f:
        all_verilog_srcs = f.read().split()

    def file_to_dir(x):
        return os.path.dirname(os.path.realpath(x))

    def file_to_basename(x):
        return os.path.basename(os.path.realpath(x))

    top_module_file_name = file_to_basename(
        model.get_metadata_prop("wrapper_filename"))
    top_module_name = top_module_file_name.strip(".v")
    build_dir = make_build_dir("pyverilator_ipstitched_")

    # dump all Verilog code to a single file
    # this is because large models with many files require
    # a verilator command line too long for bash on most systems
    # NOTE: there are duplicates in this list, and some files
    # are identical but in multiple directories (regslice_core.v)

    # remove duplicates from list by doing list -> set -> list
    all_verilog_files = list(
        set(filter(lambda x: x.endswith(".v"), all_verilog_srcs)))

    # remove all but one instances of regslice_core.v
    filtered_verilog_files = []
    remove_entry = False
    for vfile in all_verilog_files:
        if "regslice_core" in vfile:
            if not remove_entry:
                filtered_verilog_files.append(vfile)
            remove_entry = True
        else:
            filtered_verilog_files.append(vfile)

    # concatenate all verilog code into a single file
    with open(vivado_stitch_proj_dir + "/" + top_module_file_name, "w") as wf:
        for vfile in filtered_verilog_files:
            with open(vfile) as rf:
                wf.write("//Added from " + vfile + "\n\n")
                wf.write(rf.read())

    sim = PyVerilator.build(
        top_module_file_name,
        verilog_path=[vivado_stitch_proj_dir],
        build_dir=build_dir,
        trace_depth=get_rtlsim_trace_depth(),
        top_module_name=top_module_name,
        auto_eval=False,
        read_internal_signals=read_internal_signals,
    )
    return sim
示例#7
0
def pyverilate_stitched_ip(
    model,
    read_internal_signals=True,
    disable_common_warnings=True,
    extra_verilator_args=[],
):
    """Given a model with stitched IP, return a PyVerilator sim object.
    Trace depth is also controllable, see get_rtlsim_trace_depth()

    :param read_internal_signals  If set, it will be possible to examine the
        internal (not only port) signals of the Verilog module, but this may
        slow down compilation and emulation.

    :param disable_common_warnings If set, disable the set of warnings that
        Vivado-HLS-generated Verilog typically triggers in Verilator
        (which can be very verbose otherwise)

    """
    if PyVerilator is None:
        raise ImportError("Installation of PyVerilator is required.")

    vivado_stitch_proj_dir = model.get_metadata_prop("vivado_stitch_proj")
    with open(vivado_stitch_proj_dir + "/all_verilog_srcs.txt", "r") as f:
        all_verilog_srcs = f.read().split()

    def file_to_dir(x):
        return os.path.dirname(os.path.realpath(x))

    def file_to_basename(x):
        return os.path.basename(os.path.realpath(x))

    top_module_file_name = file_to_basename(
        model.get_metadata_prop("wrapper_filename"))
    top_module_name = top_module_file_name.strip(".v")
    build_dir = make_build_dir("pyverilator_ipstitched_")

    # dump all Verilog code to a single file
    # this is because large models with many files require
    # a verilator command line too long for bash on most systems
    # NOTE: there are duplicates in this list, and some files
    # are identical but in multiple directories (regslice_core.v)

    # remove duplicates from list by doing list -> set -> list
    all_verilog_files = list(
        set(filter(lambda x: x.endswith(".v"), all_verilog_srcs)))

    # remove all but one instances of regslice_core.v
    filtered_verilog_files = []
    remove_entry = False
    for vfile in all_verilog_files:
        if "regslice_core" in vfile:
            if not remove_entry:
                filtered_verilog_files.append(vfile)
            remove_entry = True
        else:
            filtered_verilog_files.append(vfile)

    # concatenate all verilog code into a single file
    with open(vivado_stitch_proj_dir + "/" + top_module_file_name, "w") as wf:
        for vfile in filtered_verilog_files:
            with open(vfile) as rf:
                wf.write("//Added from " + vfile + "\n\n")
                wf.write(rf.read())

    verilator_args = []
    # disable common verilator warnings that should be harmless but commonly occur
    # in large quantities for Vivado HLS-generated verilog code
    if disable_common_warnings:
        verilator_args += ["-Wno-STMTDLY"]
        verilator_args += ["-Wno-PINMISSING"]
        verilator_args += ["-Wno-IMPLICIT"]
        verilator_args += ["-Wno-WIDTH"]
        verilator_args += ["-Wno-COMBDLY"]
    # force inlining of all submodules to ensure we can read internal signals properly
    if read_internal_signals:
        verilator_args += ["--inline-mult", "0"]

    sim = PyVerilator.build(
        top_module_file_name,
        verilog_path=[vivado_stitch_proj_dir],
        build_dir=build_dir,
        trace_depth=get_rtlsim_trace_depth(),
        top_module_name=top_module_name,
        auto_eval=False,
        read_internal_signals=read_internal_signals,
        extra_args=verilator_args + extra_verilator_args,
    )
    return sim