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_OUTPUT_DIR=$(call RESOLVE_PATH,$(BUILD_DIR)); \
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_DESIGN_SRCS=$(call RESOLVE_PATHS,$(DESIGN_SRCS)); \
export VIV_VERILOG_DEFS="$(VERILOG_DEFS)"; \
@@ -47,7 +47,7 @@ CHECK_VIVADO_DESIGN = \
export VIV_TOOLS_DIR=$(call RESOLVE_PATH,$(TOOLS_DIR)); \
export VIV_OUTPUT_DIR=$(call RESOLVE_PATH,$(BUILD_DIR)); \
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_DESIGN_SRCS=$(call RESOLVE_PATHS,$(DESIGN_SRCS)); \
export VIV_VERILOG_DEFS="$(VERILOG_DEFS)"; \
+4 -4
View File
@@ -25,7 +25,7 @@ BUILD_VIVADO_IP = \
echo "BUILDER: Building IP $(1)"; \
echo "========================================================"; \
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 SYNTH_IP=$(SYNTH_IP); \
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; \
cp -rf $(4)/$(1)/* $(5)/$(1); \
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); \
echo "BUILDER: Building IP..."; \
export VIV_ERR=0; \
@@ -58,7 +58,7 @@ BUILD_VIVADO_BD = \
echo "BUILDER: Building BD $(1)"; \
echo "========================================================"; \
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..."; \
rm -rf $(5)/$(1); \
mkdir -p $(5)/$(1); \
@@ -90,7 +90,7 @@ BUILD_VIVADO_BDTCL = \
echo "BUILDER: Generating BD from Tcl $(1)"; \
echo "========================================================"; \
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_HDL_SRCS=$(call RESOLVE_PATHS,$(7)); \
echo "BUILDER: Staging BD Tcl in build directory..."; \
+1 -1
View File
@@ -55,7 +55,7 @@ endif
.check_tool:
@echo "BUILDER: Checking tools..."
@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;)
# -------------------------------------------------------------------
+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
# different copyright, and is highlighted appropriately. The following
@@ -24,7 +24,6 @@
Run Vivado builds
"""
from __future__ import print_function
import os
import sys
import re
@@ -34,10 +33,7 @@ import time
import argparse
import subprocess
import threading
try:
from Queue import Queue, Empty
except ImportError:
from queue import Queue, Empty # Py3k
from queue import Queue, Empty
READ_TIMEOUT = 0.1 # s
@@ -472,4 +468,3 @@ def main():
if __name__ == "__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
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"
}
@@ -352,7 +352,7 @@ function viv_modify_ip {
fi
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
echo "ERROR: Invalid part name $part_name. XCI parse error."
return 1
@@ -446,7 +446,7 @@ function viv_upgrade_ip {
for xci_path in $xci_files; do
if [[ -f $xci_path ]]; then
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 '(^$|^#|\*\*)'
test ${PIPESTATUS[0]} -eq 0
else
@@ -494,7 +494,7 @@ function probe_bitfile {
echo "- <Bitfile Path>: Path to a .bit FPGA configuration file"
return 1
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
+8 -7
View File
@@ -1,7 +1,7 @@
#! /usr/bin/python
#! /usr/bin/env python3
import sys, os
import collections
import sys
import os
import argparse
import datetime
@@ -10,7 +10,8 @@ def get_options():
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('--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()
if not args.ip_name:
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():
args = get_options();
args = get_options()
transform = {}
transform['ip_name'] = args.ip_name
transform['ip_srcs_var'] = 'IP_' + args.ip_name.upper() + '_SRCS'
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:
mak_file.write(g_makefile_template.format(**transform))
+3 -4
View File
@@ -1,8 +1,7 @@
#!/usr/bin/python
#!/usr/bin/env python3
import argparse
import os, sys
import re
import sys
# Parse command line options
def get_options():
@@ -21,7 +20,7 @@ def main():
target_tok = args.target.split('/')
if len(target_tok) < 4:
print('ERROR: Invalid target format. Must be <arch>/<device>/<package>/<speedgrade>[/<temperaturegrade>[/<silicon_revision>]]')
print('ERROR: Parsed only ' + str(len(target_tok)) + ' tokens')
print('ERROR: Parsed only ' + str(len(target_tok)) + ' tokens')
sys.exit(1)
if target_tok[0] in ['artix7', 'kintex7', 'zynq', 'spartan7', 'virtex7']:
print('' + target_tok[1] + target_tok[2] + target_tok[3])
+8 -7
View File
@@ -1,7 +1,8 @@
#!/usr/bin/python
#!/usr/bin/env python3
import argparse
import os, sys
import os
import sys
import re
# 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')
parser.print_help()
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')
parser.print_help()
sys.exit(1)
@@ -59,7 +60,7 @@ def main():
print(xci_info['DEVICE'] + xci_info['PACKAGE'] + xci_info['SPEEDGRADE'])
elif args.action == 'retarget':
# 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.')
sys.exit(1)
if not args.target:
@@ -76,16 +77,16 @@ def main():
replace_dict['TEMPERATURE_GRADE'] = target_tok[4]
if len(target_tok) > 5:
replace_dict['SILICON_REVISION'] = target_tok[5]
out_xci_filename = os.path.join(os.path.abspath(args.output_dir), os.path.basename(args.xci_filepath))
out_xci_filename = os.path.join(os.path.abspath(args.output_dir), os.path.basename(args.xci_filepath))
with open(out_xci_filename, 'w') as out_file:
for r_line in xci_lines:
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:
w_line = m.group(1) + replace_dict[m.group(2)] + m.group(4) +'\n'
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:
w_line = m.group(1) + '>' + replace_dict[m.group(2)] + '</spirit:configurableElementValue>\n'
out_file.write(w_line)
+15 -14
View File
@@ -1,7 +1,8 @@
#!/usr/bin/python
#!/usr/bin/env python3
import argparse
import os, sys
import os
import sys
import struct
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('--info', action='store_true', default=False, help='Print bitfile info')
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')
parser.print_help()
sys.exit(1)
@@ -52,9 +53,9 @@ def parse_bitfile(bitfile_bytes):
def flip32(data):
sl = struct.Struct('<I')
sb = struct.Struct('>I')
b = buffer(data)
b = memoryview(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])
return d
@@ -67,18 +68,18 @@ def main():
if args.info:
m = re.search('(.+);UserID=(.+);COMPRESS=(.+);Version=(.+)', header['design_name'])
if m:
print 'Design Name: ' + m.group(1)
print 'User ID: ' + m.group(2)
print 'Compression: ' + m.group(3)
print 'Vivado Version: ' + m.group(4)
print('Design Name: ' + m.group(1))
print('User ID: ' + m.group(2))
print('Compression: ' + m.group(3))
print('Vivado Version: ' + m.group(4))
else:
print 'Design Name: ' + header['design_name']
print 'Part Name: ' + header['part_name']
print 'Datestamp: ' + header['date'] + ' ' + header['time']
print 'Bitstream Size: ' + str(header['bitstream_len'])
print('Design Name: ' + header['design_name'])
print('Part Name: ' + header['part_name'])
print('Datestamp: ' + header['date'] + ' ' + header['time'])
print('Bitstream Size: ' + str(header['bitstream_len']))
# Write a bin file
if args.bin_out:
open(args.bin_out, 'wb').write(flip32(data) if args.flip else data)
if __name__ == '__main__':
main()
main()
+40 -38
View File
@@ -1,9 +1,11 @@
#! /usr/bin/python
#! /usr/bin/env python3
import sys, os
import sys
import os
import collections
import argparse
import re
from functools import reduce
#------------------------------------------------------------
# Types
@@ -23,11 +25,11 @@ class terminal_db_t:
self.rev_db = dict()
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))
else:
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)
else:
self.rev_db[net_name] = [ref_des]
@@ -52,13 +54,13 @@ class component_db_t:
self.db[ref_des][prop] = value
def exists(self, comp_name):
return self.db.has_key(comp_name)
return comp_name in self.db
def lookup(self, comp_name):
return self.db[comp_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):
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
class fpga_pin_db_t:
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']
self.pindb = dict()
self.iodb = set()
@@ -78,30 +80,30 @@ class fpga_pin_db_t:
if len(tokens) == 8:
if tokens != header:
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()
self.pindb[tokens[0].strip()] = pin_info
self.iodb.add(pin_info['I/O Type'])
if len(self.pindb.keys()) == 0 or len(self.iodb) == 0:
print 'ERROR: Could not parse Xilinx package file ' + pkg_file
if len(list(self.pindb.keys())) == 0 or len(self.iodb) == 0:
print('ERROR: Could not parse Xilinx package file ' + pkg_file)
sys.exit(1)
print 'INFO: * Found IO types: ' + ', '.join(self.iodb)
print('INFO: * Found IO types: ' + ', '.join(self.iodb))
self.iodb.remove('NA')
for io in io_exclusions:
if io:
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):
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:
iface_pins.add(pin)
return iface_pins
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):
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')
args = parser.parse_args()
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()
sys.exit(1)
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()
sys.exit(1)
return args
@@ -145,7 +147,7 @@ def collapse_tokens(tokens):
# Parse user specified RINF file and return a terminal and component database
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()
component_db = component_db_t()
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])
else:
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)
# 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
def write_output_files(xdc_path, vstub_path, fpga_pins, fix_names):
# 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
bus_db = dict()
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:
bus_name = m.group(1)
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)
else:
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] = []
# Walk through the bus database and write the XDC file
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()):
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.'))
if bus_db[bus] == []:
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')
else:
bits = sorted(bus_db[bus])
coherent = (bits == range(0, bits[-1]+1))
coherent = (bits == list(range(0, bits[-1]+1)))
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:
bus_full = bus + '(' + 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
if vstub_path:
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')
i = 1
for bus in sorted(bus_db.keys()):
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_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'):
port_dir = ' input '
elif port_dir_short.startswith('o'):
@@ -288,18 +290,18 @@ def write_output_files(xdc_path, vstub_path, fpga_pins, fix_names):
# Report unconnected pins
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
iface_pins = set()
for net in fpga_pins.keys():
for net in list(fpga_pins.keys()):
iface_pins.add(fpga_pins[net].loc)
# Loop through all possible pins and check if we have missed any
for pin in sorted(fpga_pin_db.iface_pins()):
if pin not in iface_pins:
print (' * ' + pin.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) +
'Name = ' + str(fpga_pin_db.get_pin_attr(pin, 'Pin Name')).ljust(10))
print(' * ' + pin.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) +
'Name = ' + str(fpga_pin_db.get_pin_attr(pin, 'Pin Name')).ljust(10))
#------------------------------------------------------------
# Main
@@ -311,21 +313,21 @@ def main():
# Parse RINF netlist
(terminal_db, component_db) = parse_rinf(args.rinf, args.suppress_warn)
# 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):
print 'ERROR: Reference designator not found in the netlist'
print('ERROR: Reference designator not found in the netlist')
sys.exit(1)
fpga_info = component_db.lookup(args.ref_des)
print 'INFO: * Name = ' + fpga_info['Name']
print 'INFO: * Description = ' + fpga_info['Description']
print('INFO: * Name = ' + fpga_info['Name'])
print('INFO: * Description = ' + fpga_info['Description'])
# 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)
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)
# Write output XDC and Verilog
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
if not args.suppress_warn:
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
(like hash files), and create image archives from sets.
"""
from __future__ import print_function
import argparse
import copy
import glob
@@ -108,7 +108,7 @@ def gen_md5(files_list, hash_filename=""):
# Write the MD5 hashes to 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)
hash_file.write(newline)
@@ -225,7 +225,7 @@ def list_differences(list1, list2):
def get_target_name(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
githash = re.findall(r"-g([\d\w]{7,8})", zip_filename)[0]
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):
"""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
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
# 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)
@@ -323,7 +323,7 @@ def determine_targets():
:return: list of valid 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,
# like the hash files
required_files = copy.deepcopy(target_info['files'])
@@ -347,7 +347,7 @@ def main():
if not args.githash:
print("Please provide --githash `<REPO>-<GITHASH>'")
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>'")
return False
+4 -4
View File
@@ -1,6 +1,6 @@
Dependencies:
- python2
- graphviz
- python-graphviz
- python-numpy
- python-matplotlib
- python3
- python3-graphviz
- python3-numpy
- python3-matplotlib
@@ -1,4 +1,4 @@
#!/usr/bin/env python
#!/usr/bin/env python3
#
# Copyright 2016 Ettus Research
#
@@ -16,8 +16,8 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
import rfnocsim
import math
import rfnocsim
import ni_hw_models as hw
class ColGlobals():
+2 -2
View File
@@ -1,4 +1,4 @@
#!/usr/bin/env python
#!/usr/bin/env python3
#
# Copyright 2016 Ettus Research
#
@@ -16,8 +16,8 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
import rfnocsim
import math
import rfnocsim
class UsrpX310(rfnocsim.SimComp):
# Hardware specific constants
+2 -2
View File
@@ -623,7 +623,7 @@ class Visualizer():
for c in sorted(comps):
comp = self.__sim_core.lookup(c)
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('=================================================================')
def dump_debug_audit_log(self, ctype, name_filt='.*'):
@@ -645,7 +645,7 @@ class Visualizer():
status = 'WARNING (Used but Undriven)'
else:
status = 'Unused'
print(' - %s: Status = %s'%(c,status))
print((' - %s: Status = %s'%(c,status)))
print('=================================================================')
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
#
@@ -16,11 +16,11 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
import argparse
import re
import rfnocsim
import ni_hw_models as hw
import colosseum_models
import argparse
import re
def main():
# Arguments
@@ -101,39 +101,39 @@ def main():
for u in sim_core.list_components('', '.*/' + ln):
c = sim_core.lookup(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))
# Visualize various metrics
vis = rfnocsim.Visualizer(sim_core)
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.producer, 'USRP.*', 2)
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_006.*FPGA_SE.*EXT.*', 2)
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_NS_.*', 2)
vis.plot_utilization(rfnocsim.comptype.channel, 'BEE7_010.*FPGA_NW.*SER_XX_.*', 3)
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_001.*FPGA_NW.*EXT.*', 2)
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.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_NE.*EXT.*', 2)
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.show_figure()
vis.new_figure([1,2])
vis.plot_consumption_latency('.*','.*USRP_.*', 1)
vis.new_figure([1, 2])
vis.plot_consumption_latency('.*', '.*USRP_.*', 1)
vis.plot_path_latency('tx[(0)]', '.*', 2)
vis.show_figure()
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
#
@@ -11,7 +11,6 @@ import sys
import subprocess
import logging
import re
import io
import time
import datetime
from queue import Queue
@@ -106,7 +105,7 @@ def gather_target_sims(basedir, targets, excludes):
def parse_output(simout):
# 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:
# - A start timestamp (indicates that Vivado started)
# - The testbench infrastructure start header (indicates that the TB started)
@@ -201,7 +200,11 @@ def run_sim(path, simulator, basedir, setupenv):
setupenv = ''
# Check if environment was setup
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:
setupenv = '. ' + os.path.realpath(setupenv) + ';'
# Run the simulation