aboutsummaryrefslogtreecommitdiffstats
path: root/fpga/usrp3/lib/io_port2/create-lvbitx.py
diff options
context:
space:
mode:
Diffstat (limited to 'fpga/usrp3/lib/io_port2/create-lvbitx.py')
-rw-r--r--fpga/usrp3/lib/io_port2/create-lvbitx.py153
1 files changed, 153 insertions, 0 deletions
diff --git a/fpga/usrp3/lib/io_port2/create-lvbitx.py b/fpga/usrp3/lib/io_port2/create-lvbitx.py
new file mode 100644
index 000000000..ea8231292
--- /dev/null
+++ b/fpga/usrp3/lib/io_port2/create-lvbitx.py
@@ -0,0 +1,153 @@
+#!/usr/bin/python
+"""
+Generate lvbitx from template and bitfile
+"""
+
+from __future__ import print_function
+from xml.etree import ElementTree
+import optparse
+import base64
+import os
+from hashlib import md5
+
+def to_native_str(str_or_bstr):
+ """
+ Returns a native string, regardless of the input string type (binary or
+ UTF-8), and the Python version (2 or 3).
+ Note that the native string type is actually not the same in Python 2 and
+ 3: In the former, it's a binary string, in the latter, it's Unicode.
+ >>> to_native_str(b'foo')
+ 'foo'
+ >>> to_native_str(u'foo')
+ 'foo'
+ """
+ if isinstance(str_or_bstr, str):
+ return str_or_bstr
+ try:
+ # This will either fail because we're running Python 2 (which doesn't)
+ # have the encoding argument) or because we're not passing in a bytes-
+ # like object (e.g., an integer)
+ return str(str_or_bstr, encoding='ascii')
+ except TypeError:
+ return str(str_or_bstr)
+
+def get_parser():
+ """Parse args."""
+ parser = optparse.OptionParser()
+ parser.add_option(
+ "--device",
+ type="string",
+ dest="device_type",
+ help="Device Type. (Has to match the LVFPGA target plugin)",
+ default=None
+ )
+ parser.add_option(
+ "--input-bin",
+ type="string",
+ dest="input_bin",
+ help="Path to bin file that needs to be merged with the LVBITX before exporting",
+ default=None
+ )
+ parser.add_option(
+ "--output-bin",
+ type="string",
+ dest="output_bin",
+ help="Create a binary configuration bitstream",
+ default=None
+ )
+ parser.add_option(
+ "--output-lvbitx",
+ type="string",
+ dest="output_lvbitx_path",
+ help="Output path for autogenerated LVBITX file",
+ default=None
+ )
+ parser.add_option(
+ "--output-src-path",
+ type="string",
+ dest="output_src_path",
+ help="Output path for autogenerated src file",
+ default=None
+ )
+ return parser
+
+def main():
+ """Go, go, go!"""
+ parser = get_parser()
+ options, args = parser.parse_args()
+ # Args
+ if len(args) < 1:
+ print('ERROR: Please specify the input LVBITX file name')
+ parser.print_help()
+ exit(1)
+
+ lvbitx_filename = args[0]
+ input_filename = os.path.abspath(lvbitx_filename)
+
+ if not os.path.isfile(input_filename):
+ print("ERROR: LVBITX File `{}' could not be accessed or is not a file."
+ .format(input_filename))
+ parser.print_help()
+ exit(1)
+
+ if options.input_bin is not None and \
+ not os.path.isfile(os.path.abspath(options.input_bin)):
+ print("ERROR: FPGA Bin File `{}' could not be accessed or is not a file."
+ .format(options.input_bin))
+ parser.print_help()
+ exit(1)
+
+ if options.output_lvbitx_path is not None and \
+ input_filename == options.output_lvbitx_path:
+ print('ERROR: Input and output LVBITX files were the same. '
+ 'Choose a difference input or output file.')
+ parser.print_help()
+ exit(1)
+
+ # Get XML Tree Node
+ tree = ElementTree.parse(input_filename)
+ root = tree.getroot()
+
+ # Update device type
+ if options.device_type is not None:
+ root.find('Project').find('TargetClass').text += '; ' + options.device_type
+
+ # Merge bitstream into LVBITX
+ if options.input_bin is not None:
+ with open(os.path.abspath(options.input_bin), 'rb') as bin_file:
+ bitstream = bin_file.read()
+ bitstream_md5 = md5(bitstream).hexdigest()
+ bitstream_b64 = base64.b64encode(bitstream)
+ bitstream_b64_lb = b'\n'.join([
+ bitstream_b64[i:i+76]
+ for i in range(0, len(bitstream_b64), 76)
+ ]) + b'\n'
+ root.find('Bitstream').text = to_native_str(bitstream_b64_lb)
+ root.find('BitstreamMD5').text = bitstream_md5
+
+ # Write BIN file
+ bitstream = base64.b64decode(root.find('Bitstream').text)
+ if options.output_lvbitx_path is not None \
+ and md5(bitstream).hexdigest() != root.find('BitstreamMD5').text:
+ print('ERROR: The MD5 sum for the output LVBITX was incorrect. '
+ 'Make sure that the bitstream in the input LVBITX or BIN file is valid.')
+ exit(1)
+
+ if options.output_bin is not None:
+ fpga_bin_file = open(options.output_bin, 'wb')
+ fpga_bin_file.write(bitstream)
+ fpga_bin_file.close()
+
+ # Save LVBITX
+ if options.output_lvbitx_path is not None:
+ with open(options.output_lvbitx_path, 'wb') as lvbitx_file:
+ tree.write(
+ lvbitx_file,
+ encoding="utf-8",
+ xml_declaration=True,
+ default_namespace=None,
+ method="xml"
+ )
+
+if __name__ == "__main__":
+ main()