コード例 #1
0
ファイル: vcd.py プロジェクト: CG4002-B04/ext_comms
def get_all_stream_if_stats(vcd_file,
                            stream_ifs=None,
                            sort_by="{'V': 1, 'R': 0}",
                            num_workers=None):
    """Return a list of streaming interface stats, sorted by the percentage
    for the given sort_by key. If stream_ifs is None, all streaming interface
    stats will be returned, otherwise treated as a list of interface names to
    return the stats for.
    By default the number of parallel workers from the environment variable
    NUM_DEFAULT_WORKERS will be used. This behavior can be changed on a per
    call basis by supplying the optional parameter: num_workers
    """

    if stream_ifs is None:
        stream_ifs = list_stream_if(vcd_file)

    if num_workers is None:
        num_workers = get_num_default_workers()

    with mp.Pool(num_workers) as p:
        stream_ifs = map(lambda x: (x, vcd_file), stream_ifs)
        all_stats = p.map(_get_stats, stream_ifs)

    def sort_key(x):
        stat = x[1]
        (samples, percent) = stat[sort_by]
        return percent

    ret = sorted(all_stats, key=sort_key)
    return ret
コード例 #2
0
ファイル: prepare_cppsim.py プロジェクト: umav1511/finn
 def __init__(self, num_workers=None):
     super().__init__()
     if num_workers is None:
         self._num_workers = get_num_default_workers()
     else:
         self._num_workers = num_workers
     assert self._num_workers >= 0, "Number of workers must be nonnegative."
     if self._num_workers == 0:
         self._num_workers = mp.cpu_count()
コード例 #3
0
ファイル: vcd.py プロジェクト: Maveric4/mt_siamtrackopt
def get_all_fifo_count_max(vcd_file, fifo_count_signals=None):
    """Return a list of max FIFO counts. If fifo_count_signals is None,
    all FIFO count signals will be returned, otherwise treated as a list of
    signal names to return the stats for."""
    if fifo_count_signals is None:
        fifo_count_signals = list_fifo_count_signals(vcd_file)

    with mp.Pool(get_num_default_workers()) as p:
        fifo_count_signals = map(lambda x: (x, vcd_file), fifo_count_signals)
        all_stats = p.map(_get_fifo_max, fifo_count_signals)

    return all_stats
コード例 #4
0
ファイル: vcd.py プロジェクト: Maveric4/mt_siamtrackopt
def get_all_stream_if_stats(vcd_file,
                            stream_ifs=None,
                            sort_by="{'V': 1, 'R': 0}"):
    """Return a list of streaming interface stats, sorted by the percentage
    for the given sort_by key. If stream_ifs is None, all streamin interface
    stats will be returned, otherwise treated as a list of interface names to
    return the stats for."""

    if stream_ifs is None:
        stream_ifs = list_stream_if(vcd_file)

    with mp.Pool(get_num_default_workers()) as p:
        stream_ifs = map(lambda x: (x, vcd_file), stream_ifs)
        all_stats = p.map(_get_stats, stream_ifs)

    def sort_key(x):
        stat = x[1]
        (samples, percent) = stat[sort_by]
        return percent

    ret = sorted(all_stats, key=sort_key)
    return ret
コード例 #5
0
    def apply(self, model):
        # ensure non-relative readmemh .dat files
        model = model.transform(ReplaceVerilogRelPaths())
        ip_dirs = ["list"]
        # add RTL streamer IP
        ip_dirs.append("/workspace/finn/finn-rtllib/memstream")
        # ensure that all nodes are fpgadataflow, and that IPs are generated
        for node in model.graph.node:
            assert is_finn_op(node.domain), "Found non-FINN node"
            backend_attribute = get_by_name(node.attribute, "backend")
            assert backend_attribute is not None, "Backend node attribute is not set."
            backend_value = backend_attribute.s.decode("UTF-8")
            assert (backend_value == "fpgadataflow"
                    ), """Backend node attribute is not
            set to "fpgadataflow"."""
            node_inst = getCustomOp(node)
            ip_dir_value = node_inst.get_nodeattr("ip_path")
            assert os.path.isdir(
                ip_dir_value), "IP generation directory doesn't exist."
            ip_dirs += [ip_dir_value]
            self.create_cmds += node_inst.code_generation_ipi()
            my_producer = model.find_producer(node.input[0])
            self.connect_clk_rst(node)
            self.connect_axi(node)
            if my_producer is None:
                # first node in graph
                self.connect_s_axis_external(node)
                if node.op_type == "TLastMarker":
                    assert (node_inst.get_nodeattr("Direction") == "in"
                            ), """Output TLastMarker incorrect direction"""
                elif node.op_type == "IODMA" and len(model.graph.node) != 1:
                    # don't apply this check for a 1-node partition
                    assert (node_inst.get_nodeattr("direction") == "in"
                            ), """Input DMA incorrect direction"""
            else:
                # intermediate node
                # wire up input(s) to previous node output(s)
                # foreach input
                #     find producer
                #     find index of producer output connected to our target input
                #     get names of hdl interfaces for input and producer output
                #     issue a TCL directive to connect input to output
                #     if FC layer with mode "decoupled", add a streamer on input 1
                for i in range(len(node.input)):
                    producer = model.find_producer(node.input[i])
                    if producer is None:
                        continue
                    j = list(producer.output).index(node.input[i])
                    src_intf_name = getCustomOp(
                        producer).get_verilog_top_module_intf_names(
                        )["m_axis"][j]
                    dst_intf_name = node_inst.get_verilog_top_module_intf_names(
                    )["s_axis"][i]
                    self.connect_cmds.append(
                        "connect_bd_intf_net [get_bd_intf_pins %s/%s] "
                        "[get_bd_intf_pins %s/%s]" %
                        (producer.name, src_intf_name, node.name,
                         dst_intf_name))
            if model.find_consumers(node.output[0]) is None:
                # last node in graph
                self.connect_m_axis_external(node)
                if node.op_type == "TLastMarker":
                    assert (node_inst.get_nodeattr("Direction") == "out"
                            ), """Output TLastMarker incorrect direction"""
                elif node.op_type == "IODMA" and len(model.graph.node) != 1:
                    assert (node_inst.get_nodeattr("direction") == "out"
                            ), """Output DMA incorrect direction"""

        # create a temporary folder for the project
        prjname = "finn_vivado_stitch_proj"
        vivado_stitch_proj_dir = make_build_dir(prefix="vivado_stitch_proj_")
        model.set_metadata_prop("vivado_stitch_proj", vivado_stitch_proj_dir)
        # start building the tcl script
        tcl = []
        # create vivado project
        tcl.append("create_project %s %s -part %s" %
                   (prjname, vivado_stitch_proj_dir, self.fpgapart))
        # add all the generated IP dirs to ip_repo_paths
        ip_dirs_str = " ".join(ip_dirs)
        tcl.append("set_property ip_repo_paths [%s] [current_project]" %
                   ip_dirs_str)
        tcl.append("update_ip_catalog")
        # create block design and instantiate all layers
        block_name = self.ip_name
        tcl.append('create_bd_design "%s"' % block_name)
        tcl.extend(self.create_cmds)
        tcl.extend(self.connect_cmds)
        fclk_mhz = 1 / (self.clk_ns * 0.001)
        fclk_hz = fclk_mhz * 1000000
        model.set_metadata_prop("clk_ns", str(self.clk_ns))
        tcl.append("set_property CONFIG.FREQ_HZ %f [get_bd_ports /ap_clk]" %
                   fclk_hz)
        tcl.append("regenerate_bd_layout")
        tcl.append("validate_bd_design")
        tcl.append("save_bd_design")
        # create wrapper hdl (for rtlsim later on)
        bd_base = "%s/%s.srcs/sources_1/bd/%s" % (
            vivado_stitch_proj_dir,
            prjname,
            block_name,
        )
        bd_filename = "%s/%s.bd" % (bd_base, block_name)
        tcl.append("make_wrapper -files [get_files %s] -top" % bd_filename)
        wrapper_filename = "%s/hdl/%s_wrapper.v" % (bd_base, block_name)
        tcl.append("add_files -norecurse %s" % wrapper_filename)
        model.set_metadata_prop("wrapper_filename", wrapper_filename)
        # synthesize to DCP and export stub, DCP and constraints
        if self.vitis:
            tcl.append(
                "set_property SYNTH_CHECKPOINT_MODE Hierarchical [ get_files %s ]"
                % bd_filename)
            tcl.append(
                "set_property -name {STEPS.SYNTH_DESIGN.ARGS.MORE OPTIONS} "
                "-value {-mode out_of_context} -objects [get_runs synth_1]")
            num_workers = get_num_default_workers()
            assert num_workers >= 0, "Number of workers must be nonnegative."
            if num_workers == 0:
                num_workers = mp.cpu_count()
            tcl.append("launch_runs synth_1 -jobs %s" % str(num_workers))
            tcl.append("wait_on_run [get_runs synth_1]")
            tcl.append("open_run synth_1 -name synth_1")
            tcl.append("write_verilog -force -mode synth_stub %s.v" %
                       block_name)
            tcl.append("write_checkpoint %s.dcp" % block_name)
            tcl.append("write_xdc %s.xdc" % block_name)
            tcl.append("report_utilization -file %s_partition_util.rpt" %
                       block_name)
        # export block design itself as an IP core
        block_vendor = "xilinx_finn"
        block_library = "finn"
        block_vlnv = "%s:%s:%s:1.0" % (block_vendor, block_library, block_name)
        model.set_metadata_prop("vivado_stitch_vlnv", block_vlnv)
        model.set_metadata_prop("vivado_stitch_ifnames", str(self.intf_names))
        tcl.append(
            ("ipx::package_project -root_dir %s/ip -vendor %s "
             "-library %s -taxonomy /UserIP -module %s -import_files") %
            (vivado_stitch_proj_dir, block_vendor, block_library, block_name))
        tcl.append("set_property core_revision 2 [ipx::find_open_core %s]" %
                   block_vlnv)
        tcl.append("ipx::create_xgui_files [ipx::find_open_core %s]" %
                   block_vlnv)
        # if targeting Vitis, add some properties to the IP
        if self.vitis:
            tcl.append(
                "ipx::remove_bus_parameter FREQ_HZ "
                "[ipx::get_bus_interfaces CLK.AP_CLK -of_objects [ipx::current_core]]"
            )
            # replace source code with dcp
            tcl.append(
                "set_property sdx_kernel true [ipx::find_open_core %s]" %
                block_vlnv)
            tcl.append(
                "set_property sdx_kernel_type rtl [ipx::find_open_core %s]" %
                block_vlnv)
            tcl.append(
                "set_property supported_families { } [ipx::find_open_core %s]"
                % block_vlnv)
            tcl.append(
                "set_property xpm_libraries {XPM_CDC XPM_MEMORY XPM_FIFO} "
                "[ipx::find_open_core %s]" % block_vlnv)
            tcl.append("set_property auto_family_support_level level_2 "
                       "[ipx::find_open_core %s]" % block_vlnv)
            # remove all files from synthesis and sim groups
            # we'll replace with DCP, stub, and xdc
            tcl.append(
                "ipx::remove_all_file "
                "[ipx::get_file_groups xilinx_anylanguagebehavioralsimulation]"
            )
            tcl.append("ipx::remove_all_file "
                       "[ipx::get_file_groups xilinx_anylanguagesynthesis]")
            tcl.append(
                "ipx::remove_file_group "
                "xilinx_anylanguagebehavioralsimulation [ipx::current_core]")
            tcl.append("ipx::remove_file_group "
                       "xilinx_anylanguagesynthesis [ipx::current_core]")
            # remove sim and src folders
            tcl.append("file delete -force %s/ip/sim" % vivado_stitch_proj_dir)
            tcl.append("file delete -force %s/ip/src" % vivado_stitch_proj_dir)
            # copy and add DCP, stub, and xdc
            tcl.append("file mkdir %s/ip/dcp" % vivado_stitch_proj_dir)
            tcl.append("file mkdir %s/ip/impl" % vivado_stitch_proj_dir)
            tcl.append("file copy -force %s.dcp %s/ip/dcp" %
                       (block_name, vivado_stitch_proj_dir))
            tcl.append("file copy -force %s.xdc %s/ip/impl" %
                       (block_name, vivado_stitch_proj_dir))
            tcl.append(
                "ipx::add_file_group xilinx_implementation [ipx::current_core]"
            )
            tcl.append(
                "ipx::add_file impl/%s.xdc [ipx::get_file_groups xilinx_implementation]"
                % block_name)
            tcl.append(
                "set_property used_in [list implementation] "
                "[ipx::get_files impl/%s.xdc "
                "-of_objects [ipx::get_file_groups xilinx_implementation]]" %
                block_name)
            tcl.append("ipx::add_file_group "
                       "xilinx_synthesischeckpoint [ipx::current_core]")
            tcl.append("ipx::add_file dcp/%s.dcp "
                       "[ipx::get_file_groups xilinx_synthesischeckpoint]" %
                       block_name)
            tcl.append(
                "ipx::add_file_group xilinx_simulationcheckpoint [ipx::current_core]"
            )
            tcl.append("ipx::add_file dcp/%s.dcp "
                       "[ipx::get_file_groups xilinx_simulationcheckpoint]" %
                       block_name)
        tcl.append("ipx::update_checksums [ipx::find_open_core %s]" %
                   block_vlnv)
        tcl.append("ipx::save_core [ipx::find_open_core %s]" % block_vlnv)
        # export list of used Verilog files (for rtlsim later on)
        tcl.append(
            "set all_v_files [get_files -filter {FILE_TYPE == Verilog " +
            "&& USED_IN_SYNTHESIS == 1} ]")
        v_file_list = "%s/all_verilog_srcs.txt" % vivado_stitch_proj_dir
        tcl.append("set fp [open %s w]" % v_file_list)
        # write each verilog filename to all_verilog_srcs.txt
        tcl.append("foreach vf $all_v_files {puts $fp $vf}")
        tcl.append("close $fp")
        # write the project creator tcl script
        tcl_string = "\n".join(tcl) + "\n"
        with open(vivado_stitch_proj_dir + "/make_project.tcl", "w") as f:
            f.write(tcl_string)
        # create a shell script and call Vivado
        make_project_sh = vivado_stitch_proj_dir + "/make_project.sh"
        working_dir = os.environ["PWD"]
        with open(make_project_sh, "w") as f:
            f.write("#!/bin/bash \n")
            f.write("cd {}\n".format(vivado_stitch_proj_dir))
            f.write("vivado -mode batch -source make_project.tcl\n")
            f.write("cd {}\n".format(working_dir))
        bash_command = ["bash", make_project_sh]
        process_compile = subprocess.Popen(bash_command,
                                           stdout=subprocess.PIPE)
        process_compile.communicate()
        return (model, False)
コード例 #6
0
    def apply(self, model):

        # create a config file and empty list of xo files
        config = []
        idma_idx = 0
        odma_idx = 0
        aximm_idx = 0
        axilite_idx = 0
        global_clk_ns = 0
        instance_names = {}
        for node in model.graph.node:
            assert node.op_type == "StreamingDataflowPartition", "Invalid link graph"
            sdp_node = getCustomOp(node)
            dataflow_model_filename = sdp_node.get_nodeattr("model")
            kernel_model = ModelWrapper(dataflow_model_filename)

            ipstitch_path = kernel_model.get_metadata_prop(
                "vivado_stitch_proj")
            if ipstitch_path is None or (not os.path.isdir(ipstitch_path)):
                raise Exception(
                    "No stitched IPI design found for %s, apply CreateStitchedIP first."
                    % node.name)

            vivado_stitch_vlnv = kernel_model.get_metadata_prop(
                "vivado_stitch_vlnv")
            if vivado_stitch_vlnv is None:
                raise Exception(
                    "No vlnv found for %s, apply CreateStitchedIP first." %
                    node.name)

            ip_dirs = ["list"]
            ip_dirs += collect_ip_dirs(kernel_model, ipstitch_path)
            ip_dirs_str = "[%s]" % (" ".join(ip_dirs))
            config.append(
                "set_property ip_repo_paths "
                "[concat [get_property ip_repo_paths [current_project]] %s] "
                "[current_project]" % ip_dirs_str)
            config.append("update_ip_catalog -rebuild -scan_changes")

            # get metadata property clk_ns to calculate clock frequency
            clk_ns = float(kernel_model.get_metadata_prop("clk_ns"))
            if clk_ns > global_clk_ns:
                global_clk_ns = clk_ns

            # gather info on connectivity
            # assume each node connected to outputs/inputs is DMA:
            # has axis, aximm and axilite
            # everything else is axis-only
            # assume only one connection from each ip to the next
            # all aximm allocated to DDR[0]
            # all kernels allocated to SLR0
            producer = model.find_producer(node.input[0])
            consumer = model.find_consumers(node.output[0])
            # define kernel instances
            # name kernels connected to graph inputs as idmaxx
            # name kernels connected to graph inputs as odmaxx
            if producer is None or consumer is None:
                if producer is None:
                    instance_names[node.name] = "idma" + str(idma_idx)
                elif consumer is None:
                    instance_names[node.name] = "odma" + str(odma_idx)
                config.append("create_bd_cell -type ip -vlnv %s %s" %
                              (vivado_stitch_vlnv, instance_names[node.name]))
                config.append(
                    "connect_bd_intf_net [get_bd_intf_pins %s/m_axi_gmem0] "
                    "[get_bd_intf_pins smartconnect_0/S%02d_AXI]" %
                    (instance_names[node.name], aximm_idx))
                config.append(
                    "connect_bd_intf_net [get_bd_intf_pins %s/s_axi_control] "
                    "[get_bd_intf_pins axi_interconnect_0/M%02d_AXI]" %
                    (instance_names[node.name], axilite_idx))
                idma_idx += 1
                aximm_idx += 1
                axilite_idx += 1
            else:
                instance_names[node.name] = node.name
                config.append("create_bd_cell -type ip -vlnv %s %s" %
                              (vivado_stitch_vlnv, instance_names[node.name]))
            config.append("connect_bd_net [get_bd_pins %s/ap_clk] "
                          "[get_bd_pins smartconnect_0/aclk]" %
                          instance_names[node.name])
            config.append("connect_bd_net [get_bd_pins %s/ap_rst_n] "
                          "[get_bd_pins smartconnect_0/aresetn]" %
                          instance_names[node.name])
            # connect streams
            if producer is not None:
                for i in range(len(node.input)):
                    producer = model.find_producer(node.input[i])
                    if producer is not None:
                        j = list(producer.output).index(node.input[i])
                        config.append(
                            "connect_bd_intf_net [get_bd_intf_pins %s/s_axis_%d] "
                            "[get_bd_intf_pins %s/m_axis_%d]" % (
                                instance_names[node.name],
                                i,
                                instance_names[producer.name],
                                j,
                            ))

        # create a temporary folder for the project
        vivado_pynq_proj_dir = make_build_dir(prefix="vivado_zynq_proj_")
        model.set_metadata_prop("vivado_pynq_proj", vivado_pynq_proj_dir)

        fclk_mhz = int(1 / (global_clk_ns * 0.001))

        # create a TCL recipe for the project
        ipcfg = vivado_pynq_proj_dir + "/ip_config.tcl"
        config = "\n".join(config) + "\n"
        with open(ipcfg, "w") as f:
            f.write(templates.custom_zynq_shell_template % (
                fclk_mhz,
                axilite_idx,
                aximm_idx,
                self.platform,
                pynq_part_map[self.platform],
                config,
                self.enable_debug,
                get_num_default_workers(),
            ))

        # create a TCL recipe for the project
        synth_project_sh = vivado_pynq_proj_dir + "/synth_project.sh"
        working_dir = os.environ["PWD"]
        with open(synth_project_sh, "w") as f:
            f.write("#!/bin/bash \n")
            f.write("cd {}\n".format(vivado_pynq_proj_dir))
            f.write("vivado -mode tcl -source %s\n" % ipcfg)
            f.write("cd {}\n".format(working_dir))

        # call the synthesis script
        bash_command = ["bash", synth_project_sh]
        process_compile = subprocess.Popen(bash_command,
                                           stdout=subprocess.PIPE)
        process_compile.communicate()
        bitfile_name = (vivado_pynq_proj_dir +
                        "/finn_zynq_link.runs/impl_1/top_wrapper.bit")
        if not os.path.isfile(bitfile_name):
            raise Exception("Synthesis failed, no bitfile found")
        deploy_bitfile_name = vivado_pynq_proj_dir + "/resizer.bit"
        copy(bitfile_name, deploy_bitfile_name)
        # set bitfile attribute
        model.set_metadata_prop("bitfile", deploy_bitfile_name)
        hwh_name = (vivado_pynq_proj_dir +
                    "/finn_zynq_link.srcs/sources_1/bd/top/hw_handoff/top.hwh")
        if not os.path.isfile(hwh_name):
            raise Exception("Synthesis failed, no hardware handoff file found")
        deploy_hwh_name = vivado_pynq_proj_dir + "/resizer.hwh"
        copy(hwh_name, deploy_hwh_name)
        model.set_metadata_prop("hw_handoff", deploy_hwh_name)
        # filename for the synth utilization report
        synth_report_filename = vivado_pynq_proj_dir + "/synth_report.xml"
        model.set_metadata_prop("vivado_synth_rpt", synth_report_filename)
        return (model, False)