Skip to content

Commit

Permalink
Merge pull request #51 from ska-sa/devel
Browse files Browse the repository at this point in the history
Merge for AR1 v1.3 QTP on site.
  • Loading branch information
paulprozesky authored Oct 3, 2016
2 parents 0edc8d4 + 7d629f3 commit a3c7343
Show file tree
Hide file tree
Showing 8 changed files with 466 additions and 188 deletions.
74 changes: 42 additions & 32 deletions scripts/casperfpga_tengbe_status.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@
logging.basicConfig(level=eval('logging.%s' % log_level))
except AttributeError:
raise RuntimeError('No such log level: %s' % log_level)
# import logging
# logging.basicConfig(filename='/tmp/casperfpga_tengbe_status_curses.log', level=logging.DEBUG)
# logging.info('****************************************************')

if args.comms == 'katcp':
HOSTCLASS = katcp_fpga.KatcpFpga
Expand Down Expand Up @@ -155,6 +158,17 @@ def exit_gracefully(sig, frame):
signal.signal(signal.SIGINT, exit_gracefully)
signal.signal(signal.SIGHUP, exit_gracefully)

# work out the maximum host/core name
max_1st_col_offset = -1
for fpga in fpgas:
max_1st_col_offset = max(max_1st_col_offset, len(fpga.host))
for gbe_name in fpga.tengbes.names():
max_1st_col_offset = max(max_1st_col_offset, len(gbe_name))
max_fldname = -1
for hdr in fpga_headers[0]:
max_fldname = max(max_fldname, len(hdr))
max_1st_col_offset += 5

# set up the curses scroll screen
scroller = scroll.Scroll(debug=False)
scroller.screen_setup()
Expand All @@ -174,54 +188,50 @@ def exit_gracefully(sig, frame):
scroller.draw_screen()
if time.time() > last_refresh + polltime:
scroller.clear_buffer()
scroller.add_line(
line = scroller.add_string(
'Polling %i host%s every %s - %is elapsed.' % (
len(fpgas),
'' if len(fpgas) == 1 else 's',
'second' if polltime == 1 else ('%i seconds' % polltime),
time.time() - STARTTIME), 0, 0, absolute=True)
start_pos = 20
pos_increment = 15
if len(fpga_headers) == 1:
scroller.add_line('Host', 0, 1, absolute=True)
for reg in fpga_headers[0]:
scroller.add_line(
reg.rjust(pos_increment), start_pos, 1, absolute=True)
start_pos += pos_increment
scroller.set_ypos(newpos=2)
scroller.set_ylimits(ymin=2)
else:
scroller.set_ypos(1)
scroller.set_ylimits(ymin=1)
time.time() - STARTTIME), 0, 0, fixed=True)
start_pos = max_1st_col_offset
pos_increment = max_fldname + 2

scroller.set_current_line(1)
scroller.set_ylimits(1)

gbe_data = utils.threaded_fpga_operation(fpgas, 10, get_gbe_data)
for ctr, fpga in enumerate(fpgas):
start_pos = max_1st_col_offset
fpga_data = gbe_data[fpga.host]
scroller.add_line(fpga.host)
line = scroller.add_string(fpga.host)
for reg in fpga_headers[0]:
fld = '{val:>{width}}'.format(val=reg, width=max_fldname)
line = scroller.add_string(fld, start_pos)
start_pos += pos_increment
scroller.add_string('', cr=True)
for core, core_data in fpga_data.items():
tap_running = tap_data[fpga.host][core]['name'] == ''
fpga_data[core]['tap_running'] = not tap_running
fpga_data[core]['ip'] = tap_data[fpga.host][core]['ip']
start_pos = 20
scroller.add_line(core, 5)
start_pos = max_1st_col_offset
line = scroller.add_string(core)
for header_register in fpga_headers[0]:
core_regname = header_register.replace('gbe', core)
if start_pos < 200:
if core_regname in core_data.keys():
if not isinstance(core_data[core_regname], str):
regval = '%d' % core_data[core_regname]
else:
regval = core_data[core_regname]
else:
regval = 'n/a'
# all on the same line
scroller.add_line(regval.rjust(pos_increment),
start_pos,
scroller.get_current_line() - 1)
start_pos += pos_increment
if core_regname in core_data.keys():
fld = '{val:>{width}}'.format(
val=core_data[core_regname],
width=max_fldname)
else:
fld = '{val:>{width}}'.format(
val='n/a', width=max_fldname)
scroller.add_string(fld, start_pos)
start_pos += pos_increment
scroller.add_string('', cr=True)
scroller.draw_screen()
last_refresh = time.time()
else:
time.sleep(0.1)
time.sleep(0.05)
except Exception, e:
exit_gracefully(None, None)
raise
Expand Down
4 changes: 3 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@
provides=['casperfpga'],
packages=['casperfpga'], # , 'casperfpga.test'],
package_dir={'casperfpga': 'src'},
scripts=glob.glob('scripts/*')
scripts=glob.glob('scripts/*'),
setup_requires=['katversion'],
use_katversion=True
)

# end
13 changes: 12 additions & 1 deletion src/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,15 @@
from snap import Snap
from tengbe import TenGbe

# end
# BEGIN VERSION CHECK
# Get package version when locally imported from repo or via -e develop install
try:
import katversion as _katversion
except ImportError:
import time as _time
__version__ = "0.0+unknown.{}".format(_time.strftime('%Y%m%d%H%M'))
else:
__version__ = _katversion.get_version(__path__[0])
# END VERSION CHECK

# end
8 changes: 6 additions & 2 deletions src/casperfpga.py
Original file line number Diff line number Diff line change
Expand Up @@ -436,8 +436,12 @@ def get_system_information(self, filename=None, fpg_info=None):
except KeyError:
LOGGER.warn('%s: no sys info key in design info!' % self.host)
# and RCS information if included
if '77777_git' in device_dict:
self.rcs_info['git'] = device_dict['77777_git']
for device_name in device_dict:
if device_name.startswith('77777_git_'):
name = device_name[device_name.find('_', 10) + 1:]
if 'git' not in self.rcs_info:
self.rcs_info['git'] = {}
self.rcs_info['git'][name] = device_dict[device_name]
if '77777_svn' in device_dict:
self.rcs_info['svn'] = device_dict['77777_svn']

Expand Down
44 changes: 37 additions & 7 deletions src/katcp_fpga.py
Original file line number Diff line number Diff line change
Expand Up @@ -576,6 +576,27 @@ def __str__(self):
(self.host, self._bindaddr[1],
'connected' if self.is_connected() else 'disconnected')

@staticmethod
def _process_git_info(metalist):
"""
Git information in the FPG must be processed.
:param metalist:
:return:
"""
got_git = {}
time_pref = str(int(time.time())).replace('.', '_') + '_'
for ctr, parms in enumerate(metalist):
name, tag, param, value = parms
if name == '77777_git':
assert tag == 'rcs'
newname = name + '_' + time_pref + param
if newname not in got_git:
got_git[newname] = (newname, tag, 'file-name', param)
param = value[0]
value = value[1:]
metalist[ctr] = (newname, tag, param, value)
metalist.extend(got_git.values())

def _read_design_info_from_host(self, device=None):
"""
Katcp request for extra system information embedded in the boffile.
Expand Down Expand Up @@ -617,47 +638,56 @@ def _read_design_info_from_host(self, device=None):
value = value[0]
name = name.replace('/', '_')
metalist.append((name, tag, param, value))
self._process_git_info(metalist)
return create_meta_dictionary(metalist)

def _read_coreinfo_from_host(self):
"""
Get the equivalent of coreinfo.tab from the host using KATCP listdev commands.
Get the equivalent of coreinfo.tab from the host using
KATCP listdev commands.
:return:
"""
LOGGER.debug('%s: reading coreinfo' % self.host)
memorymap_dict = {}
listdev_size = self.listdev(getsize=True)
listdev_address = self.listdev(getaddress=True)
if len(listdev_address) != len(listdev_size):
raise RuntimeError('Different length listdev(size) and listdev(detail)')
raise RuntimeError('Different length listdev(size) and '
'listdev(detail)')
for byte_dev, byte_size in listdev_size:
matched = False
for addrdev, address in listdev_address:
if addrdev == byte_dev:
byte_size = int(byte_size.split(':')[0])
address = int(address.split(':')[0], 16)
memorymap_dict[byte_dev] = {'address': address, 'bytes': byte_size}
memorymap_dict[byte_dev] = {'address': address,
'bytes': byte_size}
matched = True
continue
if not matched:
raise RuntimeError('No matching listdev address for device %s' % byte_dev)
raise RuntimeError('No matching listdev address for '
'device %s' % byte_dev)
return memorymap_dict

def get_system_information(self, filename=None, fpg_info=None):
"""
Get information about the design running on the FPGA.
If filename is given, get it from there, otherwise query the host via KATCP.
If filename is given, get it from there, otherwise query the
host via KATCP.
:param filename: fpg filename
:param fpg_info: a tuple with two dictionaries of FPG information
:return: <nothing> the information is populated in the class
"""
if (not self.is_running()) and (filename is None):
raise RuntimeError('This can only be run on a running device when no file is given.')
raise RuntimeError('This can only be run on a running device '
'when no file is given.')
if filename is not None:
device_dict, memorymap_dict = parse_fpg(filename)
else:
device_dict = self._read_design_info_from_host()
memorymap_dict = self._read_coreinfo_from_host()
super(KatcpFpga, self).get_system_information(fpg_info=(device_dict, memorymap_dict))
super(KatcpFpga, self).get_system_information(
fpg_info=(device_dict, memorymap_dict))

def unhandled_inform(self, msg):
"""
Expand Down
Loading

0 comments on commit a3c7343

Please sign in to comment.