fpga: Remove Python2 support from build system

- 2to3 was used to convert the Python scripts, except where the tool
  choked and manual intervention was required
- All references to "python" where replaced with "python3"
- buffer() was replaced by memoryview()


Original-commit: ca68195b5d12c5410cfac8d459a0b0902c4c72c7
This commit is contained in:
Martin Braun
2021-01-04 13:28:36 -06:00
committed by Wade Fife
parent ba66b26dc5
commit ec4fab0340
17 changed files with 121 additions and 119 deletions
+2 -2
View File
@@ -22,7 +22,7 @@ BUILD_VIVADO_DESIGN = \
export VIV_TOOLS_DIR=$(call RESOLVE_PATH,$(TOOLS_DIR)); \ export VIV_TOOLS_DIR=$(call RESOLVE_PATH,$(TOOLS_DIR)); \
export VIV_OUTPUT_DIR=$(call RESOLVE_PATH,$(BUILD_DIR)); \ export VIV_OUTPUT_DIR=$(call RESOLVE_PATH,$(BUILD_DIR)); \
export VIV_TOP_MODULE=$(2); \ export VIV_TOP_MODULE=$(2); \
export VIV_PART_NAME=`python $(TOOLS_DIR)/scripts/viv_gen_part_id.py $(3)/$(4)`; \ export VIV_PART_NAME=`python3 $(TOOLS_DIR)/scripts/viv_gen_part_id.py $(3)/$(4)`; \
export VIV_MODE=$(VIVADO_MODE); \ export VIV_MODE=$(VIVADO_MODE); \
export VIV_DESIGN_SRCS=$(call RESOLVE_PATHS,$(DESIGN_SRCS)); \ export VIV_DESIGN_SRCS=$(call RESOLVE_PATHS,$(DESIGN_SRCS)); \
export VIV_VERILOG_DEFS="$(VERILOG_DEFS)"; \ export VIV_VERILOG_DEFS="$(VERILOG_DEFS)"; \
@@ -47,7 +47,7 @@ CHECK_VIVADO_DESIGN = \
export VIV_TOOLS_DIR=$(call RESOLVE_PATH,$(TOOLS_DIR)); \ export VIV_TOOLS_DIR=$(call RESOLVE_PATH,$(TOOLS_DIR)); \
export VIV_OUTPUT_DIR=$(call RESOLVE_PATH,$(BUILD_DIR)); \ export VIV_OUTPUT_DIR=$(call RESOLVE_PATH,$(BUILD_DIR)); \
export VIV_TOP_MODULE=$(2); \ export VIV_TOP_MODULE=$(2); \
export VIV_PART_NAME=`python $(TOOLS_DIR)/scripts/viv_gen_part_id.py $(3)/$(4)`; \ export VIV_PART_NAME=`python3 $(TOOLS_DIR)/scripts/viv_gen_part_id.py $(3)/$(4)`; \
export VIV_MODE=$(VIVADO_MODE); \ export VIV_MODE=$(VIVADO_MODE); \
export VIV_DESIGN_SRCS=$(call RESOLVE_PATHS,$(DESIGN_SRCS)); \ export VIV_DESIGN_SRCS=$(call RESOLVE_PATHS,$(DESIGN_SRCS)); \
export VIV_VERILOG_DEFS="$(VERILOG_DEFS)"; \ export VIV_VERILOG_DEFS="$(VERILOG_DEFS)"; \
+4 -4
View File
@@ -25,7 +25,7 @@ BUILD_VIVADO_IP = \
echo "BUILDER: Building IP $(1)"; \ echo "BUILDER: Building IP $(1)"; \
echo "========================================================"; \ echo "========================================================"; \
export XCI_FILE=$(call RESOLVE_PATH,$(5)/$(1)/$(1).xci); \ export XCI_FILE=$(call RESOLVE_PATH,$(5)/$(1)/$(1).xci); \
export PART_NAME=`python $(TOOLS_DIR)/scripts/viv_gen_part_id.py $(2)/$(3)`; \ export PART_NAME=`python3 $(TOOLS_DIR)/scripts/viv_gen_part_id.py $(2)/$(3)`; \
export GEN_EXAMPLE=$(6); \ export GEN_EXAMPLE=$(6); \
export SYNTH_IP=$(SYNTH_IP); \ export SYNTH_IP=$(SYNTH_IP); \
echo "BUILDER: Staging IP in build directory..."; \ echo "BUILDER: Staging IP in build directory..."; \
@@ -34,7 +34,7 @@ BUILD_VIVADO_IP = \
$(TOOLS_DIR)/scripts/shared-ip-loc-manage.sh --path=$(5)/$(1) reserve; \ $(TOOLS_DIR)/scripts/shared-ip-loc-manage.sh --path=$(5)/$(1) reserve; \
cp -rf $(4)/$(1)/* $(5)/$(1); \ cp -rf $(4)/$(1)/* $(5)/$(1); \
echo "BUILDER: Retargeting IP to part $(2)/$(3)..."; \ echo "BUILDER: Retargeting IP to part $(2)/$(3)..."; \
python $(TOOLS_DIR)/scripts/viv_ip_xci_editor.py --output_dir=$(5)/$(1) --target=$(2)/$(3) retarget $(4)/$(1)/$(1).xci; \ python3 $(TOOLS_DIR)/scripts/viv_ip_xci_editor.py --output_dir=$(5)/$(1) --target=$(2)/$(3) retarget $(4)/$(1)/$(1).xci; \
cd $(5); \ cd $(5); \
echo "BUILDER: Building IP..."; \ echo "BUILDER: Building IP..."; \
export VIV_ERR=0; \ export VIV_ERR=0; \
@@ -58,7 +58,7 @@ BUILD_VIVADO_BD = \
echo "BUILDER: Building BD $(1)"; \ echo "BUILDER: Building BD $(1)"; \
echo "========================================================"; \ echo "========================================================"; \
export BD_FILE=$(call RESOLVE_PATH,$(5)/$(1)/$(1).bd); \ export BD_FILE=$(call RESOLVE_PATH,$(5)/$(1)/$(1).bd); \
export PART_NAME=`python $(TOOLS_DIR)/scripts/viv_gen_part_id.py $(2)/$(3)`; \ export PART_NAME=`python3 $(TOOLS_DIR)/scripts/viv_gen_part_id.py $(2)/$(3)`; \
echo "BUILDER: Staging BD in build directory..."; \ echo "BUILDER: Staging BD in build directory..."; \
rm -rf $(5)/$(1); \ rm -rf $(5)/$(1); \
mkdir -p $(5)/$(1); \ mkdir -p $(5)/$(1); \
@@ -90,7 +90,7 @@ BUILD_VIVADO_BDTCL = \
echo "BUILDER: Generating BD from Tcl $(1)"; \ echo "BUILDER: Generating BD from Tcl $(1)"; \
echo "========================================================"; \ echo "========================================================"; \
export BD_FILE=$(call RESOLVE_PATH,$(5)/$(1)/$(1).tcl); \ export BD_FILE=$(call RESOLVE_PATH,$(5)/$(1)/$(1).tcl); \
export PART_NAME=`python $(TOOLS_DIR)/scripts/viv_gen_part_id.py $(2)/$(3)`; \ export PART_NAME=`python3 $(TOOLS_DIR)/scripts/viv_gen_part_id.py $(2)/$(3)`; \
export BD_IP_REPOS=$(call RESOLVE_PATH,$(6)); \ export BD_IP_REPOS=$(call RESOLVE_PATH,$(6)); \
export BD_HDL_SRCS=$(call RESOLVE_PATHS,$(7)); \ export BD_HDL_SRCS=$(call RESOLVE_PATHS,$(7)); \
echo "BUILDER: Staging BD Tcl in build directory..."; \ echo "BUILDER: Staging BD Tcl in build directory..."; \
+1 -1
View File
@@ -55,7 +55,7 @@ endif
.check_tool: .check_tool:
@echo "BUILDER: Checking tools..." @echo "BUILDER: Checking tools..."
@echo -n "* "; bash --version | grep bash || (echo "ERROR: Bash not found in environment. Please install it"; exit 1;) @echo -n "* "; bash --version | grep bash || (echo "ERROR: Bash not found in environment. Please install it"; exit 1;)
@echo -n "* "; python --version || (echo "ERROR: Python not found in environment. Please install it"; exit 1;) @echo -n "* "; python3 --version || (echo "ERROR: Python not found in environment. Please install it"; exit 1;)
@echo -n "* "; vivado -version 2>&1 | grep Vivado || (echo "ERROR: Vivado not found in environment. Please run setupenv.sh"; exit 1;) @echo -n "* "; vivado -version 2>&1 | grep Vivado || (echo "ERROR: Vivado not found in environment. Please run setupenv.sh"; exit 1;)
# ------------------------------------------------------------------- # -------------------------------------------------------------------
+2 -7
View File
@@ -1,4 +1,4 @@
#!/usr/bin/env python #!/usr/bin/env python3
# #
# Notice: Some parts of this file were copied from PyBOMBS, which has a # Notice: Some parts of this file were copied from PyBOMBS, which has a
# different copyright, and is highlighted appropriately. The following # different copyright, and is highlighted appropriately. The following
@@ -24,7 +24,6 @@
Run Vivado builds Run Vivado builds
""" """
from __future__ import print_function
import os import os
import sys import sys
import re import re
@@ -34,10 +33,7 @@ import time
import argparse import argparse
import subprocess import subprocess
import threading import threading
try: from queue import Queue, Empty
from Queue import Queue, Empty
except ImportError:
from queue import Queue, Empty # Py3k
READ_TIMEOUT = 0.1 # s READ_TIMEOUT = 0.1 # s
@@ -472,4 +468,3 @@ def main():
if __name__ == "__main__": if __name__ == "__main__":
exit(not main()) exit(not main())
+4 -4
View File
@@ -338,7 +338,7 @@ function viv_create_ip {
$VIVADO_EXEC -mode gui -source $(resolve_viv_path $VIV_IP_UTILS) -nolog -nojournal -tclargs create $part_name $ip_name $(resolve_viv_path $ip_dir) $ip_vlnv $VIVADO_EXEC -mode gui -source $(resolve_viv_path $VIV_IP_UTILS) -nolog -nojournal -tclargs create $part_name $ip_name $(resolve_viv_path $ip_dir) $ip_vlnv
echo "Generating Makefile..." echo "Generating Makefile..."
python $REPO_BASE_PATH/tools/scripts/viv_gen_ip_makefile.py --ip_name=$ip_name --dest=$ip_dir/$ip_name python3 $REPO_BASE_PATH/tools/scripts/viv_gen_ip_makefile.py --ip_name=$ip_name --dest=$ip_dir/$ip_name
echo "Done generating IP in $ip_dir/$ip_name" echo "Done generating IP in $ip_dir/$ip_name"
} }
@@ -352,7 +352,7 @@ function viv_modify_ip {
fi fi
xci_path=$(readlink -f $1) xci_path=$(readlink -f $1)
part_name=$(python $REPO_BASE_PATH/tools/scripts/viv_ip_xci_editor.py read_part $xci_path) part_name=$(python3 $REPO_BASE_PATH/tools/scripts/viv_ip_xci_editor.py read_part $xci_path)
if [[ -z $part_name ]]; then if [[ -z $part_name ]]; then
echo "ERROR: Invalid part name $part_name. XCI parse error." echo "ERROR: Invalid part name $part_name. XCI parse error."
return 1 return 1
@@ -446,7 +446,7 @@ function viv_upgrade_ip {
for xci_path in $xci_files; do for xci_path in $xci_files; do
if [[ -f $xci_path ]]; then if [[ -f $xci_path ]]; then
echo "Upgrading $xci_path..." echo "Upgrading $xci_path..."
part_name=$(python $REPO_BASE_PATH/tools/scripts/viv_ip_xci_editor.py read_part $xci_path) part_name=$(python3 $REPO_BASE_PATH/tools/scripts/viv_ip_xci_editor.py read_part $xci_path)
$VIVADO_EXEC -mode batch -source $(resolve_viv_path $VIV_IP_UTILS) -nolog -nojournal -tclargs upgrade $part_name $(resolve_viv_path $xci_path) | grep -v -E '(^$|^#|\*\*)' $VIVADO_EXEC -mode batch -source $(resolve_viv_path $VIV_IP_UTILS) -nolog -nojournal -tclargs upgrade $part_name $(resolve_viv_path $xci_path) | grep -v -E '(^$|^#|\*\*)'
test ${PIPESTATUS[0]} -eq 0 test ${PIPESTATUS[0]} -eq 0
else else
@@ -494,7 +494,7 @@ function probe_bitfile {
echo "- <Bitfile Path>: Path to a .bit FPGA configuration file" echo "- <Bitfile Path>: Path to a .bit FPGA configuration file"
return 1 return 1
fi fi
python $REPO_BASE_PATH/tools/scripts/xil_bitfile_parser.py --info $1 python3 $REPO_BASE_PATH/tools/scripts/xil_bitfile_parser.py --info $1
} }
echo echo
+8 -7
View File
@@ -1,7 +1,7 @@
#! /usr/bin/python #! /usr/bin/env python3
import sys, os import sys
import collections import os
import argparse import argparse
import datetime import datetime
@@ -10,7 +10,8 @@ def get_options():
parser = argparse.ArgumentParser(description='Create a Makefile for Xilinx IP.') parser = argparse.ArgumentParser(description='Create a Makefile for Xilinx IP.')
parser.add_argument('--ip_name', type=str, default=None, help='Name for the IP core') parser.add_argument('--ip_name', type=str, default=None, help='Name for the IP core')
parser.add_argument('--dest', type=str, default=None, help='Destination directory') parser.add_argument('--dest', type=str, default=None, help='Destination directory')
parser.add_argument('--copright_auth', type=str, default='Ettus Research', help='Copyright author') parser.add_argument('--copright_auth',
type=str, default='Ettus Research', help='Copyright author')
args = parser.parse_args() args = parser.parse_args()
if not args.ip_name: if not args.ip_name:
print('ERROR: Please specify a name for the IP core\n') print('ERROR: Please specify a name for the IP core\n')
@@ -39,13 +40,13 @@ $({ip_srcs_var}) $({ip_outs_var}) : $(IP_DIR)/{ip_name}/{ip_name}.xci
""" """
def main(): def main():
args = get_options(); args = get_options()
transform = {} transform = {}
transform['ip_name'] = args.ip_name transform['ip_name'] = args.ip_name
transform['ip_srcs_var'] = 'IP_' + args.ip_name.upper() + '_SRCS' transform['ip_srcs_var'] = 'IP_' + args.ip_name.upper() + '_SRCS'
transform['ip_outs_var'] = 'IP_' + args.ip_name.upper() + '_OUTS' transform['ip_outs_var'] = 'IP_' + args.ip_name.upper() + '_OUTS'
transform['copyright'] = 'Copyright ' + str(datetime.datetime.now().year) + ' ' + args.copright_auth transform['copyright'] = 'Copyright {} {}'.format(
datetime.datetime.now().year, args.copright_auth)
with open(os.path.join(args.dest, 'Makefile.inc'), 'w') as mak_file: with open(os.path.join(args.dest, 'Makefile.inc'), 'w') as mak_file:
mak_file.write(g_makefile_template.format(**transform)) mak_file.write(g_makefile_template.format(**transform))
+2 -3
View File
@@ -1,8 +1,7 @@
#!/usr/bin/python #!/usr/bin/env python3
import argparse import argparse
import os, sys import sys
import re
# Parse command line options # Parse command line options
def get_options(): def get_options():
+7 -6
View File
@@ -1,7 +1,8 @@
#!/usr/bin/python #!/usr/bin/env python3
import argparse import argparse
import os, sys import os
import sys
import re import re
# Parse command line options # Parse command line options
@@ -20,7 +21,7 @@ def get_options():
print('ERROR: Please specify the location for the XCI file to operate on\n') print('ERROR: Please specify the location for the XCI file to operate on\n')
parser.print_help() parser.print_help()
sys.exit(1) sys.exit(1)
if (not os.path.isfile(args.xci_filepath)): if not os.path.isfile(args.xci_filepath):
print('ERROR: XCI File ' + args.xci_filepath + ' could not be accessed or is not a file.\n') print('ERROR: XCI File ' + args.xci_filepath + ' could not be accessed or is not a file.\n')
parser.print_help() parser.print_help()
sys.exit(1) sys.exit(1)
@@ -59,7 +60,7 @@ def main():
print(xci_info['DEVICE'] + xci_info['PACKAGE'] + xci_info['SPEEDGRADE']) print(xci_info['DEVICE'] + xci_info['PACKAGE'] + xci_info['SPEEDGRADE'])
elif args.action == 'retarget': elif args.action == 'retarget':
# Write a new XCI file with modified target info # Write a new XCI file with modified target info
if (not os.path.isdir(args.output_dir)): if not os.path.isdir(args.output_dir):
print('ERROR: IP Build directory ' + args.output_dir + ' could not be accessed or is not a directory.') print('ERROR: IP Build directory ' + args.output_dir + ' could not be accessed or is not a directory.')
sys.exit(1) sys.exit(1)
if not args.target: if not args.target:
@@ -81,11 +82,11 @@ def main():
with open(out_xci_filename, 'w') as out_file: with open(out_xci_filename, 'w') as out_file:
for r_line in xci_lines: for r_line in xci_lines:
w_line = r_line w_line = r_line
m = re.search(get_match_str('(' + '|'.join(replace_dict.keys()) + ')'), r_line) m = re.search(get_match_str('(' + '|'.join(list(replace_dict.keys())) + ')'), r_line)
if m is not None: if m is not None:
w_line = m.group(1) + replace_dict[m.group(2)] + m.group(4) +'\n' w_line = m.group(1) + replace_dict[m.group(2)] + m.group(4) +'\n'
else: else:
m = re.search(get_empty_match_str('(' + '|'.join(replace_dict.keys()) + ')'), r_line) m = re.search(get_empty_match_str('(' + '|'.join(list(replace_dict.keys())) + ')'), r_line)
if m is not None: if m is not None:
w_line = m.group(1) + '>' + replace_dict[m.group(2)] + '</spirit:configurableElementValue>\n' w_line = m.group(1) + '>' + replace_dict[m.group(2)] + '</spirit:configurableElementValue>\n'
out_file.write(w_line) out_file.write(w_line)
+14 -13
View File
@@ -1,7 +1,8 @@
#!/usr/bin/python #!/usr/bin/env python3
import argparse import argparse
import os, sys import os
import sys
import struct import struct
import re import re
@@ -13,7 +14,7 @@ def get_options():
parser.add_argument('--flip', action='store_true', default=False, help='Flip 32-bit endianess') parser.add_argument('--flip', action='store_true', default=False, help='Flip 32-bit endianess')
parser.add_argument('--info', action='store_true', default=False, help='Print bitfile info') parser.add_argument('--info', action='store_true', default=False, help='Print bitfile info')
args = parser.parse_args() args = parser.parse_args()
if (not os.path.isfile(args.bitfile)): if not os.path.isfile(args.bitfile):
print('ERROR: Bitfile ' + args.bitfile + ' could not be accessed or is not a file.\n') print('ERROR: Bitfile ' + args.bitfile + ' could not be accessed or is not a file.\n')
parser.print_help() parser.print_help()
sys.exit(1) sys.exit(1)
@@ -52,9 +53,9 @@ def parse_bitfile(bitfile_bytes):
def flip32(data): def flip32(data):
sl = struct.Struct('<I') sl = struct.Struct('<I')
sb = struct.Struct('>I') sb = struct.Struct('>I')
b = buffer(data) b = memoryview(data)
d = bytearray(len(data)) d = bytearray(len(data))
for offset in xrange(0, len(data), 4): for offset in range(0, len(data), 4):
sb.pack_into(d, offset, sl.unpack_from(b, offset)[0]) sb.pack_into(d, offset, sl.unpack_from(b, offset)[0])
return d return d
@@ -67,15 +68,15 @@ def main():
if args.info: if args.info:
m = re.search('(.+);UserID=(.+);COMPRESS=(.+);Version=(.+)', header['design_name']) m = re.search('(.+);UserID=(.+);COMPRESS=(.+);Version=(.+)', header['design_name'])
if m: if m:
print 'Design Name: ' + m.group(1) print('Design Name: ' + m.group(1))
print 'User ID: ' + m.group(2) print('User ID: ' + m.group(2))
print 'Compression: ' + m.group(3) print('Compression: ' + m.group(3))
print 'Vivado Version: ' + m.group(4) print('Vivado Version: ' + m.group(4))
else: else:
print 'Design Name: ' + header['design_name'] print('Design Name: ' + header['design_name'])
print 'Part Name: ' + header['part_name'] print('Part Name: ' + header['part_name'])
print 'Datestamp: ' + header['date'] + ' ' + header['time'] print('Datestamp: ' + header['date'] + ' ' + header['time'])
print 'Bitstream Size: ' + str(header['bitstream_len']) print('Bitstream Size: ' + str(header['bitstream_len']))
# Write a bin file # Write a bin file
if args.bin_out: if args.bin_out:
open(args.bin_out, 'wb').write(flip32(data) if args.flip else data) open(args.bin_out, 'wb').write(flip32(data) if args.flip else data)
+37 -35
View File
@@ -1,9 +1,11 @@
#! /usr/bin/python #! /usr/bin/env python3
import sys, os import sys
import os
import collections import collections
import argparse import argparse
import re import re
from functools import reduce
#------------------------------------------------------------ #------------------------------------------------------------
# Types # Types
@@ -23,11 +25,11 @@ class terminal_db_t:
self.rev_db = dict() self.rev_db = dict()
def add(self, ref_des, net_name, pin_name): def add(self, ref_des, net_name, pin_name):
if self.db.has_key(ref_des): if ref_des in self.db:
self.db[ref_des].append(terminal_t(net_name, pin_name)) self.db[ref_des].append(terminal_t(net_name, pin_name))
else: else:
self.db[ref_des] = [terminal_t(net_name, pin_name)] self.db[ref_des] = [terminal_t(net_name, pin_name)]
if self.rev_db.has_key(net_name): if net_name in self.rev_db:
self.rev_db[net_name].append(ref_des) self.rev_db[net_name].append(ref_des)
else: else:
self.rev_db[net_name] = [ref_des] self.rev_db[net_name] = [ref_des]
@@ -52,13 +54,13 @@ class component_db_t:
self.db[ref_des][prop] = value self.db[ref_des][prop] = value
def exists(self, comp_name): def exists(self, comp_name):
return self.db.has_key(comp_name) return comp_name in self.db
def lookup(self, comp_name): def lookup(self, comp_name):
return self.db[comp_name] return self.db[comp_name]
def attr_exists(self, comp_name, attr_name): def attr_exists(self, comp_name, attr_name):
return self.exists(comp_name) and self.db[comp_name].has_key(attr_name) return self.exists(comp_name) and attr_name in self.db[comp_name]
def get_attr(self, comp_name, attr_name): def get_attr(self, comp_name, attr_name):
return self.db[comp_name][attr_name] return self.db[comp_name][attr_name]
@@ -68,7 +70,7 @@ class component_db_t:
# Also maintans all the IO Types to aid in filtering # Also maintans all the IO Types to aid in filtering
class fpga_pin_db_t: class fpga_pin_db_t:
def __init__(self, pkg_file, io_exclusions = []): def __init__(self, pkg_file, io_exclusions = []):
print 'INFO: Parsing Xilinx Package File ' + pkg_file + '...' print('INFO: Parsing Xilinx Package File ' + pkg_file + '...')
header = ['Pin','Pin Name','Memory Byte Group','Bank','VCCAUX Group','Super Logic Region','I/O Type','No-Connect'] header = ['Pin','Pin Name','Memory Byte Group','Bank','VCCAUX Group','Super Logic Region','I/O Type','No-Connect']
self.pindb = dict() self.pindb = dict()
self.iodb = set() self.iodb = set()
@@ -78,30 +80,30 @@ class fpga_pin_db_t:
if len(tokens) == 8: if len(tokens) == 8:
if tokens != header: if tokens != header:
pin_info = dict() pin_info = dict()
for col in range(1,len(header)): for col in range(1, len(header)):
pin_info[header[col].strip()] = tokens[col].strip() pin_info[header[col].strip()] = tokens[col].strip()
self.pindb[tokens[0].strip()] = pin_info self.pindb[tokens[0].strip()] = pin_info
self.iodb.add(pin_info['I/O Type']) self.iodb.add(pin_info['I/O Type'])
if len(self.pindb.keys()) == 0 or len(self.iodb) == 0: if len(list(self.pindb.keys())) == 0 or len(self.iodb) == 0:
print 'ERROR: Could not parse Xilinx package file ' + pkg_file print('ERROR: Could not parse Xilinx package file ' + pkg_file)
sys.exit(1) sys.exit(1)
print 'INFO: * Found IO types: ' + ', '.join(self.iodb) print('INFO: * Found IO types: ' + ', '.join(self.iodb))
self.iodb.remove('NA') self.iodb.remove('NA')
for io in io_exclusions: for io in io_exclusions:
if io: if io:
self.iodb.remove(io.rstrip().lstrip()) self.iodb.remove(io.rstrip().lstrip())
print 'INFO: * Using IO types: ' + ', '.join(self.iodb) print('INFO: * Using IO types: ' + ', '.join(self.iodb))
def iface_pins(self): def iface_pins(self):
iface_pins = set() iface_pins = set()
for pin in self.pindb.keys(): for pin in list(self.pindb.keys()):
if self.pindb[pin]['I/O Type'] in self.iodb: if self.pindb[pin]['I/O Type'] in self.iodb:
iface_pins.add(pin) iface_pins.add(pin)
return iface_pins return iface_pins
def is_iface_pin(self, pin): def is_iface_pin(self, pin):
return (self.pindb.has_key(pin)) and (self.pindb[pin]['I/O Type'] in self.iodb) return (pin in self.pindb) and (self.pindb[pin]['I/O Type'] in self.iodb)
def get_pin_attr(self, pin, attr): def get_pin_attr(self, pin, attr):
return self.pindb[pin][attr] return self.pindb[pin][attr]
@@ -124,11 +126,11 @@ def get_options():
parser.add_argument('--fix_names', action='store_true', default=False, help='Fix net names when writing the XDC and Verilog') parser.add_argument('--fix_names', action='store_true', default=False, help='Fix net names when writing the XDC and Verilog')
args = parser.parse_args() args = parser.parse_args()
if not args.xil_pkg_file: if not args.xil_pkg_file:
print 'ERROR: Please specify a Xilinx package file using the --xil_pkg_file option\n' print('ERROR: Please specify a Xilinx package file using the --xil_pkg_file option\n')
parser.print_help() parser.print_help()
sys.exit(1) sys.exit(1)
if not args.rinf: if not args.rinf:
print 'ERROR: Please specify an input RINF file using the --rinf option\n' print('ERROR: Please specify an input RINF file using the --rinf option\n')
parser.print_help() parser.print_help()
sys.exit(1) sys.exit(1)
return args return args
@@ -145,7 +147,7 @@ def collapse_tokens(tokens):
# Parse user specified RINF file and return a terminal and component database # Parse user specified RINF file and return a terminal and component database
def parse_rinf(rinf_path, suppress_warnings): def parse_rinf(rinf_path, suppress_warnings):
print 'INFO: Parsing RINF File ' + rinf_path + '...' print('INFO: Parsing RINF File ' + rinf_path + '...')
terminal_db = terminal_db_t() terminal_db = terminal_db_t()
component_db = component_db_t() component_db = component_db_t()
with open(rinf_path, 'r') as rinf_f: with open(rinf_path, 'r') as rinf_f:
@@ -176,7 +178,7 @@ def parse_rinf(rinf_path, suppress_warnings):
terminal_db.add(tokens[0], net_name, tokens[1]) terminal_db.add(tokens[0], net_name, tokens[1])
else: else:
if not suppress_warnings: if not suppress_warnings:
print 'WARNING: Ignoring line continuation for ' + state + ' at line ' + str(line_num) print('WARNING: Ignoring line continuation for ' + state + ' at line ' + str(line_num))
return (terminal_db, component_db) return (terminal_db, component_db)
# From all the FPGA pins filter out the ones # From all the FPGA pins filter out the ones
@@ -218,7 +220,7 @@ def fix_net_name(name):
# Write an XDC file with sanity checks and readability enhancements # Write an XDC file with sanity checks and readability enhancements
def write_output_files(xdc_path, vstub_path, fpga_pins, fix_names): def write_output_files(xdc_path, vstub_path, fpga_pins, fix_names):
# Figure out the max pin name length for human readable text alignment # Figure out the max pin name length for human readable text alignment
max_pin_len = reduce(lambda x,y:max(x,y), map(len, fpga_pins.keys())) max_pin_len = reduce(lambda x,y:max(x,y), list(map(len, list(fpga_pins.keys()))))
# Create a bus database. Collapse multi-bit buses into single entries # Create a bus database. Collapse multi-bit buses into single entries
bus_db = dict() bus_db = dict()
for pin in sorted(fpga_pins.keys()): for pin in sorted(fpga_pins.keys()):
@@ -226,7 +228,7 @@ def write_output_files(xdc_path, vstub_path, fpga_pins, fix_names):
if m: if m:
bus_name = m.group(1) bus_name = m.group(1)
bit_num = int(m.group(2)) bit_num = int(m.group(2))
if bus_db.has_key(bus_name): if bus_name in bus_db:
bus_db[bus_name].append(bit_num) bus_db[bus_name].append(bit_num)
else: else:
bus_db[bus_name] = [bit_num] bus_db[bus_name] = [bit_num]
@@ -234,10 +236,10 @@ def write_output_files(xdc_path, vstub_path, fpga_pins, fix_names):
bus_db[pin] = [] bus_db[pin] = []
# Walk through the bus database and write the XDC file # Walk through the bus database and write the XDC file
with open(xdc_path, 'w') as xdc_f: with open(xdc_path, 'w') as xdc_f:
print 'INFO: Writing template XDC ' + xdc_path + '...' print('INFO: Writing template XDC ' + xdc_path + '...')
for bus in sorted(bus_db.keys()): for bus in sorted(bus_db.keys()):
if not re.match("[a-zA-Z].[a-zA-Z0-9_]*$", bus): if not re.match("[a-zA-Z].[a-zA-Z0-9_]*$", bus):
print ('CRITICAL WARNING: Invalid net name (bad Verilog syntax): ' + bus + print('CRITICAL WARNING: Invalid net name (bad Verilog syntax): ' + bus +
('. Possibly fixed but please review.' if fix_names else '. Please review.')) ('. Possibly fixed but please review.' if fix_names else '. Please review.'))
if bus_db[bus] == []: if bus_db[bus] == []:
xdc_pin = fix_net_name(bus.upper()) if fix_names else bus.upper() xdc_pin = fix_net_name(bus.upper()) if fix_names else bus.upper()
@@ -249,9 +251,9 @@ def write_output_files(xdc_path, vstub_path, fpga_pins, fix_names):
xdc_f.write('\n') xdc_f.write('\n')
else: else:
bits = sorted(bus_db[bus]) bits = sorted(bus_db[bus])
coherent = (bits == range(0, bits[-1]+1)) coherent = (bits == list(range(0, bits[-1]+1)))
if not coherent: if not coherent:
print 'CRITICAL WARNING: Incoherent bus: ' + bus + '. Some bits may be missing. Please review.' print('CRITICAL WARNING: Incoherent bus: ' + bus + '. Some bits may be missing. Please review.')
for bit in bits: for bit in bits:
bus_full = bus + '(' + str(bit) + ')' bus_full = bus + '(' + str(bit) + ')'
xdc_pin = bus.upper() + '[' + str(bit) + ']' xdc_pin = bus.upper() + '[' + str(bit) + ']'
@@ -264,13 +266,13 @@ def write_output_files(xdc_path, vstub_path, fpga_pins, fix_names):
# Walk through the bus database and write a stub Verilog file # Walk through the bus database and write a stub Verilog file
if vstub_path: if vstub_path:
with open(vstub_path, 'w') as vstub_f: with open(vstub_path, 'w') as vstub_f:
print 'INFO: Writing Verilog stub ' + vstub_path + '...' print('INFO: Writing Verilog stub ' + vstub_path + '...')
vstub_f.write('module ' + os.path.splitext(os.path.basename(vstub_path))[0] + ' (\n') vstub_f.write('module ' + os.path.splitext(os.path.basename(vstub_path))[0] + ' (\n')
i = 1 i = 1
for bus in sorted(bus_db.keys()): for bus in sorted(bus_db.keys()):
port_name = fix_net_name(bus.upper()) if fix_names else bus.upper() port_name = fix_net_name(bus.upper()) if fix_names else bus.upper()
port_loc = fpga_pins[bus].loc.upper() if (bus_db[bus] == []) else '<Multiple>' port_loc = fpga_pins[bus].loc.upper() if (bus_db[bus] == []) else '<Multiple>'
port_dir_short = raw_input('[' + str(i) + '/' + str(len(bus_db.keys())) +'] Direction for ' + port_name + ' (' + port_loc + ')? {[i]nput,[o]utput,[b]oth}: ').lower() port_dir_short = input('[' + str(i) + '/' + str(len(list(bus_db.keys()))) +'] Direction for ' + port_name + ' (' + port_loc + ')? {[i]nput,[o]utput,[b]oth}: ').lower()
if port_dir_short.startswith('i'): if port_dir_short.startswith('i'):
port_dir = ' input ' port_dir = ' input '
elif port_dir_short.startswith('o'): elif port_dir_short.startswith('o'):
@@ -288,15 +290,15 @@ def write_output_files(xdc_path, vstub_path, fpga_pins, fix_names):
# Report unconnected pins # Report unconnected pins
def report_unconnected_pins(fpga_pins, fpga_pin_db): def report_unconnected_pins(fpga_pins, fpga_pin_db):
print 'WARNING: The following pins were not connected. Please review.' print('WARNING: The following pins were not connected. Please review.')
# Collect all the pin locations that have been used for constrain/stub creation # Collect all the pin locations that have been used for constrain/stub creation
iface_pins = set() iface_pins = set()
for net in fpga_pins.keys(): for net in list(fpga_pins.keys()):
iface_pins.add(fpga_pins[net].loc) iface_pins.add(fpga_pins[net].loc)
# Loop through all possible pins and check if we have missed any # Loop through all possible pins and check if we have missed any
for pin in sorted(fpga_pin_db.iface_pins()): for pin in sorted(fpga_pin_db.iface_pins()):
if pin not in iface_pins: if pin not in iface_pins:
print (' * ' + pin.ljust(6) + ': ' + print(' * ' + pin.ljust(6) + ': ' +
'Bank = ' + str(fpga_pin_db.get_pin_attr(pin, 'Bank')).ljust(6) + 'Bank = ' + str(fpga_pin_db.get_pin_attr(pin, 'Bank')).ljust(6) +
'IO Type = ' + str(fpga_pin_db.get_pin_attr(pin, 'I/O Type')).ljust(10) + 'IO Type = ' + str(fpga_pin_db.get_pin_attr(pin, 'I/O Type')).ljust(10) +
'Name = ' + str(fpga_pin_db.get_pin_attr(pin, 'Pin Name')).ljust(10)) 'Name = ' + str(fpga_pin_db.get_pin_attr(pin, 'Pin Name')).ljust(10))
@@ -311,21 +313,21 @@ def main():
# Parse RINF netlist # Parse RINF netlist
(terminal_db, component_db) = parse_rinf(args.rinf, args.suppress_warn) (terminal_db, component_db) = parse_rinf(args.rinf, args.suppress_warn)
# Look for desired reference designator and print some info about it # Look for desired reference designator and print some info about it
print 'INFO: Resolving reference designator ' + args.ref_des + '...' print('INFO: Resolving reference designator ' + args.ref_des + '...')
if not component_db.exists(args.ref_des): if not component_db.exists(args.ref_des):
print 'ERROR: Reference designator not found in the netlist' print('ERROR: Reference designator not found in the netlist')
sys.exit(1) sys.exit(1)
fpga_info = component_db.lookup(args.ref_des) fpga_info = component_db.lookup(args.ref_des)
print 'INFO: * Name = ' + fpga_info['Name'] print('INFO: * Name = ' + fpga_info['Name'])
print 'INFO: * Description = ' + fpga_info['Description'] print('INFO: * Description = ' + fpga_info['Description'])
# Build a list of all FPGA interface pins in the netlist # Build a list of all FPGA interface pins in the netlist
fpga_pins = filter_fpga_pins(args.ref_des, terminal_db, fpga_pin_db, args.traverse_depth) fpga_pins = filter_fpga_pins(args.ref_des, terminal_db, fpga_pin_db, args.traverse_depth)
if not fpga_pins: if not fpga_pins:
print 'ERROR: Could not cross-reference pins for ' + args.ref_des + ' with FPGA device. Are you sure it is an FPGA?' print('ERROR: Could not cross-reference pins for ' + args.ref_des + ' with FPGA device. Are you sure it is an FPGA?')
sys.exit(1) sys.exit(1)
# Write output XDC and Verilog # Write output XDC and Verilog
write_output_files(args.xdc_out, args.vstub_out, fpga_pins, args.fix_names) write_output_files(args.xdc_out, args.vstub_out, fpga_pins, args.fix_names)
print 'INFO: Output file(s) generated successfully!' print('INFO: Output file(s) generated successfully!')
# Generate a report of all unconnected pins # Generate a report of all unconnected pins
if not args.suppress_warn: if not args.suppress_warn:
report_unconnected_pins(fpga_pins, fpga_pin_db) report_unconnected_pins(fpga_pins, fpga_pin_db)
+6 -6
View File
@@ -10,7 +10,7 @@ Package image files into image archive packages
Provides functions for packaging image files into image packages. Generate the intermediate files Provides functions for packaging image files into image packages. Generate the intermediate files
(like hash files), and create image archives from sets. (like hash files), and create image archives from sets.
""" """
from __future__ import print_function
import argparse import argparse
import copy import copy
import glob import glob
@@ -108,7 +108,7 @@ def gen_md5(files_list, hash_filename=""):
# Write the MD5 hashes to file # Write the MD5 hashes to file
with open(hash_filename, 'a') as hash_file: with open(hash_filename, 'a') as hash_file:
for filename, md5_hex in hashes.items(): for filename, md5_hex in list(hashes.items()):
newline = "{md5_hex} {filename}\n".format(filename=filename, md5_hex=md5_hex) newline = "{md5_hex} {filename}\n".format(filename=filename, md5_hex=md5_hex)
hash_file.write(newline) hash_file.write(newline)
@@ -225,7 +225,7 @@ def list_differences(list1, list2):
def get_target_name(zip_filename): def get_target_name(zip_filename):
"""Return the package target that created the given zip_filename""" """Return the package target that created the given zip_filename"""
for target, target_info in PACKAGE_MAPPING.items(): for target, target_info in list(PACKAGE_MAPPING.items()):
# First we need to strip the Git hash out of the filename # First we need to strip the Git hash out of the filename
githash = re.findall(r"-g([\d\w]{7,8})", zip_filename)[0] githash = re.findall(r"-g([\d\w]{7,8})", zip_filename)[0]
stripped_filename = os.path.basename(zip_filename.replace(githash, "{}")) stripped_filename = os.path.basename(zip_filename.replace(githash, "{}"))
@@ -263,7 +263,7 @@ def verify_package(zip_filename):
def edit_manifest_line(line, new_repo_and_hash, new_hashes_dict): def edit_manifest_line(line, new_repo_and_hash, new_hashes_dict):
"""Edit the line in the manifest to (maybe) include the new repo, git hash, and SHA""" """Edit the line in the manifest to (maybe) include the new repo, git hash, and SHA"""
# Check each value in your dictionary of new hashes # Check each value in your dictionary of new hashes
for filename, new_hash in new_hashes_dict.items(): for filename, new_hash in list(new_hashes_dict.items()):
# If the filename with a new hash shows up in the line # If the filename with a new hash shows up in the line
# Note: the filename has a Git hash in it, so we need to peel that off first # Note: the filename has a Git hash in it, so we need to peel that off first
full_filename_matches = re.findall(r"([\d\w]+)-g([\da-fA-F]{7,8})", filename) full_filename_matches = re.findall(r"([\d\w]+)-g([\da-fA-F]{7,8})", filename)
@@ -323,7 +323,7 @@ def determine_targets():
:return: list of valid targets :return: list of valid targets
""" """
found_targets = [] found_targets = []
for target, target_info in PACKAGE_MAPPING.items(): for target, target_info in list(PACKAGE_MAPPING.items()):
# Grab the list of files required, but remove any files that we're going to build here, # Grab the list of files required, but remove any files that we're going to build here,
# like the hash files # like the hash files
required_files = copy.deepcopy(target_info['files']) required_files = copy.deepcopy(target_info['files'])
@@ -347,7 +347,7 @@ def main():
if not args.githash: if not args.githash:
print("Please provide --githash `<REPO>-<GITHASH>'") print("Please provide --githash `<REPO>-<GITHASH>'")
return False return False
elif not re.findall(r"[\d\w]+-[\d\w]{7,8}", args.githash): if not re.findall(r"[\d\w]+-[\d\w]{7,8}", args.githash):
print("--githash does not match expected form. Should be `<REPO>-<GITHASH>'") print("--githash does not match expected form. Should be `<REPO>-<GITHASH>'")
return False return False
+4 -4
View File
@@ -1,6 +1,6 @@
Dependencies: Dependencies:
- python2
- graphviz - graphviz
- python-graphviz - python3
- python-numpy - python3-graphviz
- python-matplotlib - python3-numpy
- python3-matplotlib
@@ -1,4 +1,4 @@
#!/usr/bin/env python #!/usr/bin/env python3
# #
# Copyright 2016 Ettus Research # Copyright 2016 Ettus Research
# #
@@ -16,8 +16,8 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
# #
import rfnocsim
import math import math
import rfnocsim
import ni_hw_models as hw import ni_hw_models as hw
class ColGlobals(): class ColGlobals():
+2 -2
View File
@@ -1,4 +1,4 @@
#!/usr/bin/env python #!/usr/bin/env python3
# #
# Copyright 2016 Ettus Research # Copyright 2016 Ettus Research
# #
@@ -16,8 +16,8 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
# #
import rfnocsim
import math import math
import rfnocsim
class UsrpX310(rfnocsim.SimComp): class UsrpX310(rfnocsim.SimComp):
# Hardware specific constants # Hardware specific constants
+2 -2
View File
@@ -623,7 +623,7 @@ class Visualizer():
for c in sorted(comps): for c in sorted(comps):
comp = self.__sim_core.lookup(c) comp = self.__sim_core.lookup(c)
for s in sorted(comp.get_items()): for s in sorted(comp.get_items()):
print(' - %s: (%s) Latency = %gs'%(s,c,comp.get_latency(s))) print((' - %s: (%s) Latency = %gs' % (s, c, comp.get_latency(s))))
print('=================================================================') print('=================================================================')
def dump_debug_audit_log(self, ctype, name_filt='.*'): def dump_debug_audit_log(self, ctype, name_filt='.*'):
@@ -645,7 +645,7 @@ class Visualizer():
status = 'WARNING (Used but Undriven)' status = 'WARNING (Used but Undriven)'
else: else:
status = 'Unused' status = 'Unused'
print(' - %s: Status = %s'%(c,status)) print((' - %s: Status = %s'%(c,status)))
print('=================================================================') print('=================================================================')
def new_figure(self, grid_dims=[1,1], fignum=1, figsize=(16, 9), dpi=72): def new_figure(self, grid_dims=[1,1], fignum=1, figsize=(16, 9), dpi=72):
+11 -11
View File
@@ -1,4 +1,4 @@
#!/usr/bin/env python #!/usr/bin/env python3
# #
# Copyright 2016 Ettus Research # Copyright 2016 Ettus Research
# #
@@ -16,11 +16,11 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
# #
import argparse
import re
import rfnocsim import rfnocsim
import ni_hw_models as hw import ni_hw_models as hw
import colosseum_models import colosseum_models
import argparse
import re
def main(): def main():
# Arguments # Arguments
@@ -101,39 +101,39 @@ def main():
for u in sim_core.list_components('', '.*/' + ln): for u in sim_core.list_components('', '.*/' + ln):
c = sim_core.lookup(u) c = sim_core.lookup(u)
m = re.match('(.+)/(SER_.*)', u) m = re.match('(.+)/(SER_.*)', u)
if (c.get_utilization('bandwidth') != master_stats[ln]): if c.get_utilization('bandwidth') != master_stats[ln]:
print('[WARN] Data flowing over ' + ln + ' is probably different between ' + master_fpga + ' and ' + m.group(1)) print('[WARN] Data flowing over ' + ln + ' is probably different between ' + master_fpga + ' and ' + m.group(1))
# Visualize various metrics # Visualize various metrics
vis = rfnocsim.Visualizer(sim_core) vis = rfnocsim.Visualizer(sim_core)
vis.show_network() vis.show_network()
vis.new_figure([1,2]) vis.new_figure([1, 2])
vis.plot_utilization(rfnocsim.comptype.hardware, 'BEE7.*', 1) vis.plot_utilization(rfnocsim.comptype.hardware, 'BEE7.*', 1)
vis.plot_utilization(rfnocsim.comptype.producer, 'USRP.*', 2) vis.plot_utilization(rfnocsim.comptype.producer, 'USRP.*', 2)
vis.show_figure() vis.show_figure()
vis.new_figure([1,2]) vis.new_figure([1, 2])
vis.plot_utilization(rfnocsim.comptype.channel, 'BEE7_000.*FPGA_NW.*EXT.*', 1) vis.plot_utilization(rfnocsim.comptype.channel, 'BEE7_000.*FPGA_NW.*EXT.*', 1)
vis.plot_utilization(rfnocsim.comptype.channel, 'BEE7_006.*FPGA_SE.*EXT.*', 2) vis.plot_utilization(rfnocsim.comptype.channel, 'BEE7_006.*FPGA_SE.*EXT.*', 2)
vis.show_figure() vis.show_figure()
vis.new_figure([1,3]) vis.new_figure([1, 3])
vis.plot_utilization(rfnocsim.comptype.channel, 'BEE7_010.*FPGA_NW.*SER_EW_.*', 1) vis.plot_utilization(rfnocsim.comptype.channel, 'BEE7_010.*FPGA_NW.*SER_EW_.*', 1)
vis.plot_utilization(rfnocsim.comptype.channel, 'BEE7_010.*FPGA_NW.*SER_NS_.*', 2) vis.plot_utilization(rfnocsim.comptype.channel, 'BEE7_010.*FPGA_NW.*SER_NS_.*', 2)
vis.plot_utilization(rfnocsim.comptype.channel, 'BEE7_010.*FPGA_NW.*SER_XX_.*', 3) vis.plot_utilization(rfnocsim.comptype.channel, 'BEE7_010.*FPGA_NW.*SER_XX_.*', 3)
vis.show_figure() vis.show_figure()
vis.new_figure([1,4]) vis.new_figure([1, 4])
vis.plot_utilization(rfnocsim.comptype.channel, 'BEE7_000.*FPGA_NW.*EXT.*', 1) vis.plot_utilization(rfnocsim.comptype.channel, 'BEE7_000.*FPGA_NW.*EXT.*', 1)
vis.plot_utilization(rfnocsim.comptype.channel, 'BEE7_001.*FPGA_NW.*EXT.*', 2) vis.plot_utilization(rfnocsim.comptype.channel, 'BEE7_001.*FPGA_NW.*EXT.*', 2)
vis.plot_utilization(rfnocsim.comptype.channel, 'BEE7_002.*FPGA_NW.*EXT.*', 3) vis.plot_utilization(rfnocsim.comptype.channel, 'BEE7_002.*FPGA_NW.*EXT.*', 3)
vis.plot_utilization(rfnocsim.comptype.channel, 'BEE7_003.*FPGA_NW.*EXT.*', 4) vis.plot_utilization(rfnocsim.comptype.channel, 'BEE7_003.*FPGA_NW.*EXT.*', 4)
vis.show_figure() vis.show_figure()
vis.new_figure([1,4]) vis.new_figure([1, 4])
vis.plot_utilization(rfnocsim.comptype.channel, 'BEE7_010.*FPGA_NW.*EXT.*', 1) vis.plot_utilization(rfnocsim.comptype.channel, 'BEE7_010.*FPGA_NW.*EXT.*', 1)
vis.plot_utilization(rfnocsim.comptype.channel, 'BEE7_010.*FPGA_NE.*EXT.*', 2) vis.plot_utilization(rfnocsim.comptype.channel, 'BEE7_010.*FPGA_NE.*EXT.*', 2)
vis.plot_utilization(rfnocsim.comptype.channel, 'BEE7_010.*FPGA_SW.*EXT.*', 3) vis.plot_utilization(rfnocsim.comptype.channel, 'BEE7_010.*FPGA_SW.*EXT.*', 3)
vis.plot_utilization(rfnocsim.comptype.channel, 'BEE7_010.*FPGA_SE.*EXT.*', 4) vis.plot_utilization(rfnocsim.comptype.channel, 'BEE7_010.*FPGA_SE.*EXT.*', 4)
vis.show_figure() vis.show_figure()
vis.new_figure([1,2]) vis.new_figure([1, 2])
vis.plot_consumption_latency('.*','.*USRP_.*', 1) vis.plot_consumption_latency('.*', '.*USRP_.*', 1)
vis.plot_path_latency('tx[(0)]', '.*', 2) vis.plot_path_latency('tx[(0)]', '.*', 2)
vis.show_figure() vis.show_figure()
vis.plot_utilization(rfnocsim.comptype.producer, '.*MGMT_HOST.*') vis.plot_utilization(rfnocsim.comptype.producer, '.*MGMT_HOST.*')
+7 -4
View File
@@ -1,4 +1,4 @@
#!/usr/bin/python3 #!/usr/bin/env python3
# #
# Copyright 2018 Ettus Research, a National Instruments Company # Copyright 2018 Ettus Research, a National Instruments Company
# #
@@ -11,7 +11,6 @@ import sys
import subprocess import subprocess
import logging import logging
import re import re
import io
import time import time
import datetime import datetime
from queue import Queue from queue import Queue
@@ -106,7 +105,7 @@ def gather_target_sims(basedir, targets, excludes):
def parse_output(simout): def parse_output(simout):
# Gather results (basic metrics) # Gather results (basic metrics)
results = {'retcode':RETCODE_SUCCESS, 'stdout':simout, 'passed':False} results = {'retcode': RETCODE_SUCCESS, 'stdout': simout, 'passed': False}
# Look for the following in the log: # Look for the following in the log:
# - A start timestamp (indicates that Vivado started) # - A start timestamp (indicates that Vivado started)
# - The testbench infrastructure start header (indicates that the TB started) # - The testbench infrastructure start header (indicates that the TB started)
@@ -201,7 +200,11 @@ def run_sim(path, simulator, basedir, setupenv):
setupenv = '' setupenv = ''
# Check if environment was setup # Check if environment was setup
if 'VIVADO_PATH' not in os.environ: if 'VIVADO_PATH' not in os.environ:
return {'retcode': RETCODE_EXEC_ERR, 'passed':False, 'stdout':bytes('Simulation environment was not initialized\n', 'utf-8')} return {
'retcode': RETCODE_EXEC_ERR,
'passed': False,
'stdout': bytes('Simulation environment was not initialized\n', 'utf-8')
}
else: else:
setupenv = '. ' + os.path.realpath(setupenv) + ';' setupenv = '. ' + os.path.realpath(setupenv) + ';'
# Run the simulation # Run the simulation