diff options
| -rw-r--r-- | fpga/usrp3/tools/scripts/auto_inst_e310.yml | 22 | ||||
| -rw-r--r-- | fpga/usrp3/tools/scripts/auto_inst_x310.yml | 29 | ||||
| -rwxr-xr-x | fpga/usrp3/tools/scripts/uhd_image_builder.py | 537 | ||||
| -rwxr-xr-x | fpga/usrp3/tools/scripts/uhd_image_builder_gui.py | 656 | 
4 files changed, 0 insertions, 1244 deletions
| diff --git a/fpga/usrp3/tools/scripts/auto_inst_e310.yml b/fpga/usrp3/tools/scripts/auto_inst_e310.yml deleted file mode 100644 index 5842e17c2..000000000 --- a/fpga/usrp3/tools/scripts/auto_inst_e310.yml +++ /dev/null @@ -1,22 +0,0 @@ -# auto-inst file for E310 -# To regenerate rfnoc_ce_auto_inst_e310.v: -#   ./uhd_image_builder.py  -d e310 -t E310_RFNOC_sg3 -y auto_inst_e310.yml -o rfnoc_ce_auto_inst_e310.v - -- block: axi_fifo_loopback -  parameters: - -- block: window -  parameters: - -- block: fft -  parameters: - -- block: fosphor -  parameters: -    MTU: 12 - -- block: axi_fifo_loopback -  parameters: - -- block: fir_filter -  parameters: diff --git a/fpga/usrp3/tools/scripts/auto_inst_x310.yml b/fpga/usrp3/tools/scripts/auto_inst_x310.yml deleted file mode 100644 index 26548031b..000000000 --- a/fpga/usrp3/tools/scripts/auto_inst_x310.yml +++ /dev/null @@ -1,29 +0,0 @@ -# auto-inst file for X310 -# To regenerate rfnoc_ce_auto_inst_x310.v: -#   ./uhd_image_builder.py  -d x310 -t X310_RFNOC_HG -m 10 --fill-with-fifos -y auto_inst_x310.yml -o rfnoc_ce_auto_inst_x310.v - -- block: ddc -  parameters: -    NOC_ID: 64'hDDC0_0000_0000_0001 -    NUM_CHAINS: 1 - -- block: duc -  parameters: - -- block: fft -  parameters: - -- block: window -  parameters: - -- block: fir_filter -  parameters: - -- block: siggen -  parameters: - -- block: keep_one_in_n -  parameters: - -- block: fosphor -  parameters: diff --git a/fpga/usrp3/tools/scripts/uhd_image_builder.py b/fpga/usrp3/tools/scripts/uhd_image_builder.py deleted file mode 100755 index 7398b6e13..000000000 --- a/fpga/usrp3/tools/scripts/uhd_image_builder.py +++ /dev/null @@ -1,537 +0,0 @@ -#!/usr/bin/env python -""" -Copyright 2016-2017 Ettus Research -Copyright 2019 Ettus Research, A National Instrument Brand - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program.  If not, see <http://www.gnu.org/licenses/>. -""" - -from __future__ import print_function -import argparse -import os -import re -import glob - -HEADER_TMPL = """///////////////////////////////////////////////////////// -// Auto-generated by uhd_image_builder.py! Any changes -// in this file will be overwritten the next time -// this script is run. -///////////////////////////////////////////////////////// -localparam NUM_CE = {num_ce}; -wire [NUM_CE*64-1:0] ce_flat_o_tdata, ce_flat_i_tdata; -wire [63:0]          ce_o_tdata[0:NUM_CE-1], ce_i_tdata[0:NUM_CE-1]; -wire [NUM_CE-1:0]    ce_o_tlast, ce_o_tvalid, ce_o_tready, ce_i_tlast, ce_i_tvalid, ce_i_tready; -wire [63:0]          ce_debug[0:NUM_CE-1]; -// Flattern CE tdata arrays -genvar k; -generate -  for (k = 0; k < NUM_CE; k = k + 1) begin -    assign ce_o_tdata[k] = ce_flat_o_tdata[k*64+63:k*64]; -    assign ce_flat_i_tdata[k*64+63:k*64] = ce_i_tdata[k]; -  end -endgenerate -wire ce_clk = radio_clk; -wire ce_rst = radio_rst; -""" - -BLOCK_TMPL = """ -noc_block_{blockname} {blockparameters} {instname} ( -  .bus_clk(bus_clk), .bus_rst(bus_rst), -  .ce_clk({clock}_clk), .ce_rst({clock}_rst), -  .i_tdata(ce_o_tdata[{n}]), .i_tlast(ce_o_tlast[{n}]), .i_tvalid(ce_o_tvalid[{n}]), .i_tready(ce_o_tready[{n}]), -  .o_tdata(ce_i_tdata[{n}]), .o_tlast(ce_i_tlast[{n}]), .o_tvalid(ce_i_tvalid[{n}]), .o_tready(ce_i_tready[{n}]), -  .debug(ce_debug[{n}]){extraports} -); -""" - -FILL_FIFO_TMPL = """ -// Fill remaining crossbar ports with loopback FIFOs -genvar n; -generate -  for (n = {fifo_start}; n < NUM_CE; n = n + 1) begin -    noc_block_axi_fifo_loopback inst_noc_block_axi_fifo_loopback ( -      .bus_clk(bus_clk), .bus_rst(bus_rst), -      .ce_clk(ce_clk), .ce_rst(ce_rst), -      .i_tdata(ce_o_tdata[n]), .i_tlast(ce_o_tlast[n]), .i_tvalid(ce_o_tvalid[n]), .i_tready(ce_o_tready[n]), -      .o_tdata(ce_i_tdata[n]), .o_tlast(ce_i_tlast[n]), .o_tvalid(ce_i_tvalid[n]), .o_tready(ce_i_tready[n]), -      .debug(ce_debug[n]) -    ); -  end -endgenerate -""" - -# List of blocks that are part of our library but that do not take part -# in the process this tool provides -BLACKLIST = {'radio_core', 'axi_dma_fifo'} - -OOT_DIR_TMPL = """\nOOT_DIR = {oot_dir}\n""" -OOT_INC_TMPL = """include $(OOT_DIR)/Makefile.inc\n""" -OOT_SRCS_TMPL = """RFNOC_OOT_SRCS += {sources}\n""" -OOT_SRCS_FILE_HDR = """################################################## -# Include OOT makefiles -##################################################\n""" - - -def setup_parser(): -    """ -    Create argument parser -    """ -    parser = argparse.ArgumentParser( -        description="Generate the NoC block instantiation file", -    ) -    parser.add_argument( -        "-I", "--include-dir", -        help="Path directory of the RFNoC Out-of-Tree module", -        nargs='+', -        default=None) -    parser.add_argument( -        "-y", "--yml", -        help="YML file definition of onboard blocks\ -              (overrides the 'block' positional arguments)", -        default=None) -    parser.add_argument( -        "-m", "--max-num-blocks", type=int, -        help="Maximum number of blocks (Max. Allowed for x310|x300: 10,\ -                for e300: 14, for e320: 12, for n300: 11, \ -                for n310/n320: 10)", -        default=10) -    parser.add_argument( -        "--fill-with-fifos", -        help="If the number of blocks provided was smaller than the max\ -                number, fill the rest with FIFOs", -        action="store_true") -    parser.add_argument( -        "-o", "--outfile", -        help="Output /path/filename - By running this directive,\ -                you won't build your IP", -        default=None) -    parser.add_argument( -        "--auto-inst-src", -        help="Advanced Usage: The Verilog source for the auto_inst file that " -             "will be used instead of generating one automatically", -        default=None) -    parser.add_argument( -        "-d", "--device", -        help="Device to be programmed [x300, x310, e310, e320, n300, n310, n320]", -        default="x310") -    parser.add_argument( -        "-t", "--target", -        help="Build target - image type [X3X0_RFNOC_HG, X3X0_RFNOC_XG,\ -                E310_RFNOC_sg3, E320_RFNOC_1G, N310_RFNOC_HG, ...]", -        default=None) -    parser.add_argument( -        "-g", "--GUI", -        help="Open Vivado GUI during the FPGA building process", -        action="store_true") -    parser.add_argument( -        "-c", "--clean-all", -        help="Cleans the IP before a new build", -        action="store_true") -    parser.add_argument( -        "blocks", -        help="List block names to instantiate.", -        default="", -        nargs='*', -    ) -    return parser - -def get_default_parameters(): -    default = {"clock" : "ce", -               "parameters" : None, -               "extraports" : None} -    return default - - -def parse_yml(ymlfile): -    """ -    Parse an input yaml file with a list of blocks and parameters! -    """ -    try: -        import yaml -    except ImportError: -        print('[ERROR] Could not import yaml module') -        exit(1) - -    with open(ymlfile, 'r') as input_file: -        data = yaml.load(input_file) -    blocks = [] -    params = [] -    for val in data: -        print(val['block']) -        blocks.append(val['block']) -        blockparams = get_default_parameters() -        if "clock" in val: -            blockparams["clock"] = val["clock"] -        if "parameters" in val: -            blockparams["parameters"] = val["parameters"] -        if "extraports" in val: -            blockparams["extraports"] = val["extraports"] -        print(blockparams) -        params.append(blockparams) -    print(data) -    return blocks, params - -def format_param_str(parameters): -    """ -    Take a single block parameter dictionary and format as a verilog string -    """ -    paramstr = "" -    if parameters: -        paramstrlist = [] -        for key in parameters.keys(): -            value = "" -            if parameters[key] is not None: -                value = parameters[key] -            currstr = ".%s(%s)" % (str.upper(key), value) -            paramstrlist.append(currstr) -        paramstr = "#(%s)" % (", ".join(paramstrlist)) -    return paramstr - -def format_port_str(extraports): -    """ -    Take a single dictionary and format as a verilog string representing extra block ports -    """ -    portstr = "" -    if extraports: -        portstrlist = [] -        for key in extraports.keys(): -            value = "" -            if extraports[key] is not None: -                value = extraports[key] -            currstr = ".%s(%s)" % (key, value) -            portstrlist.append(currstr) -        portstr = ",\n  %s" % (",\n  ".join(portstrlist)) -    return portstr - -def create_auto_inst(blocks, blockparams, max_num_blocks, fill_with_fifos=False): -    """ -    Returns the Verilog source for the auto_inst file. -    """ -    if len(blocks) == 0: -        print("[GEN_RFNOC_INST ERROR] No blocks specified!") -        exit(1) -    if len(blocks) > max_num_blocks: -        print("[GEN_RFNOC_INST ERROR] Trying to connect {} blocks, max is {}" -              .format(len(blocks), max_num_blocks)) -        exit(1) -    num_ce = max_num_blocks -    if not fill_with_fifos: -        num_ce = len(blocks) -    vfile = HEADER_TMPL.format(num_ce=num_ce) -    blocks_in_blacklist = [block for block in blocks if block in BLACKLIST] -    if len(blocks_in_blacklist): -        print("[RFNoC ERROR]: The following blocks require special treatment and"\ -                " can't be instantiated with this tool:  ") -        for element in blocks_in_blacklist: -            print(" * ", element) -        print("Remove them from the command and run the uhd_image_builder.py again.") -        exit(0) -    print("--Using the following blocks to generate image:") -    block_count = {k: 0 for k in set(blocks)} -    for i, (block, params) in enumerate(zip(blocks, blockparams)): -        block_count[block] += 1 -        instname = "inst_{}{}".format(block, "" \ -                if block_count[block] == 1 else block_count[block]) -        print("    * {}".format(block)) -        vfile += BLOCK_TMPL.format(blockname=block, -                                   blockparameters=format_param_str(params["parameters"]), -                                   instname=instname, -                                   n=i, -                                   clock=params["clock"], -                                   extraports=format_port_str(params["extraports"])) -    if fill_with_fifos: -        vfile += FILL_FIFO_TMPL.format(fifo_start=len(blocks)) -    return vfile - -def file_generator(args, vfile): -    """ -    Takes the target device as an argument and, if no '-o' directive is given, -    replaces the auto_ce file in the corresponding top folder. With the -    presence of -o, it just generates a version of the verilog file which -    is  not intended to be build -    """ -    fpga_utils_path = get_scriptpath() -    print("Adding CE instantiation file for '%s'" % args.target) -    path_to_file = fpga_utils_path +'/../../top/' + device_dict(args.device.lower()) +\ -            '/rfnoc_ce_auto_inst_' + args.device.lower() + '.v' -    if args.outfile is None: -        open(path_to_file, 'w').write(vfile) -    else: -        open(args.outfile, 'w').write(vfile) - -def append_re_line_sequence(filename, linepattern, newline): -    """ Detects the re 'linepattern' in the file. After its last occurrence, -    paste 'newline'. If the pattern does not exist, append the new line -    to the file. Then, write. If the newline already exists, leaves the file -    unchanged""" -    oldfile = open(filename, 'r').read() -    lines = re.findall(newline, oldfile, flags=re.MULTILINE) -    if len(lines) != 0: -        pass -    else: -        pattern_lines = re.findall(linepattern, oldfile, flags=re.MULTILINE) -        if len(pattern_lines) == 0: -            open(filename, 'a').write(newline) -            return -        last_line = pattern_lines[-1] -        newfile = oldfile.replace(last_line, last_line + newline + '\n') -        open(filename, 'w').write(newfile) - -def create_oot_include(device, include_dirs): -    """ -    Create the include file for OOT RFNoC sources -    """ -    oot_dir_list = [] -    target_dir = device_dict(device.lower()) -    dest_srcs_file = os.path.join(get_scriptpath(), '..', '..', 'top',\ -            target_dir, 'Makefile.OOT.inc') -    incfile = open(dest_srcs_file, 'w') -    incfile.write(OOT_SRCS_FILE_HDR) -    if include_dirs is not None: -        for dirs in include_dirs: -            currpath = os.path.abspath(str(dirs)) -            if os.path.isdir(currpath) & (os.path.basename(currpath) == "rfnoc"): -                # Case 1: Pointed directly to rfnoc directory -                oot_path = currpath -            elif os.path.isdir(os.path.join(currpath, 'rfnoc')): -                # Case 2: Pointed to top level rfnoc module directory -                oot_path = os.path.join(currpath, 'rfnoc') -            elif os.path.isfile(os.path.join(currpath, 'Makefile.inc')): -                # Case 3: Pointed to a random directory with a Makefile.inc -                oot_path = currpath -            else: -                print('No RFNoC module found at ' + os.path.abspath(currpath)) -                continue -            if oot_path not in oot_dir_list: -                oot_dir_list.append(oot_path) -                named_path = os.path.join('$(BASE_DIR)', get_relative_path(get_basedir(), oot_path)) -                incfile.write(OOT_DIR_TMPL.format(oot_dir=named_path)) -                if os.path.isfile(os.path.join(oot_path, 'Makefile.inc')): -                    # Check for Makefile.inc -                    incfile.write(OOT_INC_TMPL) -                elif os.path.isfile(os.path.join(oot_path, 'rfnoc', 'Makefile.inc')): -                    # Check for Makefile.inc -                    incfile.write(OOT_INC_TMPL) -                elif os.path.isfile(os.path.join(oot_path, 'rfnoc', 'fpga-src', 'Makefile.srcs')): -                    # Legacy: Check for fpga-src/Makefile.srcs -                    # Read, then append to file -                    curr_srcs = open(os.path.join(oot_path, 'rfnoc', 'fpga-src', 'Makefile.srcs'), 'r').read() -                    curr_srcs = curr_srcs.replace('SOURCES_PATH', os.path.join(oot_path, 'rfnoc', 'fpga-src', '')) -                    incfile.write(OOT_SRCS_TMPL.format(sources=curr_srcs)) -                else: -                    print('No valid makefile found at ' + os.path.abspath(currpath)) -                    continue -    incfile.close() - -def append_item_into_file(device, include_dir): -    """ -    Basically the same as append_re_line_sequence function, but it does not -    append anything when the input is not found -    --- -    Detects the re 'linepattern' in the file. After its last occurrence, -    pastes the input string. If pattern doesn't exist -    notifies and leaves the file unchanged -    """ -    def get_oot_srcs_list(include_dir): -        """ -        Pull the OOT sources out of the Makefile.srcs -        """ -        oot_srcs_file = os.path.join(include_dir, 'Makefile.srcs') -        oot_srcs_list = readfile(oot_srcs_file) -        return [w.replace('SOURCES_PATH', include_dir) for w in oot_srcs_list] -    # Here we go -    target_dir = device_dict(device.lower()) -    if include_dir is not None: -        for directory in include_dir: -            dirs = os.path.join(directory, '') -            checkdir_v(dirs) -            dest_srcs_file = os.path.join(get_scriptpath(), '..', '..', 'top',\ -                    target_dir, 'Makefile.srcs') -            oot_srcs_list = get_oot_srcs_list(dirs) -            dest_srcs_list = readfile(dest_srcs_file) -            prefixpattern = re.escape('$(addprefix ' + dirs + ', \\\n') -            linepattern = re.escape('RFNOC_OOT_SRCS = \\\n') -            oldfile = open(dest_srcs_file, 'r').read() -            prefixlines = re.findall(prefixpattern, oldfile, flags=re.MULTILINE) -            if len(prefixlines) == 0: -                lines = re.findall(linepattern, oldfile, flags=re.MULTILINE) -                if len(lines) == 0: -                    print("Pattern {} not found. Could not write `{}'" -                          .format(linepattern, oldfile)) -                    return -                else: -                    last_line = lines[-1] -                    srcs = "".join(oot_srcs_list) -            else: -                last_line = prefixlines[-1] -                srcs = "".join([ -                    item -                    for item in oot_srcs_list -                    if item not in dest_srcs_list -                ]) -            newfile = oldfile.replace(last_line, last_line + srcs) -            open(dest_srcs_file, 'w').write(newfile) - -def compare(file1, file2): -    """ -    compares two files line by line, and returns the lines of first file that -    were not found on the second. The returned is a tuple item that can be -    accessed in the form of a list as tuple[0], where each line takes a -    position on the list or in a string as tuple [1]. -    """ -    notinside = [] -    with open(file1, 'r') as arg1: -        with open(file2, 'r') as arg2: -            text1 = arg1.readlines() -            text2 = arg2.readlines() -            for item in text1: -                if item not in text2: -                    notinside.append(item) -    return notinside - -def readfile(files): -    """ -    compares two files line by line, and returns the lines of first file that -    were not found on the second. The returned is a tuple item that can be -    accessed in the form of a list as tuple[0], where each line takes a -    position on the list or in a string as tuple [1]. -    """ -    contents = [] -    with open(files, 'r') as arg: -        text = arg.readlines() -        for item in text: -            contents.append(item) -    return contents - -def build(args): -    " build " -    cwd = get_scriptpath() -    target_dir = device_dict(args.device.lower()) -    build_dir = os.path.join(cwd, '..', '..', 'top', target_dir) -    if os.path.isdir(build_dir): -        print("changing temporarily working directory to {0}".\ -                format(build_dir)) -        os.chdir(build_dir) -        make_cmd = ". ./setupenv.sh " -        if args.clean_all: -            make_cmd = make_cmd + "&& make cleanall " -        make_cmd = make_cmd + "&& make " + dtarget(args) -        if args.GUI: -            make_cmd = make_cmd + " GUI=1" -        # Wrap it into a bash call: -        make_cmd = '/bin/bash -c "{0}"'.format(make_cmd) -        ret_val = os.system(make_cmd) -        os.chdir(cwd) -    return ret_val - -def device_dict(args): -    """ -    helps selecting the device building folder based on the targeted device -    """ -    build_dir = { -        'x300':'x300', -        'x310':'x300', -        'e300':'e31x', -        'e310':'e31x', -        'e320':'e320', -        'n300':'n3xx', -        'n310':'n3xx', -        'n320':'n3xx' -    } -    return build_dir[args] - -def dtarget(args): -    """ -    If no target specified,  selects the default building target based on the -    targeted device -    """ -    if args.target is None: -        default_trgt = { -            'x300':'X300_RFNOC_HG', -            'x310':'X310_RFNOC_HG', -            'e310':'E310_SG3_RFNOC', -            'e320':'E320_RFNOC_1G', -            'n300':'N300_RFNOC_HG', -            'n310':'N310_RFNOC_HG', -            'n320':'N320_RFNOC_XG', -        } -        return default_trgt[args.device.lower()] -    else: -        return args.target - -def checkdir_v(include_dir): -    """ -    Checks the existance of verilog files in the given include dir -    """ -    nfiles = glob.glob(os.path.join(include_dir,'')+'*.v') -    if len(nfiles) == 0: -        print('[ERROR] No verilog files found in the given directory') -        exit(0) -    else: -        print('Verilog sources found!') -    return - -def get_scriptpath(): -    """ -    returns the absolute path where a script is located -    """ -    return os.path.dirname(os.path.realpath(__file__)) - -def get_basedir(): -    """ -    returns the base directory (BASE_DIR) used in rfnoc build process -    """ -    return os.path.abspath(os.path.join(get_scriptpath(), '..', '..', 'top')) - -def get_relative_path(base, target): -    """ -    Find the relative path (including going "up" directories) from base to target -    """ -    basedir = os.path.abspath(base) -    prefix = os.path.commonprefix([basedir, os.path.abspath(target)]) -    path_tail = os.path.relpath(os.path.abspath(target), prefix) -    total_path = path_tail -    if prefix != "": -        while basedir != os.path.abspath(prefix): -            basedir = os.path.dirname(basedir) -            total_path = os.path.join('..', total_path) -        return total_path -    else: -        print("Could not determine relative path") -        return path_tail - -def main(): -    " Go, go, go! " -    args = setup_parser().parse_args() -    if args.yml: -        print("Using yml file. Ignoring command line blocks arguments") -        blocks, params = parse_yml(args.yml) -    else: -        blocks = args.blocks -        params = [get_default_parameters()]*len(blocks) -    if args.auto_inst_src is None: -        vfile = create_auto_inst(blocks, params, args.max_num_blocks, args.fill_with_fifos) -    else: -        vfile = open(args.auto_inst_src, 'r').read() -    file_generator(args, vfile) -    create_oot_include(args.device, args.include_dir) -    if args.outfile is  None: -        return build(args) -    else: -        print("Instantiation file generated at {}".\ -                format(args.outfile)) -        return 0 - -if __name__ == "__main__": -    exit(main()) diff --git a/fpga/usrp3/tools/scripts/uhd_image_builder_gui.py b/fpga/usrp3/tools/scripts/uhd_image_builder_gui.py deleted file mode 100755 index 4d14cd256..000000000 --- a/fpga/usrp3/tools/scripts/uhd_image_builder_gui.py +++ /dev/null @@ -1,656 +0,0 @@ -#!/usr/bin/env python -""" -Copyright 2016-2018 Ettus Research - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program.  If not, see <http://www.gnu.org/licenses/>. -""" - -from __future__ import print_function -import os -import re -import sys -import signal -import threading -import xml.etree.ElementTree as ET -from PyQt5 import (QtGui, -                   QtCore, -                   QtWidgets) -from PyQt5.QtWidgets import QGridLayout -from PyQt5.QtCore import (pyqtSlot, -                          Qt, -                          QModelIndex) -import uhd_image_builder - -signal.signal(signal.SIGINT, signal.SIG_DFL) - -class MainWindow(QtWidgets.QWidget): -    """ -    UHD_IMAGE_BUILDER -    """ -    # pylint: disable=too-many-instance-attributes - -    def __init__(self): -        super(MainWindow, self).__init__() -        ################################################## -        # Initial Values -        ################################################## -        self.target = 'x300' -        self.device = 'x310' -        self.build_target = 'X310_RFNOC_HG' -        self.oot_dirs = [] -        self.max_allowed_blocks = 10 -        self.cmd_dict = {"target": '-t {}'.format(self.build_target), -                         "device": '-d {}'.format(self.device), -                         "include": '', -                         "fill_fifos": '', -                         "viv_gui": '', -                         "cleanall": '', -                         "show_file": ''} -        self.cmd_name = ['./uhd_image_builder.py', ] -        self.cmd_prefix = list(self.cmd_name) -        self.instantiation_file = os.path.join(uhd_image_builder.get_scriptpath(), -                                               '..', '..', 'top', self.target, -                                               'rfnoc_ce_auto_inst_' + self.device.lower() + -                                               '.v') - -        # List of blocks that are part of our library but that do not take place -        # on the process this tool provides -        self.blacklist = ['noc_block_radio_core', 'noc_block_axi_dma_fifo', 'noc_block_pfb'] -        self.lock = threading.Lock() -        self.init_gui() - -    def init_gui(self): -        """ -        Initializes GUI init values and constants -        """ -        # pylint: disable=too-many-statements - -        ettus_sources = os.path.join(uhd_image_builder.get_scriptpath(), '..', '..', 'lib',\ -            'rfnoc', 'Makefile.srcs') -        ################################################## -        # Grid Layout -        ################################################## -        grid = QGridLayout() -        grid.setSpacing(15) -        ################################################## -        # Buttons -        ################################################## -        oot_btn = QtWidgets.QPushButton('Add OOT Blocks', self) -        oot_btn.setToolTip('Add your custom Out-of-tree blocks') -        grid.addWidget(oot_btn, 9, 0) -        from_grc_btn = QtWidgets.QPushButton('Import from GRC', self) -        grid.addWidget(from_grc_btn, 9, 2) -        show_file_btn = QtWidgets.QPushButton('Show instantiation File', self) -        grid.addWidget(show_file_btn, 9, 1) -        add_btn = QtWidgets.QPushButton('>>', self) -        grid.addWidget(add_btn, 2, 2) -        rem_btn = QtWidgets.QPushButton('<<', self) -        grid.addWidget(rem_btn, 3, 2) -        self.gen_bit_btn = QtWidgets.QPushButton('Generate .bit file', self) -        grid.addWidget(self.gen_bit_btn, 9, 3) - -        ################################################## -        # Checkbox -        ################################################## -        self.fill_with_fifos = QtWidgets.QCheckBox('Fill with FIFOs', self) -        self.viv_gui = QtWidgets.QCheckBox('Open Vivado GUI', self) -        self.cleanall = QtWidgets.QCheckBox('Clean IP', self) -        grid.addWidget(self.fill_with_fifos, 5, 2) -        grid.addWidget(self.viv_gui, 6, 2) -        grid.addWidget(self.cleanall, 7, 2) - -        ################################################## -        # uhd_image_builder command display -        ################################################## -        label_cmd_display = QtWidgets.QLabel(self) -        label_cmd_display.setText("uhd_image_builder command:") -        label_cmd_display.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter) -        label_cmd_display.setStyleSheet(" QLabel {font-weight: bold; color: black}") -        grid.addWidget(label_cmd_display, 10, 0) -        self.cmd_display = QtWidgets.QTextEdit(self) -        self.cmd_display.setMaximumHeight(label_cmd_display.sizeHint().height() * 3) -        self.cmd_display.setReadOnly(True) -        self.cmd_display.setText("".join(self.cmd_name)) -        grid.addWidget(self.cmd_display, 10, 1, 1, 3) - -        ################################################## -        # uhd_image_builder target help display -        ################################################## -        self.help_display = QtWidgets.QLabel(self) -        grid.addWidget(self.help_display, 11, 1, 1, 3) -        self.help_display.setWordWrap(True) -        help_description = QtWidgets.QLabel(self) -        grid.addWidget(help_description, 11, 0) -        help_description.setText("Target description: ") -        help_description.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter) -        help_description.setStyleSheet(" QLabel {font-weight: bold; color: black}") - -        ################################################## -        # Panels - QTreeModels -        ################################################## -        ### Far-left Panel: Build targets -        self.targets = QtWidgets.QTreeView(self) -        self.targets.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers) -        self.model_targets = QtGui.QStandardItemModel(self) -        self.model_targets.setHorizontalHeaderItem(0, QtGui.QStandardItem("Select build target")) -        self.targets.setModel(self.model_targets) -        self.populate_target('x300') -        self.populate_target('e300') -        self.populate_target('e320') -        self.populate_target('n3xx') -        grid.addWidget(self.targets, 0, 0, 8, 1) - -        ### Central Panel: Available blocks -        ### Create tree to categorize Ettus Block and OOT Blocks in different lists -        self.blocks_available = QtWidgets.QTreeView(self) -        self.blocks_available.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers) -        self.blocks_available.setContextMenuPolicy(Qt.CustomContextMenu) -        ettus_blocks = QtGui.QStandardItem("Ettus-provided Blocks") -        ettus_blocks.setEnabled(False) -        ettus_blocks.setForeground(Qt.black) -        self.populate_list(ettus_blocks, ettus_sources) -        self.oot = QtGui.QStandardItem("OOT Blocks for X300 devices") -        self.oot.setEnabled(False) -        self.oot.setForeground(Qt.black) -        self.refresh_oot_dirs() -        self.model_blocks_available = QtGui.QStandardItemModel(self) -        self.model_blocks_available.appendRow(ettus_blocks) -        self.model_blocks_available.appendRow(self.oot) -        self.model_blocks_available.setHorizontalHeaderItem( -            0, QtGui.QStandardItem("List of blocks available") -            ) -        self.blocks_available.setSelectionMode(QtWidgets.QAbstractItemView.ExtendedSelection) -        self.blocks_available.setModel(self.model_blocks_available) -        grid.addWidget(self.blocks_available, 0, 1, 8, 1) - -        ### Far-right Panel: Blocks in current design -        self.blocks_in_design = QtWidgets.QTreeView(self) -        self.blocks_in_design.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers) -        self.model_in_design = QtGui.QStandardItemModel(self) -        self.model_in_design.setHorizontalHeaderItem( -            0, QtGui.QStandardItem("Blocks in current design")) -        self.blocks_in_design.setSelectionMode(QtWidgets.QAbstractItemView.ExtendedSelection) -        self.blocks_in_design.setModel(self.model_in_design) -        grid.addWidget(self.blocks_in_design, 0, 3, 8, 1) - -        ################################################## -        # Informative Labels -        ################################################## -        block_num_hdr = QtWidgets.QLabel(self) -        block_num_hdr.setText("Blocks in current design") -        block_num_hdr.setStyleSheet(" QLabel {font-weight: bold; color: black}") -        block_num_hdr.setAlignment(QtCore.Qt.AlignHCenter) -        grid.addWidget(block_num_hdr, 0, 2) -        self.block_num = QtWidgets.QLabel(self) -        self.block_num.setText("-") -        self.block_num.setAlignment(QtCore.Qt.AlignHCenter) -        grid.addWidget(self.block_num, 1, 2) -        self.block_num.setStyleSheet(" QLabel {color: green}") -        self.generating_bitstream = QtWidgets.QLabel(self) -        self.generating_bitstream.setText("") -        self.generating_bitstream.setAlignment(QtCore.Qt.AlignHCenter) -        grid.addWidget(self.generating_bitstream, 11, 0, 1, 5) -        self.generating_bitstream.setStyleSheet(" QLabel {font-weight: bold; color: black}") - -        ################################################## -        # Connection of the buttons with their signals -        ################################################## -        self.fill_with_fifos.clicked.connect(self.fill_slot) -        self.fill_with_fifos.clicked.connect(self.cmd_display_slot) -        self.viv_gui.clicked.connect(self.viv_gui_slot) -        self.viv_gui.clicked.connect(self.cmd_display_slot) -        self.cleanall.clicked.connect(self.cleanall_slot) -        self.cleanall.clicked.connect(self.cmd_display_slot) -        oot_btn.clicked.connect(self.file_dialog) -        from_grc_btn.clicked.connect(self.blocks_to_add_slot) -        from_grc_btn.clicked.connect(self.cmd_display_slot) -        from_grc_btn.clicked.connect(self.file_grc_dialog) -        add_btn.clicked.connect(self.add_to_design) -        add_btn.clicked.connect(self.blocks_to_add_slot) -        add_btn.clicked.connect(self.check_blk_num) -        add_btn.clicked.connect(self.cmd_display_slot) -        rem_btn.clicked.connect(self.remove_from_design) -        rem_btn.clicked.connect(self.blocks_to_add_slot) -        rem_btn.clicked.connect(self.cmd_display_slot) -        show_file_btn.clicked.connect(self.show_file) -        show_file_btn.clicked.connect(self.cmd_display_slot) -        show_file_btn.clicked.connect(self.run_command) -        self.gen_bit_btn.clicked.connect(self.generate_bit) -        self.gen_bit_btn.clicked.connect(self.cmd_display_slot) -        self.gen_bit_btn.clicked.connect(self.run_command) -        self.targets.clicked.connect(self.ootlist) -        self.targets.clicked.connect(self.set_target_and_device) -        self.targets.clicked.connect(self.cmd_display_slot) -        self.targets.clicked.connect(self.check_blk_num) -        self.blocks_available.doubleClicked.connect(self.add_to_design) -        self.blocks_available.doubleClicked.connect(self.blocks_to_add_slot) -        self.blocks_available.doubleClicked.connect(self.check_blk_num) -        self.blocks_available.doubleClicked.connect(self.cmd_display_slot) -        self.blocks_in_design.doubleClicked.connect(self.remove_from_design) -        self.blocks_in_design.doubleClicked.connect(self.blocks_to_add_slot) -        self.blocks_in_design.doubleClicked.connect(self.cmd_display_slot) - -        ################################################## -        # Set a default size based on screen geometry -        ################################################## -        screen_size = QtWidgets.QDesktopWidget().screenGeometry(-1) -        self.resize(screen_size.width()/1.4, screen_size.height()/1.7) -        self.setWindowTitle("uhd_image_builder.py GUI") -        self.setLayout(grid) -        self.show() - -    ################################################## -    # Slots and functions/actions -    ################################################## -    @pyqtSlot() -    def blocks_to_add_slot(self): -        """ -        Retrieves a list of the blocks in design to be displayed in TextEdit -        """ -        availables = [] -        blocks = [] -        availables = self.iter_tree(self.model_blocks_available, availables) -        blk_count = self.model_in_design.rowCount() -        self.block_num.setText("{}/{}".format(blk_count, -                                              self.max_allowed_blocks)) -        for i in range(blk_count): -            blocks.append(self.blocks_in_design.model().data( -                self.blocks_in_design.model().index(i, 0))) -        self.cmd_prefix = self.cmd_name + blocks - -    @pyqtSlot() -    def check_blk_num(self): -        """ -        Checks the amount of blocks in the design pannel -        """ -        blk_count = self.model_in_design.rowCount() -        if blk_count > self.max_allowed_blocks: -            self.block_num.setStyleSheet(" QLabel {font-weight:bold; color: red}") -            self.show_too_many_blocks_warning(blk_count) - -    @pyqtSlot() -    def fill_slot(self): -        """ -        Populates 'fill_fifos' value into the command dictionary -        """ -        if self.fill_with_fifos.isChecked(): -            self.cmd_dict["fill_fifos"] = '--fill-with-fifos' -        else: -            self.cmd_dict["fill_fifos"] = '' - -    @pyqtSlot() -    def viv_gui_slot(self): -        """ -        Populates 'viv_gui' value into the command dictionary -        """ -        if self.viv_gui.isChecked(): -            self.cmd_dict["viv_gui"] = '-g' -        else: -            self.cmd_dict["viv_gui"] = '' - -    @pyqtSlot() -    def cleanall_slot(self): -        """ -        Populates 'cleanall' value into the command dictionary -        """ -        if self.cleanall.isChecked(): -            self.cmd_dict["cleanall"] = '-c' -        else: -            self.cmd_dict["cleanall"] = '' - -    @pyqtSlot() -    def cmd_display_slot(self): -        """ -        Displays the command to be run in a QTextEdit in realtime -        """ -        text = [" ".join(self.cmd_prefix),] -        for value in self.cmd_dict.values(): -            if value is not '': -                text.append(value) -        self.cmd_display.setText(" ".join(text)) - -    @pyqtSlot() -    def add_to_design(self): -        """ -        Adds blocks from the 'available' pannel to the list to be added -        into the design -        """ -        indexes = self.blocks_available.selectedIndexes() -        for index in indexes: -            word = self.blocks_available.model().data(index) -            element = QtGui.QStandardItem(word) -            if word is not None: -                self.model_in_design.appendRow(element) - -    @pyqtSlot() -    def remove_from_design(self): -        """ -        Removes blocks from the list that is to be added into the design -        """ -        indexes = self.blocks_in_design.selectedIndexes() -        for index in indexes: -            self.model_in_design.removeRow(index.row()) -        # Edit Informative Label formatting -        blk_count = self.model_in_design.rowCount() -        if blk_count <= self.max_allowed_blocks: -            self.block_num.setStyleSheet(" QLabel {color: green}") - -    @pyqtSlot() -    def show_file(self): -        """ -        Show the rfnoc_ce_auto_inst file in the default text editor -        """ -        self.cmd_dict['show_file'] = '-o {}'.format(self.instantiation_file) - -    @pyqtSlot() -    def generate_bit(self): -        """ -        Runs the FPGA .bit generation command -        """ -        self.cmd_dict['show_file'] = '' - -    @pyqtSlot() -    def run_command(self): -        """ -        Executes the uhd_image_builder command based on user options -        """ -        if self.check_no_blocks() and self.check_blk_not_in_sources(): -            process = threading.Thread(target=self.generate_bitstream) -            process.start() -            if self.cmd_dict['show_file'] is not '': -                os.system("xdg-open " + self.instantiation_file) - -    @pyqtSlot() -    def set_target_and_device(self): -        """ -        Populates the 'target' and 'device' values of the command directory -        and the device dependent max_allowed_blocks in display -        """ -        self.cmd_dict['target'] = '-t {}'.format(self.build_target) -        self.cmd_dict['device'] = '-d {}'.format(self.device) -        blk_count = self.model_in_design.rowCount() -        self.block_num.setText("{}/{}".format(blk_count, -                                              self.max_allowed_blocks)) -        self.instantiation_file = os.path.join(uhd_image_builder.get_scriptpath(), -                                               '..', '..', 'top', self.target, -                                               'rfnoc_ce_auto_inst_' + self.device.lower() + -                                               '.v') - -    @pyqtSlot() -    def ootlist(self): -        """ -        Lists the Out-of-tree module blocks -        """ -        index = self.targets.currentIndex() -        self.build_target = str(self.targets.model().data(index)) -        self.device = self.build_target[:4] -        if self.device == 'X310' or self.device == 'X300': -            self.target = 'x300' -            self.max_allowed_blocks = 10 -        elif self.device == 'E310': -            self.target = 'e300' -            self.max_allowed_blocks = 14 -        elif self.device == 'E320': -            self.target = 'e320' -            self.max_allowed_blocks = 12 -        elif self.device == 'N300': -            self.target = 'n3xx' -            self.max_allowed_blocks = 11 -        elif self.device == 'N310' or self.device == 'N320': -            self.target = 'n3xx' -            self.max_allowed_blocks = 10 -        oot_sources = os.path.join(uhd_image_builder.get_scriptpath(), '..', '..', 'top',\ -            self.target, 'Makefile.srcs') -        self.show_list(self.oot, self.target, oot_sources) - -        # Show the help string for a selected target -        selected_makefile = os.path.join(uhd_image_builder.get_scriptpath(), -                                         '..', '..', 'top', self.target, 'Makefile') -        pattern = "^\#\S*{}.*".format(self.build_target) -        with open(selected_makefile) as fil: -            help_string = re.findall(pattern, fil.read(), re.MULTILINE)[0].replace("##","") -            self.help_display.setText(help_string) - -    @pyqtSlot() -    def file_dialog(self): -        """ -        Opens a dialog window to add manually the Out-of-tree module blocks -        """ -        append_directory = [] -        startpath = os.path.join(uhd_image_builder.get_scriptpath(), '..', '..', '..', '..') -        new_oot = str(QtWidgets.QFileDialog.getExistingDirectory(self, 'RFNoC Out of Tree Directory', startpath)) -        if len(new_oot) > 0: -            self.oot_dirs.append(new_oot) -            uhd_image_builder.create_oot_include(self.device, self.oot_dirs) -            self.refresh_oot_dirs() - -    @pyqtSlot() -    def file_grc_dialog(self): -        """ -        Opens a dialog window to add manually the GRC description file, from where -        the RFNoC blocks will be parsed and added directly into the "Design" pannel -        """ -        filename = QtWidgets.QFileDialog.getOpenFileName(self, 'Open File', '/home/')[0] -        if len(filename) > 0: -            self.grc_populate_list(self.model_in_design, filename) -            self.set_target_and_device() -            self.blocks_to_add_slot() -            self.cmd_display_slot() - -    def check_no_blocks(self): -        """ -        Checks if there are no blocks in the design pannel. Needs to be a -        different slot because triggers from clicking signals from pannels -        would be superfluous -        """ -        blk_count = self.model_in_design.rowCount() -        if blk_count == 0: -            self.show_no_blocks_warning() -            return False -        return True - -    def show_no_srcs_warning(self, block_to_add): -        """ -        Shows a warning message window when no sources are found for the blocks that -        are in the design pannel -        """ -        # Create Warning message window -        msg = QtWidgets.QMessageBox() -        msg.setIcon(QtWidgets.QMessageBox.Warning) -        msg.setText("The following blocks are in your design but their sources"\ -            " have not been added: \n\n {0}. \n\nPlease be sure of adding them"\ -            "before continuing. Would you like to add them now?"\ -            "".format(block_to_add)) -        msg.setWindowTitle("No sources for design") -        yes_btn = msg.addButton("Yes", QtWidgets.QMessageBox.YesRole) -        no_btn = msg.addButton("No", QtWidgets.QMessageBox.NoRole) -        msg.exec_() -        if msg.clickedButton() == yes_btn: -            self.file_dialog() -            return False -        elif msg.clickedButton() == no_btn: -            return True - -    @staticmethod -    def show_no_blocks_warning(): -        """ -        Shows a warning message window when no blocks are found in the 'design' pannel -        """ -        # Create Warning message window -        msg = QtWidgets.QMessageBox() -        msg.setIcon(QtWidgets.QMessageBox.Warning) -        msg.setText("There are no Blocks in the current design") -        msg.exec_() - -    def show_too_many_blocks_warning(self, number_of_blocks): -        """ -        Shows a warning message window when too many blocks are found in the 'design' pannel -        """ -        # Create Warning message window -        msg = QtWidgets.QMessageBox() -        msg.setIcon(QtWidgets.QMessageBox.Warning) -        msg.setText("You added {} blocks while the maximum allowed blocks for"\ -                " a {} device is {}. Please remove some of the blocks to "\ -                "continue with the design".format(number_of_blocks, -                                                  self.device, self.max_allowed_blocks)) -        msg.exec_() - -    def iter_tree(self, model, output, parent=QModelIndex()): -        """ -        Iterates over the Index tree -        """ -        for i in range(model.rowCount(parent)): -            index = model.index(i, 0, parent) -            item = model.data(index) -            output.append(str(item)) -            if model.hasChildren(index): -                self.iter_tree(model, output, index) -        return output - -    def show_list(self, parent, target, files): -        """ -        Shows the Out-of-tree blocks that are available for a given device -        """ -        parent.setText('OOT Blocks for {} devices'.format(target.upper())) -        self.refresh_oot_dirs() - -    def populate_list(self, parent, files, clear=True): -        """ -        Populates the pannels with the blocks that are listed in the Makefile.srcs -        of our library -        """ -        # Clean the list before populating it again -        if (clear): -            parent.removeRows(0, parent.rowCount()) -        suffix = '.v \\\n' -        with open(files) as fil: -            blocks = fil.readlines() -        for element in blocks: -            if element.endswith(suffix) and 'noc_block' in element: -                element = element[:-len(suffix)] -                if element not in self.blacklist: -                    block = QtGui.QStandardItem(element.partition('noc_block_')[2]) -                    parent.appendRow(block) - -    @staticmethod -    def show_not_xml_warning(): -        """ -        Shows a warning message window when no blocks are found in the 'design' pannel -        """ -        # Create Warning message window -        msg = QtWidgets.QMessageBox() -        msg.setIcon(QtWidgets.QMessageBox.Warning) -        msg.setText("[ParseError]: The chosen file is not XML formatted") -        msg.exec_() - -    def grc_populate_list(self, parent, files): -        """ -        Populates the 'Design' list with the RFNoC blocks found in a GRC file -        """ -        try: -            tree = ET.parse(files) -            root = tree.getroot() -            for blocks in root.iter('block'): -                for param in blocks.iter('param'): -                    for key in param.iter('key'): -                        if 'fpga_module_name' in key.text: -                            if param.findtext('value') in self.blacklist: -                                continue -                            block = QtGui.QStandardItem(param.findtext('value').\ -                                    partition('noc_block_')[2]) -                            parent.appendRow(block) -        except ET.ParseError: -            self.show_not_xml_warning() -            return - -    def refresh_oot_dirs(self): -        """ -        Populates the OOT directory list from the OOT include file -        """ -        oot_include = os.path.join(uhd_image_builder.get_scriptpath(), '..', '..', 'top',\ -            self.target, 'Makefile.OOT.inc') -        dir_list = [] -        with open(oot_include, 'r') as fil: -            text = fil.readlines() -            for lines in text: -                lines = lines.partition('$(BASE_DIR)/') -                if (lines[1] == '$(BASE_DIR)/'): -                    relpath = lines[2].replace('\n', '') -                    ootpath = os.path.abspath(os.path.join(uhd_image_builder.get_scriptpath(), '..', '..', 'top', relpath)) -                    dir_list.append(ootpath) -        if (len(dir_list) == 0): -            self.oot.removeRows(0, self.oot.rowCount()) -            self.cmd_dict["include"] = '' -        else: -            self.oot_dirs = dir_list -            self.cmd_dict["include"] = '-I {}'.format(' '.join(self.oot_dirs)) -        for (ii, oot) in enumerate(dir_list): -            self.populate_list(self.oot, os.path.join(oot, 'fpga-src', 'Makefile.srcs'), clear=ii==0) - -    def populate_target(self, selected_target): -        """ -        Parses the Makefile available and lists the build targets into the left pannel -        """ -        pattern = "^(?!\#)^\S*_RFNOC[^:]*" -        build_targets = os.path.join(uhd_image_builder.get_scriptpath(), '..', '..', 'top', -                                     selected_target, 'Makefile') -        with open(build_targets) as fil: -            targets = re.findall(pattern, fil.read(), re.MULTILINE) -            for target in targets: -                self.model_targets.appendRow(QtGui.QStandardItem(target)) - -    def check_blk_not_in_sources(self): -        """ -        Checks if a block added from GRC flowgraph is not yet in the sources -        list -        """ -        availables = [] -        notin = [] -        availables = self.iter_tree(self.model_blocks_available, availables) -        for i in range(self.model_in_design.rowCount()): -            block_to_add = self.blocks_in_design.model().data( -                self.blocks_in_design.model().index(i, 0)) -            if str(block_to_add) not in availables: -                notin.append(str(block_to_add)) -        if len(notin) > 0: -            self.show_no_srcs_warning(notin) -            return False -        return True - -    def generate_bitstream(self): -        """ -        Runs the bitstream generation command in a separate thread -        """ -        self.lock.acquire() -        self.gen_bit_btn.setEnabled(False) -        command = self.cmd_display.toPlainText() -        self.generating_bitstream.setText( -            "[Generating BitStream]: The FPGA is currently being generated" + \ -            " with the blocks of the current design. See the terminal window" + \ -            " for further compilation details") -        os.system(command) -        self.lock.release() -        self.gen_bit_btn.setEnabled(True) -        self.generating_bitstream.setText("") - -def main(): -    """ -    Main GUI method -    """ -    app = QtWidgets.QApplication(sys.argv) -    _window = MainWindow() -    sys.exit(app.exec_()) - -if __name__ == '__main__': -    main() | 
