aboutsummaryrefslogtreecommitdiffstats
path: root/fpga/usrp3/build.py
diff options
context:
space:
mode:
Diffstat (limited to 'fpga/usrp3/build.py')
-rwxr-xr-xfpga/usrp3/build.py170
1 files changed, 170 insertions, 0 deletions
diff --git a/fpga/usrp3/build.py b/fpga/usrp3/build.py
new file mode 100755
index 000000000..41cb855fe
--- /dev/null
+++ b/fpga/usrp3/build.py
@@ -0,0 +1,170 @@
+#!/usr/bin/env python
+#
+# Copyright 2016 Ettus Research LLC
+#
+
+import argparse
+import os
+import subprocess
+import logging
+import re
+import json
+
+_LIB_DIR = os.path.join("lib")
+_RFNOC_DIR = os.path.join("lib", "rfnoc")
+_SIM_DIR = os.path.join("lib", "sim")
+_BASE_DIR = os.path.dirname(os.path.realpath(__file__))
+
+_SEARCH_BASE = [_RFNOC_DIR, _SIM_DIR]
+_LOG = logging.getLogger(os.path.basename(__file__))
+_LOG.setLevel(logging.INFO)
+_STDOUT = logging.StreamHandler()
+_LOG.addHandler(_STDOUT)
+_FORMATTER = logging.Formatter('[%(name)s] - %(levelname)s - %(message)s')
+_STDOUT.setFormatter(_FORMATTER)
+
+
+def match_file(expr, path):
+ """ Match regex expr on all lines of path and return list of matches """
+ matches = []
+ with open(path, 'rb') as my_file:
+ for line in my_file:
+ match = expr.match(line)
+ if match:
+ matches.append(match)
+ return matches
+
+
+def create_index(paths):
+ """ Create an index of modules in .v/.vhd and dump it to modules.json """
+ hdl_expressions = {
+ re.compile(r".*\.v$"):
+ re.compile(b"module (?P<mod_name>[\\w]+) *$", re.IGNORECASE),
+ re.compile(r".*\.vhd$"):
+ re.compile(b"entity (?P<mod_name>[\\w]+) is *$", re.IGNORECASE)
+ }
+ ignore_dirs = ["build-ip", "sim"]
+
+ modules = {}
+ for path in paths:
+ for root, dirs, files in os.walk(os.path.join(_BASE_DIR, path)):
+ ignore = [my_dir in dirs for my_dir in ignore_dirs]
+ if any(ignore):
+ for index, ignore_me in enumerate(ignore):
+ if not ignore_me:
+ continue
+ dirs.pop(dirs.index(ignore_dirs[index]))
+ for my_file in files:
+ matches = []
+ for key, value in hdl_expressions.items():
+ if key.match(my_file):
+ matches = match_file(value,
+ os.path.join(root, my_file))
+ break
+
+ for match in matches:
+ if match.group("mod_name") in modules:
+ _LOG.error("%s is already in modules",
+ match.group("mod_name"))
+ _LOG.error("Old Path: %s",
+ modules[match.group("mod_name")])
+ _LOG.error("New Path: %s", os.path.join(root, my_file))
+ else:
+ modules.update({
+ match.group("mod_name").decode('utf-8'):
+ os.path.join(root, my_file)
+ })
+ with open("modules.json", "w") as my_file:
+ json.dump(
+ modules, my_file, sort_keys=True, indent=4, separators=(',', ': '))
+
+
+def call_xsim(path):
+ """ Call make xsim with default environment at path """
+ os.chdir(os.path.join(_BASE_DIR, path))
+ env = os.environ
+ env["REPO_BASE_PATH"] = _BASE_DIR
+ env["DISPLAY_NAME"] = "USRP-XSIM"
+ env["VIVADO_VER"] = "2017.4"
+ env["PRODUCT_ID_MAP"] = "foo/foo/bar/bar"
+ setup_env = os.path.join(_BASE_DIR, "tools", "scripts", "setupenv_base.sh")
+ result = subprocess.Popen(
+ ". {setup}; make xsim".format(setup=setup_env), env=env,
+ shell=True).wait()
+ return result
+
+
+def find_xsims():
+ """ Find testbenches in lib/sim (dirs with Makefile) """
+ sims = {}
+ for basedir in _SEARCH_BASE:
+ for root, _, files in os.walk(os.path.join(_BASE_DIR, basedir)):
+ if "Makefile" in files:
+ sims.update({os.path.basename(root): root})
+ return sims
+
+
+def run_xsim(args):
+ """ Run xsim for all specified modules """
+ sims = find_xsims()
+ result_all = 0
+ if not isinstance(args.target, list):
+ args.target = [args.target]
+ if "cleanall" in args.target:
+ env = os.environ
+ env["REPO_BASE_PATH"] = _BASE_DIR
+ for name, path in sims.iteritems():
+ _LOG.info("Cleaning %s", name)
+ os.chdir(os.path.join(_BASE_DIR, path))
+ subprocess.Popen("make cleanall", env=env, shell=True).wait()
+ elif "all" in args.target:
+ for name, path in sims.iteritems():
+ _LOG.info("Running %s xsim", name)
+ result = call_xsim(path)
+ if result:
+ result_all = result
+ else:
+ for target in args.target:
+ _LOG.info("Running %s xsim", target)
+ result = call_xsim(sims[target])
+ if result:
+ result_all = result
+ return result_all
+
+
+def parse_args():
+ """ Parse cmdline arguments"""
+ test_benches = find_xsims()
+ parser = argparse.ArgumentParser()
+ subparser = parser.add_subparsers(dest="command", metavar="")
+ xsim_parser = subparser.add_parser(
+ "xsim", help="Run available testbenches")
+ xsim_parser.add_argument(
+ "target",
+ nargs="+",
+ choices=list(test_benches.keys()) + ["all", "cleanall"],
+ help="Space separated simulation target(s) or all. Available targets: "
+ + ", ".join(list(test_benches.keys()) + ["all", "cleanall"]),
+ metavar="")
+ index_parser = subparser.add_parser(
+ "index", help="Index available HDL modules")
+ index_parser.add_argument(
+ "create",
+ help="Create a modules.json of available HDL modules in lib/")
+ return parser.parse_args()
+
+
+def main():
+ """Main logic"""
+ args = parse_args()
+ result = 0
+ if args.command == "xsim":
+ result = run_xsim(args)
+ elif args.command == "index":
+ create_index([_LIB_DIR])
+
+ return result
+
+
+if __name__ == "__main__":
+ exit(not main())