aboutsummaryrefslogtreecommitdiffstats
path: root/host/utils/bin/rfnoc_image_builder
diff options
context:
space:
mode:
Diffstat (limited to 'host/utils/bin/rfnoc_image_builder')
-rwxr-xr-xhost/utils/bin/rfnoc_image_builder194
1 files changed, 194 insertions, 0 deletions
diff --git a/host/utils/bin/rfnoc_image_builder b/host/utils/bin/rfnoc_image_builder
new file mode 100755
index 000000000..0df0d5d3c
--- /dev/null
+++ b/host/utils/bin/rfnoc_image_builder
@@ -0,0 +1,194 @@
+#!/usr/bin/env python
+"""
+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 sys
+import argparse
+import hashlib
+import logging
+import os
+import re
+import yaml
+
+logging.basicConfig(format='[%(levelname).3s] %(message)s')
+# CMAKE will dump final site-package folder into this to allow the script find
+# its package folder
+sys.path.insert(0, "@RFNOC_PACKAGE_DIR@")
+#pylint : disable = wrong - import - position
+import rfnoc.image_builder
+import rfnoc.yaml_utils
+
+
+def setup_parser():
+ """
+ Create argument parser
+ """
+ parser = argparse.ArgumentParser(
+ description="Build UHD image using RFNoC blocks",
+ )
+
+ config_group = parser.add_mutually_exclusive_group(required=True)
+ config_group.add_argument(
+ "-y", "--yaml_config",
+ help="Path to yml configuration file")
+ config_group.add_argument(
+ "-r", "--grc_config",
+ help="Path to grc file to generate config from")
+
+ parser.add_argument(
+ "-F", "--fpga-dir",
+ help="Path directory of the FPGA source tree",
+ required=True,
+ default=None)
+ parser.add_argument(
+ "-o", "--image-core-output",
+ help="Path to where to save the image core Verilog source. "
+ "Defaults to the location of the YAML file.")
+ parser.add_argument(
+ "-x", "--router-hex-output",
+ help="Path to where to save the static router hex file. "
+ "Defaults to the location of the YAML file, filename $device_static_router.hex",
+ default=None)
+
+ parser.add_argument(
+ "-I", "--include-dir",
+ help="Path directory of the RFNoC Out-of-Tree module",
+ nargs='+',
+ default=None)
+
+ parser.add_argument(
+ "-b", "--grc-blocks",
+ help="Path directory of GRC block descriptions (needed for --grc-config only)",
+ default=None)
+ parser.add_argument(
+ "-l", "--log-level",
+ help="Adjust log level",
+ default='info')
+ parser.add_argument(
+ "--generate-only",
+ help="Just generate files without building IP",
+ action="store_true")
+ 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 (e.g. X310_HG, N320_XG, ...)",
+ 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")
+
+ return parser
+
+
+def image_config(args):
+ """
+ Load image configuration.
+
+ The configuration can be either passed as RFNoC image configuration or as
+ GNU Radio Companion grc. In latter case the grc files is converted into a
+ RFNoC image configuration on the fly.
+ :param args: arguments passed to the script.
+ :return: image configuration as dictionary
+ """
+ if args.yaml_config:
+ return rfnoc.yaml_utils.load_config(args.yaml_config, get_config_path()), \
+ args.yaml_config
+
+ with open(args.grc_config) as grc_file:
+ config = yaml.load(grc_file)
+ logging.info("Converting GNU Radio Companion file to image builder format")
+ config = rfnoc.image_builder.convert_to_image_config(config, args.grc_blocks)
+ return config, args.grc_config
+
+
+def resolve_path(path, local):
+ """
+ Replaced path by local if path is enclosed with "@" (placeholder markers)
+ :param path: the path to check
+ :param local: new path content if path is placeholder
+ :return: path if path is not a placeholder else local
+ """
+ return re.sub("^@.*@$", local, path)
+
+
+def get_fpga_path(args):
+ """
+ Returns FPGA path. This is the fpga_dir of arguments, If fpga_dir does
+ not exists it is the predefined path of of the script.
+ :param args: arguments passed to the script
+ :return: FPGA root path
+ """
+ result = args.fpga_dir
+ if not os.path.isdir(result):
+ logging.info("%s is not a valid directory.", result)
+ result = resolve_path("@FPGA_PATH@", os.path.join(
+ os.path.dirname(__file__), '..', '..', '..', 'fpga-src'))
+ logging.info("Fall back to %s", result)
+ return result
+
+
+def get_config_path():
+ """
+ Returns path that contains configurations files (yml descriptions for
+ block, IO signatures and device bsp).
+ :return: Configuration path
+ """
+ return os.path.normpath(resolve_path("@CONFIG_PATH@", os.path.join(
+ os.path.dirname(__file__), '..', '..', 'include', 'uhd')))
+
+
+def main():
+ """
+ Wrapper for rfnoc.image_builder.build_image.
+ :return: exit code
+ """
+ args = setup_parser().parse_args()
+ if args.log_level is not None:
+ logging.root.setLevel(args.log_level.upper())
+
+ config, source = image_config(args)
+ source_hash = hashlib.sha256()
+ with open(source, "rb") as source_file:
+ source_hash.update(source_file.read())
+
+ rfnoc.image_builder.build_image(
+ config=config,
+ fpga_path=args.fpga_dir,
+ config_path=get_config_path(),
+ device=args.device,
+ target=args.target,
+ generate_only=args.generate_only,
+ clean_all=args.clean_all,
+ gui=args.GUI,
+ source=source,
+ source_hash=source_hash.hexdigest(),
+ output_path=args.image_core_output,
+ router_hex_path=args.router_hex_output,
+ )
+
+if __name__ == "__main__":
+ exit(main())