aboutsummaryrefslogtreecommitdiffstats
path: root/fpga/usrp3/top/x400/tools
diff options
context:
space:
mode:
authorWade Fife <wade.fife@ettus.com>2021-06-08 19:40:46 -0500
committerAaron Rossetto <aaron.rossetto@ni.com>2021-06-10 11:56:58 -0500
commit6d3765605262016a80f71e36357f749ea35cbe5a (patch)
tree7d62d6622befd4132ac1ee085effa1426f7f53e5 /fpga/usrp3/top/x400/tools
parentf706b89e6974e28ce76aadeeb06169becc86acba (diff)
downloaduhd-6d3765605262016a80f71e36357f749ea35cbe5a.tar.gz
uhd-6d3765605262016a80f71e36357f749ea35cbe5a.tar.bz2
uhd-6d3765605262016a80f71e36357f749ea35cbe5a.zip
fpga: x400: Add support for X410 motherboard FPGA
Co-authored-by: Andrew Moch <Andrew.Moch@ni.com> Co-authored-by: Daniel Jepson <daniel.jepson@ni.com> Co-authored-by: Javier Valenzuela <javier.valenzuela@ni.com> Co-authored-by: Joerg Hofrichter <joerg.hofrichter@ni.com> Co-authored-by: Kumaran Subramoniam <kumaran.subramoniam@ni.com> Co-authored-by: Max Köhler <max.koehler@ni.com> Co-authored-by: Michael Auchter <michael.auchter@ni.com> Co-authored-by: Paul Butler <paul.butler@ni.com> Co-authored-by: Wade Fife <wade.fife@ettus.com> Co-authored-by: Hector Rubio <hrubio@ni.com>
Diffstat (limited to 'fpga/usrp3/top/x400/tools')
-rw-r--r--fpga/usrp3/top/x400/tools/get_dts_input.py58
-rwxr-xr-xfpga/usrp3/top/x400/tools/parse_versions_for_dts.py153
2 files changed, 211 insertions, 0 deletions
diff --git a/fpga/usrp3/top/x400/tools/get_dts_input.py b/fpga/usrp3/top/x400/tools/get_dts_input.py
new file mode 100644
index 000000000..caa731fc7
--- /dev/null
+++ b/fpga/usrp3/top/x400/tools/get_dts_input.py
@@ -0,0 +1,58 @@
+#!/usr/bin/env python3
+#
+# Copyright 2021 Ettus Research, a National Instruments Brand
+#
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+"""
+This script parses the target DTS file name and determines which DTS input
+file to use as the source, then the DTS source file name to stdout. For
+example, if the target is:
+
+ build/usrp_x410_fpga_XG_100.dts
+
+then it will print the input DTS file name (replacing the directory and
+removing the _100):
+
+ dts/usrp_x410_fpga_XG.dts
+
+Note: This code assumes it's being run from the top x400 directory, because it
+ will always add dts/ input file path.
+
+usage: get_dts_input.py [-h] --target INPUT
+
+Arguments:
+
+ -h, --help Show this help message and exit
+ --target TARGET The target file name (e.g., build/usrp_x410_fpga_X4_200.dts)
+
+"""
+import argparse
+import os
+import sys
+
+def parse_args():
+ """Parser for the command line arguments"""
+ parser = argparse.ArgumentParser(description='Get input DTS path from target DTS path')
+ parser.add_argument('--target', required=True, help='The name of the target DTS file')
+ args = parser.parse_args()
+ return args
+
+def get_input(target):
+ # Remove the path from the beginning
+ dts_input = os.path.basename(target)
+ # Remove the _XXX and extension from the end of the file name
+ dts_input = "_".join(dts_input.split("_")[:-1])
+ # Add path and extension
+ dts_input = os.path.join('dts', dts_input + '.dts')
+ return dts_input
+
+def main():
+ """ main function """
+ args = parse_args()
+ dts_input = get_input(args.target)
+ print(dts_input)
+ return True
+
+if __name__ == '__main__':
+ sys.exit(not main())
diff --git a/fpga/usrp3/top/x400/tools/parse_versions_for_dts.py b/fpga/usrp3/top/x400/tools/parse_versions_for_dts.py
new file mode 100755
index 000000000..bf44611d9
--- /dev/null
+++ b/fpga/usrp3/top/x400/tools/parse_versions_for_dts.py
@@ -0,0 +1,153 @@
+#!/usr/bin/env python3
+#
+# Copyright 2021 Ettus Research, a National Instruments Brand
+#
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+
+"""
+This script parses versioning information from a Verilog file and generates a
+devicetree include file (.dtsi) that follows the syntax that is required by MPM
+for version checking.
+
+usage: parse-versions-for-dts.py [-h] --input INPUT --output OUTPUT
+ --components COMPONENTS
+
+Arguments:
+
+ -h, --help show this help message and exit
+ --input INPUT The input file(s) to parse. A comma separated list can
+ be used to specify multiple files
+ --output OUTPUT The output file
+ --components COMPONENTS
+ The components for which the version information is
+ extracted. A comma separated list can be used to
+ specify multiple components.
+
+Example call:
+
+./parse-versions-for-dts.py \
+ --input regmap/global_regs_regmap_utils.vh \
+ --output build/component_versions.dtsi \
+ --components fpga
+
+Example for variable definitions in a Verilog file
+(regmap/global_regs_regmap_utils.vh):
+
+ localparam FPGA_CURRENT_VERSION_MAJOR = 'h4;
+ localparam FPGA_CURRENT_VERSION_MINOR = 'h2;
+ localparam FPGA_CURRENT_VERSION_BUILD = 'h18;
+ localparam FPGA_OLDEST_COMPATIBLE_VERSION_MAJOR = 'h4;
+ localparam FPGA_OLDEST_COMPATIBLE_VERSION_MINOR = 'h0;
+ localparam FPGA_OLDEST_COMPATIBLE_VERSION_BUILD = 'h0;
+ localparam FPGA_VERSION_LAST_MODIFIED_TIME = 'h20111013;
+
+Example for the generated dtsi include file (build/component_versions.dtsi)
+
+ // mpm_version fpga_current_version 4.2.24
+ // mpm_version fpga_oldest_compatible_version 4.0.0
+ // mpm_version fpga_version_last_modified_time 0x20111013
+"""
+import argparse
+import re
+import sys
+
+def parse_args():
+ """Parser for the command line arguments"""
+ parser = argparse.ArgumentParser(description='Parse variables from Verilog files')
+ parser.add_argument('--input', required=True,
+ help='The input file(s) to parse. A comma separated ' \
+ 'list can be used to specify multiple files')
+ parser.add_argument('--output', required=True, help='The output file')
+ parser.add_argument('--components', required=True,
+ help='The components for which the version information ' \
+ 'is extracted. A comma separated list can be used ' \
+ 'to specify multiple components.')
+ args = parser.parse_args()
+ args.input = args.input.split(',')
+ args.components = args.components.split(',')
+ return args
+
+def parse_variables_from_verilog(filename):
+ """Parses variables from a Verilog file and stores them in a dict.
+ The following syntax is supported:
+ localparam <VARIABLE> = <VALUE>;
+ :param str filename: input filename
+ """
+ pattern_dec = re.compile(r'^(\d*)$')
+ pattern_hex = re.compile(r'^\d*\'h(\w*)$')
+
+ def _convert_verilog_datatype(str_value):
+ """Converts the Verilog value string to the corresponding Python datatype
+ The following notations are supported:
+ - decimal (e.g. 1)
+ - hexadecimal (e.g. 'h4)
+ - hexadecimal with specification of the variable width (e.g. 32'h4)
+ :param str str_value: the string value to be converted
+ """
+ match_dec = pattern_dec.match(str_value)
+ if match_dec:
+ return int(match_dec.group(1))
+ match_hex = pattern_hex.match(str_value)
+ if match_hex:
+ return int(match_hex.group(1), 16)
+ return '?'
+
+ with open(filename) as f:
+ lines = f.read().splitlines()
+ pattern = re.compile(r'\s*localparam (\S*)\s*=\s*(\S*);')
+ variables = {}
+ for line in lines:
+ match = pattern.match(line)
+ if match:
+ key = match.group(1)
+ value = _convert_verilog_datatype(match.group(2))
+ variables[key] = value
+ return variables
+
+def map_variables(variables, component):
+ """map the variables as they shall appear in the generated dtsi file
+ :param dict variables: the variables that were parsed from the Verilog file(s)
+ :param str component: the name of the component
+ """
+ COMPONENT = component.upper()
+ mapped_vars = {
+ '{}_current_version'.format(component): '{}.{}.{}'.format(
+ variables['{}_CURRENT_VERSION_MAJOR'.format(COMPONENT)],
+ variables['{}_CURRENT_VERSION_MINOR'.format(COMPONENT)],
+ variables['{}_CURRENT_VERSION_BUILD'.format(COMPONENT)]
+ ),
+ '{}_oldest_compatible_version'.format(component): '{}.{}.{}'.format(
+ variables['{}_CURRENT_VERSION_MAJOR'.format(COMPONENT)],
+ variables['{}_CURRENT_VERSION_MINOR'.format(COMPONENT)],
+ variables['{}_CURRENT_VERSION_BUILD'.format(COMPONENT)]
+ ),
+ '{}_version_last_modified_time'.format(component): '0x{:X}'.format(
+ variables['{}_VERSION_LAST_MODIFIED_TIME'.format(COMPONENT)]
+ ),
+ }
+ return mapped_vars
+
+def generate_dtsi_file(filename, mapped_vars):
+ """Generate the dtsi file
+ :param str filename: the output filename
+ :param dict mapped_vars: the variables that shall be written to the file
+ """
+ with open(filename, 'w') as f:
+ for k, v in mapped_vars.items():
+ f.write('// mpm_version {} {}\n'.format(k, v))
+
+def main():
+ """ main function """
+ args = parse_args()
+ variables = {}
+ mapped_vars = {}
+ for file in args.input:
+ variables.update(parse_variables_from_verilog(file))
+ for component in args.components:
+ mapped_vars.update(map_variables(variables, component))
+ generate_dtsi_file(args.output, mapped_vars)
+ return True
+
+if __name__ == '__main__':
+ sys.exit(not main())