├── corr2 ├── debug ├── __init__.py ├── bf_parts.gnumeric ├── regextest.py ├── grng.py ├── xeng_42_qdr_errcheck.py ├── fengct_outfreqs.py ├── corr2_snb_filter_status.py ├── plot_line.py ├── spead2test_rx.py ├── skarab_deng_002_output_fft.py ├── corr2_xengine_vacc_sync.py ├── multifpga.py ├── corr2_fengine_tvg.py ├── corr2_xeng_reorder_pwr_1chan.py ├── corr2_xeng_rx_power.py ├── vaccbug │ ├── setup_tvg.py │ └── read_write_info_snap.py ├── mystery_packet.py ├── corr2_clocks.py ├── xeng_35_vacc_snapcheck.py ├── deng_fake_dig_control.py ├── frt_aa_unpack_snap.py ├── corr2_get_baselines.py ├── corr2_startcorr.py ├── xeng_40_vacc_tvg.py ├── snaptest.py ├── corr2_filter_start.py ├── xeng_08_x_new_b_reorder_insidesnap.py ├── test_f_tx.py ├── xeng_preprocess_snapshot.py ├── fengct_txips.py ├── corr2_deprogram.py ├── fengct_out_bram.py ├── fengct_dvout.py ├── skarab_feng_000_rx_pc.py ├── corr2_ping_hosts.py ├── spead2test.py ├── digitiser_receiver.py ├── xeng_reord_snapshot.py ├── corr2_issue_spead_metadata.py ├── corr2_program.py ├── plot_line2.py ├── plot_line3.py ├── mcast.py ├── corr2_bf_partition_select.py ├── deng_check_unpack.py ├── feng_delay_test_fhost_level.py ├── feng_delay_test_fengops_level.py ├── frt_a_d80_snap.py ├── corr2_start_stop_product.py ├── fake_xeng_data.py ├── spead_receiver_example.py ├── deng_unpack_packet_capture.py ├── fengct_txspectrum.py ├── corr2_fengine_sync.py ├── speadtest.py ├── xeng_16_x_nd_vacc_tvg_test.py ├── filt_00_adc_hist.py ├── skarab_deng_000_setup.py ├── feng_check_28_pack_snap.py ├── corr2_get_mappings.py ├── feng_check_02_unpack_spead_errors.py ├── beng │ └── 00_input.py ├── feng_delay_test_register_level.py ├── xeng_17_x_nd_vacc_tvg_test2.py ├── fengct_input.py ├── xeng_30_qdr_errcheck.py ├── fake_spec_ctrl.py └── xeng_00_x_new_aa_timesnap.py ├── scripts ├── __init__.py ├── lband_resync_reset.sh ├── uhf_resync_reset.sh └── corr2_adc_levels_plot.py ├── pip-build-requirements.txt ├── apt-build-requirements.txt ├── unused_src ├── restart_corr.py ├── digitiser.py ├── rts_xengine.py ├── xengine.py ├── testing.py ├── sdk.py ├── fengine.py └── numbers.py ├── MANIFEST.in ├── .gitignore ├── src ├── __init__.py ├── host_fpga.py ├── LICENSE.txt ├── fxcorrelator_speadops.py ├── host.py ├── termcolors.py ├── data_source.py ├── log.py ├── sensors_periodic.py ├── sensor_scheduler.py └── delay.py ├── LICENSE.txt ├── README.md ├── setup.py └── testing └── test_ferrors.py /corr2: -------------------------------------------------------------------------------- 1 | src -------------------------------------------------------------------------------- /debug/__init__.py: -------------------------------------------------------------------------------- 1 | __author__ = 'paulp' 2 | -------------------------------------------------------------------------------- /scripts/__init__.py: -------------------------------------------------------------------------------- 1 | __author__ = 'paulp' 2 | -------------------------------------------------------------------------------- /pip-build-requirements.txt: -------------------------------------------------------------------------------- 1 | git+https://github.com/ska-sa/casperfpga#egg=casperfpga 2 | -------------------------------------------------------------------------------- /debug/bf_parts.gnumeric: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ska-sa/corr2/devel/debug/bf_parts.gnumeric -------------------------------------------------------------------------------- /apt-build-requirements.txt: -------------------------------------------------------------------------------- 1 | libfreetype6-dev 2 | pkg-config 3 | build-essential 4 | python-dev 5 | libhdf5-dev 6 | -------------------------------------------------------------------------------- /debug/regextest.py: -------------------------------------------------------------------------------- 1 | 2 | 3 | some_var = 1 4 | other_var = 2 5 | 6 | print('this is a correct print') 7 | 8 | print('this is a correct print %i' % some_var) 9 | 10 | print('this is a correct print %i, %i' % (some_var, other_var)) 11 | 12 | -------------------------------------------------------------------------------- /unused_src/restart_corr.py: -------------------------------------------------------------------------------- 1 | import fxcorrelator, logging 2 | logging.basicConfig(level=logging.INFO) 3 | c = fxcorrelator.FxCorrelator('rts correlator', config_source='/home/paulp/code/corr2.ska.github/debug/fxcorr_labrts.ini') 4 | c.initialise() 5 | 6 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include DESCRIPTION.rst 2 | include *.conf 3 | include *.txt 4 | 5 | # Include the test suite (FIXME: does not work yet) 6 | # recursive-include tests * 7 | 8 | # Explicitly note anything that is in package_data, as Python 2.6 does 9 | # not include these by default 10 | # include sample/*.dat 11 | -------------------------------------------------------------------------------- /scripts/lband_resync_reset.sh: -------------------------------------------------------------------------------- 1 | cmc="10.103.254.1" 2 | port=$(kcpcmd -s $cmc:7147 array-list | grep array-list | cut -f3 -d' ' | cut -f1 -d',') 3 | 4 | for prt in $port 5 | do 6 | inst=$(kcpcmd -t 10 -s $cmc:$prt sensor-value | grep instrument-state | cut -f6 -d' ') 7 | if [[ $inst = *856* ]] 8 | then 9 | kcpcmd -t 10 -s $cmc:$prt feng-auto-resync-reset 10 | fi 11 | done 12 | -------------------------------------------------------------------------------- /scripts/uhf_resync_reset.sh: -------------------------------------------------------------------------------- 1 | cmc="10.103.254.3" 2 | port=$(kcpcmd -s $cmc:7147 array-list | grep array-list | cut -f3 -d' ' | cut -f1 -d',') 3 | echo $port 4 | for prt in $port 5 | do 6 | inst=$(kcpcmd -t 10 -s $cmc:$prt sensor-value | grep instrument-state | cut -f6 -d' ') 7 | if [[ $inst = *544* ]] 8 | then 9 | kcpcmd -t 10 -s $cmc:$prt feng-auto-resync-reset 10 | fi 11 | done 12 | -------------------------------------------------------------------------------- /unused_src/digitiser.py: -------------------------------------------------------------------------------- 1 | """ 2 | @author: paulp 3 | """ 4 | 5 | import logging 6 | from casperfpga import KatcpClientFpga 7 | 8 | LOGGER = logging.getLogger(__name__) 9 | 10 | 11 | class Digitiser(KatcpClientFpga): 12 | def __init__(self, host_device, port=7147): 13 | KatcpClientFpga.__init__(self, host_device, port) 14 | LOGGER.info('New Digitiser created - %s', str(self)) 15 | 16 | def __str__(self): 17 | return 'digitiser %s @ %i' % (self.host, self.katcp_port) 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Editor backup files 2 | *~ 3 | 4 | # OS generated files # 5 | ###################### 6 | .DS_Store* 7 | ehthumbs.db 8 | Icon? 9 | Thumbs.db 10 | 11 | # Compiled source # 12 | ################### 13 | *.com 14 | *.class 15 | *.dll 16 | *.exe 17 | *.o 18 | *.so 19 | +build/ 20 | *.egg-info 21 | *.pyc 22 | MANIFEST 23 | build 24 | dist 25 | 26 | # PyCharm and other editor droppings # 27 | ############################################# 28 | .idea 29 | .ropeproject 30 | 31 | .eggs 32 | .venv 33 | -------------------------------------------------------------------------------- /debug/grng.py: -------------------------------------------------------------------------------- 1 | __author__ = 'paulp' 2 | 3 | import casperfpga 4 | import numpy 5 | 6 | fpgfile = '/home/paulp/grng_to_snap_2014_Aug_27_1427.fpg' 7 | host = 'roach020958' 8 | correlation = 0 # 0-5 - see block 9 | 10 | 11 | f = casperfpga.KatcpFpga(host) 12 | 13 | f.upload_to_ram_and_program(fpgfile) 14 | 15 | f.registers.control.write(reset='pulse', corrsel=correlation, snapwe=True) 16 | 17 | f.registers.control.write(snaptrig='pulse') 18 | 19 | data = f.snapshots.snapshot_ss.read(man_trig=True) 20 | 21 | fftdata = numpy.fft.fft(data['data']['d0'], 1024) 22 | 23 | 24 | -------------------------------------------------------------------------------- /debug/xeng_42_qdr_errcheck.py: -------------------------------------------------------------------------------- 1 | import casperfpga 2 | 3 | 4 | host = 'roach02081a' 5 | 6 | errors_undetected = {} 7 | undetected_writes = {} 8 | 9 | f = casperfpga.KatcpFpga(host) 10 | f.get_system_information() 11 | 12 | snapname = 'snap_vacc_ss' 13 | 14 | snap = f.snapshots[snapname] 15 | 16 | d = snap.read(circular_capture=True, man_trig=True, man_valid=True)['data'] 17 | 18 | print(len(d[d.keys()[0]]) 19 | 20 | print('ctr\t', 21 | for key in d.keys(): 22 | print(key, '\t', 23 | print('' 24 | for ctr in range(len(d['new_acc'])): 25 | print(ctr, 26 | for key in d.keys(): 27 | print(d[key][ctr], '\t', 28 | print('' 29 | -------------------------------------------------------------------------------- /src/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | corr2 - control and monitoring for casper-based instruments. 3 | """ 4 | 5 | # import the base corr2 modules 6 | import fxcorrelator 7 | import host_fpga 8 | import host 9 | import instrument 10 | import utils 11 | # corr2 requires casperfpga 12 | 13 | # BEGIN VERSION CHECK 14 | # Get package version when locally imported from repo or via -e develop install 15 | try: 16 | import katversion as _katversion 17 | except ImportError: 18 | import time as _time 19 | __version__ = "0.0+unknown.{}".format(_time.strftime('%Y%m%d%H%M')) 20 | else: 21 | __version__ = _katversion.get_version(__path__[0]) 22 | # END VERSION CHECK 23 | 24 | # end 25 | -------------------------------------------------------------------------------- /src/host_fpga.py: -------------------------------------------------------------------------------- 1 | import logging 2 | import time 3 | 4 | from casperfpga.casperfpga import CasperFpga 5 | from casperfpga.network import Mac 6 | 7 | LOGGER = logging.getLogger(__name__) 8 | 9 | 10 | class FpgaHost(CasperFpga): 11 | """ 12 | A Host that is a CASPER FPGA, ROACH2 or SKARAB. 13 | """ 14 | 15 | def setup_host_gbes(self): 16 | """ 17 | Set up the gbe ports on hosts 18 | :return: 19 | """ 20 | for gbe in self.gbes: 21 | if gbe.block_info['tag'] == 'xps:forty_gbe': 22 | gbe.fabric_enable() 23 | else: 24 | raise RuntimeError("This gbe core is not supported!") 25 | # end 26 | -------------------------------------------------------------------------------- /debug/fengct_outfreqs.py: -------------------------------------------------------------------------------- 1 | import feng_utils 2 | 3 | hosts = feng_utils.setup_hosts() 4 | feng_utils.ct_tvg(hosts, 1) 5 | feng_utils.print_err_regs(hosts) 6 | 7 | # raise RuntimeError 8 | 9 | # get a snapshot of the output 10 | f = hosts[0] 11 | d = f.snapshots.out_freqs_ss.read(man_trig=True)['data'] 12 | prev_idx = -8 13 | prev_xeng = -1 14 | errors = [] 15 | for ctr, freq in enumerate(d['d0_0']): 16 | xeng = freq / 256 17 | prtstr = '%5i - freq(%4i) xeng(%2i)' % (ctr, freq, xeng) 18 | if xeng != prev_xeng: 19 | diff = ctr - prev_idx 20 | if diff != 8: 21 | errors.append(ctr) 22 | prtstr += ' ERROR' 23 | prev_idx = ctr 24 | print(prtstr) 25 | prev_xeng = xeng 26 | print errors 27 | 28 | # end 29 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2006 Aaron Parsons, Jason Manley, Paul Prozesky 2 | # This program is free software; you can redistribute it and/or 3 | # modify it under the terms of the GNU General Public License 4 | # as published by the Free Software Foundation; either version 2 5 | # of the License, or (at your option) any later version. 6 | # 7 | # This program is distributed in the hope that it will be useful, 8 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 9 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | # GNU General Public License for more details. 11 | # 12 | # You should have received a copy of the GNU General Public License 13 | # along with this program; if not, write to the Free Software 14 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 15 | 16 | -------------------------------------------------------------------------------- /src/LICENSE.txt: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2006 Aaron Parsons, Jason Manley, Paul Prozesky 2 | # This program is free software; you can redistribute it and/or 3 | # modify it under the terms of the GNU General Public License 4 | # as published by the Free Software Foundation; either version 2 5 | # of the License, or (at your option) any later version. 6 | # 7 | # This program is distributed in the hope that it will be useful, 8 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 9 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | # GNU General Public License for more details. 11 | # 12 | # You should have received a copy of the GNU General Public License 13 | # along with this program; if not, write to the Free Software 14 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 15 | 16 | -------------------------------------------------------------------------------- /debug/corr2_snb_filter_status.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # pylint: disable-msg=C0103 4 | # pylint: disable-msg=C0301 5 | """ 6 | View the status of a given SNB filter board. 7 | 8 | @author: paulp 9 | """ 10 | import argparse 11 | 12 | parser = argparse.ArgumentParser( 13 | description='Display information about a MeerKAT SNB filter host.', 14 | formatter_class=argparse.ArgumentDefaultsHelpFormatter) 15 | parser.add_argument( 16 | '--loglevel', dest='log_level', action='store', default='', 17 | help='log level to use, default None, options INFO, DEBUG, ERROR') 18 | args = parser.parse_args() 19 | 20 | if args.log_level: 21 | import logging 22 | log_level = args.log_level.strip() 23 | try: 24 | logging.basicConfig(level=getattr(logging, log_level)) 25 | except AttributeError: 26 | raise RuntimeError('No such log level: %s' % log_level) 27 | 28 | raise NotImplementedError('This will be completed when filter hosts' 29 | 'are in use.') 30 | 31 | # end 32 | -------------------------------------------------------------------------------- /debug/plot_line.py: -------------------------------------------------------------------------------- 1 | import matplotlib as mpl 2 | mpl.use('TkAgg') 3 | import matplotlib.pyplot as plt 4 | import numpy as np 5 | import time 6 | import sys 7 | 8 | DATA_LEN = 32768 9 | TIME_START = 0 10 | 11 | 12 | # import matplotlib.rcsetup as rcsetup 13 | # print(rcsetup.all_backends) 14 | 15 | assert mpl.rcParams['backend'] == 'TkAgg' 16 | 17 | 18 | def tic(task): 19 | global TICTOC 20 | TICTOC = (time.time(), task) 21 | 22 | 23 | def toc(): 24 | global TICTOC 25 | print('tictoc \'%s\'' % TICTOC[1], time.time() - TICTOC[0] 26 | sys.stdout.flush() 27 | 28 | 29 | def get_data(): 30 | print('in' 31 | sys.stdout.flush() 32 | time.sleep(np.random.rand() * 2) 33 | print('out' 34 | sys.stdout.flush() 35 | return np.random.randn(DATA_LEN), np.random.randn(DATA_LEN) 36 | 37 | subplots = [plt.subplot(2, 1, 1), plt.subplot(2, 1, 2)] 38 | 39 | plt.ion() 40 | plt.show() 41 | 42 | while True: 43 | 44 | (a, b) = get_data() 45 | 46 | subplots[0].clear() 47 | subplots[1].clear() 48 | 49 | subplots[0].plot(a) 50 | subplots[1].plot(b) 51 | 52 | plt.draw() 53 | -------------------------------------------------------------------------------- /src/fxcorrelator_speadops.py: -------------------------------------------------------------------------------- 1 | SPEAD_ADDRSIZE = 48 2 | 3 | def add_item(sig, stx=None, **kwargs): 4 | """ 5 | Add an item to a SPEAD ItemGroup, send if SPEAD TX provided 6 | :param sig: SPEAD ItemGroup 7 | :param stx: SPEAD transmitter 8 | :param kwargs: 9 | :return: 10 | """ 11 | # sid = kwargs['id'] 12 | # spead2 metadata create (and send) 13 | if sig is not None: 14 | sig.add_item(**kwargs) 15 | if stx is not None: 16 | stx.send_heap(sig.get_heap(descriptors='all', data='all')) 17 | 18 | def item_0x1600(sig, stx=None): 19 | add_item( 20 | sig=sig, stx=stx, 21 | name='timestamp', id=0x1600, 22 | description='Timestamp of start of this integration. uint ' 23 | 'counting multiples of ADC samples since last sync ' 24 | '(sync_time, id=0x1027). Divide this number by ' 25 | 'timestamp_scale (id=0x1046) to get back to seconds ' 26 | 'since last sync when this integration was actually ' 27 | 'started.', 28 | shape=[], 29 | format=[('u', SPEAD_ADDRSIZE)]) 30 | 31 | -------------------------------------------------------------------------------- /debug/spead2test_rx.py: -------------------------------------------------------------------------------- 1 | import spead2 2 | import spead2.recv as s2rx 3 | 4 | PORT = 8888 5 | 6 | strm = s2rx.Stream(spead2.ThreadPool(), bug_compat=0, 7 | max_heaps=8, ring_heaps=8) 8 | strm.add_udp_reader(port=PORT, max_size=4096, 9 | buffer_size=51200000) 10 | 11 | ig = spead2.ItemGroup() 12 | 13 | for heap in strm: 14 | ig.update(heap) 15 | for key in ig.keys(): 16 | itm = ig[key] 17 | print(key, ':' 18 | print('\t', 'id:', '0x%4x' % itm.id 19 | print('\t', 'name:', itm.name 20 | print('\t', 'description:', itm.description 21 | print('\t', 'value:', itm.value 22 | print('\t', 'dtype:', itm.dtype 23 | print('\t', 'format:', itm.format 24 | print('\t', 'itemsize_bits:', itm.itemsize_bits 25 | print('\t', 'order:', itm.order 26 | print('\t', 'shape:', itm.shape 27 | print('\t', 'version:', itm.version 28 | print('\t', 'allow_immediate:', itm.allow_immediate() 29 | print('\t', 'is_variable_size:', itm.is_variable_size() 30 | print('' 31 | print(50*'&*' 32 | 33 | # import IPython 34 | # IPython.embed() 35 | -------------------------------------------------------------------------------- /debug/skarab_deng_002_output_fft.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | """ 4 | Check the SPEAD error counter and valid counter in the 5 | unpack section of the F-engines. 6 | 7 | @author: paulp 8 | """ 9 | import os 10 | import logging 11 | 12 | # force the use of the TkAgg backend 13 | import matplotlib 14 | matplotlib.use('TkAgg') 15 | 16 | from matplotlib import pyplot 17 | 18 | import numpy as np 19 | 20 | from casperfpga import casperfpga 21 | 22 | logging.basicConfig(level=logging.INFO) 23 | 24 | DENG = True 25 | 26 | f = casperfpga.CasperFpga(os.environ['SKARAB_DSIM']) 27 | f.get_system_information(os.environ['SKARAB_DSIM_FPG']) 28 | 29 | 30 | def get_output_samples(): 31 | snap = f.snapshots.ss_fifo_in_ss.read(man_trig=True)['data'] 32 | samples = [] 33 | for ctr in range(len(snap['d0'])): 34 | for ctr2 in range(8): 35 | samples.append(snap['d%1i' % ctr2][ctr]) 36 | return samples 37 | 38 | 39 | samples = get_output_samples() 40 | 41 | power = [sample**2 for sample in samples] 42 | 43 | print sum(power) 44 | 45 | fft = np.abs(np.fft.fft(samples, 1024)) 46 | 47 | fig = pyplot.figure() 48 | sub_plot = fig.add_subplot(1, 1, 1) 49 | sub_plot.plot(fft) 50 | pyplot.show() 51 | 52 | 53 | # end 54 | -------------------------------------------------------------------------------- /unused_src/rts_xengine.py: -------------------------------------------------------------------------------- 1 | import logging 2 | from xengine_fpga import XengineCasperFpga 3 | 4 | LOGGER = logging.getLogger(__name__) 5 | 6 | 7 | class RtsXengine(XengineCasperFpga): 8 | """ 9 | The RTS wideband X-engine 10 | """ 11 | def __init__(self, fpga, engine_id=0, host_instrument=None, config_file=None, descriptor='rts_xengine'): 12 | """Constructor 13 | """ 14 | XengineCasperFpga.__init__(self, fpga, engine_id, host_instrument, config_file, descriptor) 15 | 16 | self._get_wb_rts_xengine_config() 17 | 18 | def _get_wb_rts_xengine_config(self): 19 | """ 20 | """ 21 | 22 | def __getattribute__(self, name): 23 | """Overload __getattribute__ to make shortcuts for getting object data. 24 | """ 25 | if name == 'tx_cnt': 26 | return self.host.device_by_name('tx_cnt%s' %self.offset) 27 | 28 | return XengineCasperFpga.__getattribute__(self, name) 29 | 30 | # flashy leds on front panel 31 | def enable_leds(self): 32 | """ Turn on the Knightrider effect 33 | """ 34 | self.control.write(leds_en=1) 35 | 36 | def disable_leds(self): 37 | """ Turn off the Knightrider effect 38 | """ 39 | self.control.write(leds_en=0) 40 | 41 | -------------------------------------------------------------------------------- /debug/corr2_xengine_vacc_sync.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """ 3 | Try to synch the VACCs on the x-engines in a correlator. 4 | """ 5 | import argparse 6 | import os 7 | 8 | from corr2 import fxcorrelator 9 | 10 | parser = argparse.ArgumentParser( 11 | description='Try to synchronise the VACCs on the x-engines on a ' 12 | 'running correlator.', 13 | formatter_class=argparse.ArgumentDefaultsHelpFormatter) 14 | parser.add_argument( 15 | '--config', dest='config', type=str, action='store', default='', 16 | help='corr2 config file') 17 | parser.add_argument( 18 | '--loglevel', dest='log_level', action='store', default='INFO', 19 | help='log level to use, default None, options INFO, DEBUG, ERROR') 20 | args = parser.parse_args() 21 | 22 | if args.log_level: 23 | import logging 24 | log_level = args.log_level.strip() 25 | try: 26 | logging.basicConfig(level=getattr(logging, log_level)) 27 | except AttributeError: 28 | raise RuntimeError('No such log level: %s' % log_level) 29 | 30 | if 'CORR2INI' in os.environ.keys() and args.config == '': 31 | args.config = os.environ['CORR2INI'] 32 | 33 | c = fxcorrelator.FxCorrelator('rts correlator', config_source=args.config) 34 | c.standard_log_config() 35 | c.initialise(program=False) 36 | c.xops.vacc_sync() 37 | 38 | # end 39 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # CORR2 2 | 3 | [![Codacy Badge](https://api.codacy.com/project/badge/Grade/dc5e1d1d17024777a43aa2c47da03f02)](https://app.codacy.com/app/mmphego/corr2?utm_source=github.com&utm_medium=referral&utm_content=ska-sa/corr2&utm_campaign=Badge_Grade_Dashboard) 4 | 5 | This package provides interfaces and functions to configure MeerKAT packetised digital backend; FX correlators, beamformers and other real-time instrumentation. 6 | 7 | ## Installation: 8 | Do the normal 9 | ```bash 10 | $ sudo python setup.py install 11 | ``` 12 | 13 | ### Usage 14 | 15 | ```python 16 | import corr2 17 | c = corr2.fxcorrelator.FxCorrelator('Corr', '/etc/corr/correlator_config.ini') 18 | c.initialise() 19 | ``` 20 | 21 | ## ToDo: 22 | - Make it work! 23 | 24 | Release Notes: 25 | - 2015-07-08: Updated for new DEng registers, requires a DEng build newer 26 | than around 2015-07-01 to work. 27 | - 2015-05-21: requires rootfs 28 | roach2-root-unknown-katonly-private-5911330-2015-05-19.romfs or newer for 29 | the IGMP protocol version setting to work. Roach file-system 'keep' file 30 | must be removed, or (after installing above romfs or newer), the 31 | ?reset-config request can be issued followed by a reboot. 32 | - 2015-05-29: Needs DEng version r2_deng_tvg_2015_May_21_1535.fpg or later 33 | for dsimengine to work properly 34 | - 2015-06-10ish - new_transport_check branch created that breaks interface 35 | with earlier f-engines 36 | -------------------------------------------------------------------------------- /debug/multifpga.py: -------------------------------------------------------------------------------- 1 | import logging 2 | 3 | from casperfpga import utils as casperutils 4 | 5 | logging.basicConfig(level=logging.INFO) 6 | 7 | some_skarabs = ['10.99.49.171', '10.99.51.170', '10.99.53.170', '10.99.57.170'] 8 | a_fpg = '/home/paulp/bofs/sbram_test_2017-6-14_1312.fpg' 9 | program = False 10 | 11 | fpgas = casperutils.threaded_create_fpgas_from_hosts(some_skarabs) 12 | 13 | # a func that exists on the fpga object 14 | if program: 15 | casperutils.threaded_fpga_function( 16 | fpgas, timeout=120, 17 | target_function=('upload_to_ram_and_program', [a_fpg], {})) 18 | else: 19 | casperutils.threaded_fpga_function( 20 | fpgas, timeout=120, 21 | target_function=('get_system_information', [a_fpg], {})) 22 | print(50*'%') 23 | 24 | # another func that exists on the fpga object 25 | print(casperutils.threaded_fpga_function( 26 | fpgas, timeout=120, target_function=('listdev', [], {}))) 27 | print(50*'%') 28 | 29 | 30 | def some_func(fpga, an_arg, a_kwarg): 31 | return fpga.host + '_' + str(an_arg) + '_' + str(a_kwarg) 32 | 33 | # a custom func 34 | print(casperutils.threaded_fpga_operation( 35 | fpgas, timeout=10, 36 | target_function=(some_func, [34], {'a_kwarg': 'astring'}))) 37 | print(50*'%') 38 | 39 | # a lambda func 40 | print(casperutils.threaded_fpga_operation( 41 | fpgas, timeout=10, 42 | target_function=( 43 | lambda fpga: fpga.registers.ram_control.read()['data'], [], {}))) 44 | 45 | # end 46 | -------------------------------------------------------------------------------- /unused_src/xengine.py: -------------------------------------------------------------------------------- 1 | # pylint: disable-msg=C0103 2 | # pylint: disable-msg=C0301 3 | """ 4 | @author: paulp 5 | """ 6 | 7 | import logging 8 | from engine import Engine 9 | 10 | LOGGER = logging.getLogger(__name__) 11 | 12 | 13 | class Xengine(Engine): 14 | """ 15 | A Cross-correlation (X) Engine. 16 | X-engines cross multiply a subset of channels from a number of fengines and accumulate the result 17 | """ 18 | def __init__(self, host_device, engine_id, config_source): 19 | """ 20 | """ 21 | 22 | raise NotImplementedError 23 | 24 | Engine.__init__(self, host_device, engine_id, config_source) 25 | 26 | # check that we have all the required attributes for an f-engine 27 | assert hasattr(self, 'vacc_len'), 'x-engine must have a vector accumulator length' 28 | 29 | def set_accumulation_length(self, accumuluation_length, issue_meta=True): 30 | """ Set the accumulation time for the vector accumulator 31 | @param accumulation_length: the accumulation time in spectra 32 | @param issue_meta: issue SPEAD meta data indicating the change in time 33 | @returns: the actual accumulation time in spectra 34 | """ 35 | raise NotImplementedError 36 | 37 | def get_accumulation_length(self): 38 | """ Get the current accumulation time of the vector accumulator 39 | @returns: the accumulation time in spectra 40 | """ 41 | raise NotImplementedError 42 | 43 | # end 44 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | from glob import glob 2 | from pip import _internal as pip 3 | from setuptools import setup 4 | from subprocess import check_output 5 | 6 | _install_requires = [ 7 | 'casperfpga', 8 | 'pkginfo', 9 | 'h5py', 10 | 'iniparse', 11 | 'katcp>=0.6.2', 12 | 'matplotlib==2.0.2', 13 | 'numpy', 14 | 'spead2', 15 | 'coloredlogs', 16 | 'tornado>=4.3', 17 | 'lazy-import>=0.2.2' 18 | ] 19 | 20 | setup( 21 | name='corr2', 22 | description='Interfaces to MeerKAT CBF', 23 | long_description=open('README.md').read(), 24 | license='GPL', 25 | author='Tyrone van Balla', 26 | author_email='tvanballa at ska.ac.za', 27 | url='https://github.com/ska-sa/corr2', 28 | classifiers=[ 29 | 'Development Status :: 3 - Alpha', 30 | 'Intended Audience :: Developers', 31 | 'Operating System :: OS Independent', 32 | 'License :: OSI Approved :: GNU General Public License (GPL)', 33 | 'Topic :: Scientific/Engineering :: Astronomy', 34 | 'Topic :: Software Development :: Libraries :: Python Modules', 35 | ], 36 | install_requires=_install_requires, 37 | provides=['corr2'], 38 | packages=['corr2'], 39 | package_dir={'corr2': 'src'}, 40 | scripts=glob('scripts/*'), 41 | setup_requires=['katversion'], 42 | use_katversion=True, 43 | entry_points={ 44 | "metadata": [ 45 | "foo_bar = setuptools.dist:assert_string_list", 46 | ], 47 | }, 48 | ) 49 | 50 | # end 51 | -------------------------------------------------------------------------------- /debug/corr2_fengine_tvg.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | """ 4 | @author: paulp 5 | """ 6 | import argparse 7 | 8 | from casperfpga import utils as fpgautils 9 | from corr2 import utils 10 | 11 | 12 | parser = argparse.ArgumentParser( 13 | description='Display information about a MeerKAT F-engine.', 14 | formatter_class=argparse.ArgumentDefaultsHelpFormatter) 15 | parser.add_argument( 16 | '--hosts', dest='hosts', type=str, action='store', default='', 17 | help='comma-delimited list of hosts, or a corr2 config file') 18 | parser.add_argument( 19 | '--prect', dest='prect', action='store_true', default=False, 20 | help='turn on or off the pre corner turn TVG') 21 | parser.add_argument( 22 | '--loglevel', dest='log_level', action='store', default='', 23 | help='log level to use, default None, options INFO, DEBUG, ERROR') 24 | args = parser.parse_args() 25 | 26 | polltime = args.polltime 27 | 28 | if args.log_level != '': 29 | import logging 30 | log_level = args.log_level.strip() 31 | try: 32 | logging.basicConfig(level=eval('logging.%s' % log_level)) 33 | except AttributeError: 34 | raise RuntimeError('No such log level: %s' % log_level) 35 | 36 | # make the fpgas 37 | fpgas = utils.feng_script_get_fpgas(args) 38 | 39 | # pre corner turn 40 | fpgautils.threaded_fpga_operation( 41 | fpgas, 10, lambda fpga_: fpga_.registers.control.write(tvg_ct=args.prect)) 42 | 43 | fpgautils.threaded_fpga_function(fpgas, 10, 'disconnect') 44 | # end 45 | -------------------------------------------------------------------------------- /debug/corr2_xeng_reorder_pwr_1chan.py: -------------------------------------------------------------------------------- 1 | import time,corr2,casperfpga,numpy,sys,pylab 2 | c=corr2.fxcorrelator.FxCorrelator('bob',config_source='/etc/corr/avdbyl_test_1k_16t.ini') 3 | c.initialise(program=False,configure=False,require_epoch=False) 4 | 5 | n_ants=4 6 | n_chans=1024 7 | x=c.xhosts[0] 8 | 9 | x.registers.tvg_control.write(snap_reord_mux_we_sel=1) #only capture a specific frequency 10 | x.registers.sys0_snap_reord_we_freq=4 #freq_this_engine 11 | data=x.snapshots.sys0_snap_reord0_ss.read()['data'] 12 | 13 | i=0 14 | pol0=[] 15 | pol1=[] 16 | for ant in range(n_ants): 17 | pol0.append([]) 18 | pol1.append([]) 19 | while i < len(data['data']): 20 | for ant_n in range(n_ants): 21 | for pi in range(256): 22 | pol0[ant_n].append(complex(numpy.int8((data['data'][i+pi]&0xff000000)>>24),numpy.int8((data['data'][i+pi]&0x00ff0000)>>16))) 23 | pol1[ant_n].append(complex(numpy.int8((data['data'][i+pi]&0xff00)>>8),numpy.int8((data['data'][i+pi]&0x00ff)))) 24 | #print ant_n,pol0[ant_n][-1],pol1[ant_n][-1] 25 | i+=256 26 | 27 | 28 | for i in range(len(pol0[0])): 29 | print '{:4}'.format(i), 30 | for ant_n in range(n_ants): 31 | print '{:11}'.format(pol0[ant_n][i]), 32 | print ' |||| ', 33 | for ant_n in range(n_ants): 34 | print '{:11}'.format(pol1[ant_n][i]), 35 | print '' 36 | 37 | #for ant_n in range(n_ants): 38 | # pylab.plot(numpy.abs(pol0[ant_n])) 39 | #pylab.show() 40 | #for ant_n in range(n_ants): 41 | # pylab.plot(pol0[ant_n]) 42 | #pylab.show() 43 | -------------------------------------------------------------------------------- /unused_src/testing.py: -------------------------------------------------------------------------------- 1 | 2 | source_names = 'ant0_x', 'ant0_y', 'ant1_x', 'ant1_y', 'ant2_x', 'ant2_y', 'ant3_x', 'ant3_y' 3 | 4 | 5 | def _get_ant_mapping_list(): 6 | return source_names 7 | 8 | 9 | def map_input_to_ant(input_n): 10 | """Maps an input number to an antenna string.""" 11 | return _get_ant_mapping_list()[input_n] 12 | 13 | 14 | def get_baseline_order(): 15 | """ 16 | Return the order of baseline data output by a CASPER correlator X engine. 17 | :return: 18 | """ 19 | # TODO 20 | n_ants = 4 21 | order1 = [] 22 | order2 = [] 23 | for ctr1 in range(n_ants): 24 | print 'ctr1(%d)' % ctr1 25 | for ctr2 in range(int(n_ants/2), -1, -1): 26 | temp = (ctr1 - ctr2) % n_ants 27 | print '\tctr2(%d) temp(%d)' % (ctr2, temp) 28 | if ctr1 >= temp: 29 | order1.append((temp, ctr1)) 30 | else: 31 | order2.append((ctr1, temp)) 32 | order2 = [order_ for order_ in order2 if order_ not in order1] 33 | baseline_order = order1 + order2 34 | rv = [] 35 | for baseline in baseline_order: 36 | rv.append((source_names[baseline[0] * 2], source_names[baseline[1] * 2])) 37 | rv.append((source_names[baseline[0] * 2 + 1], source_names[baseline[1] * 2 + 1])) 38 | rv.append((source_names[baseline[0] * 2], source_names[baseline[1] * 2 + 1])) 39 | rv.append((source_names[baseline[0] * 2 + 1], source_names[baseline[1] * 2])) 40 | return rv 41 | 42 | print get_baseline_order() -------------------------------------------------------------------------------- /debug/corr2_xeng_rx_power.py: -------------------------------------------------------------------------------- 1 | import time,corr2,casperfpga,numpy,sys 2 | c=corr2.fxcorrelator.FxCorrelator('bob',config_source='/etc/corr/avdbyl_test_1k_16t.ini') 3 | c.initialise(program=False,configure=False,require_epoch=False) 4 | 5 | def print_xeng_rx_power(xhost_n): 6 | print 'Xhost %i:'%xhost_n 7 | raw_data = c.xhosts[xhost_n].snapshots.snap_rx_unpack0_ss.read()['data'] 8 | xeng_id = numpy.array(raw_data['xeng_id']) 9 | feng_id = numpy.array(raw_data['fengid']) 10 | freq_this_eng = numpy.array(raw_data['freq_this_eng']) 11 | data = numpy.array(raw_data['data']) 12 | choicelist = [data] 13 | data0 = numpy.select([(xeng_id==(xhost_n*4+0))&(feng_id==0)],choicelist) 14 | data1 = numpy.select([(xeng_id==(xhost_n*4+1))&(feng_id==0)],choicelist) 15 | data2 = numpy.select([(xeng_id==(xhost_n*4+2))&(feng_id==0)],choicelist) 16 | data3 = numpy.select([(xeng_id==(xhost_n*4+3))&(feng_id==0)],choicelist) 17 | print "RX power from feng0, pol1, xeng0: ",numpy.sum(numpy.abs([(numpy.int8(i&0xff) + numpy.int8(i>>8)*1j) for i in data0])) 18 | print "RX power from feng0, pol1, xeng1: ",numpy.sum(numpy.abs([(numpy.int8(i&0xff) + numpy.int8(i>>8)*1j) for i in data1])) 19 | print "RX power from feng0, pol1, xeng2: ",numpy.sum(numpy.abs([(numpy.int8(i&0xff) + numpy.int8(i>>8)*1j) for i in data2])) 20 | print "RX power from feng0, pol1, xeng3: ",numpy.sum(numpy.abs([(numpy.int8(i&0xff) + numpy.int8(i>>8)*1j) for i in data3])) 21 | 22 | 23 | def print_xeng_reordered_power(xhost_n): 24 | return 25 | 26 | 27 | for xhost_n in range(4): 28 | print_xeng_rx_power(xhost_n) 29 | print 'done!' 30 | -------------------------------------------------------------------------------- /debug/vaccbug/setup_tvg.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | """ 4 | """ 5 | import logging 6 | import argparse 7 | import os 8 | 9 | from casperfpga import utils as casper_utils 10 | from corr2 import utils, xhost_fpga 11 | 12 | logging.basicConfig(level=logging.INFO) 13 | 14 | parser = argparse.ArgumentParser( 15 | description='Set up the TVG on a x-engine VACC.', 16 | formatter_class=argparse.ArgumentDefaultsHelpFormatter) 17 | parser.add_argument( 18 | '--config', dest='config', type=str, action='store', default='', 19 | help='a corr2 config file, will use $CORR2INI if none given') 20 | args = parser.parse_args() 21 | 22 | if 'CORR2INI' in os.environ.keys() and args.config == '': 23 | args.config = os.environ['CORR2INI'] 24 | if args.config != '': 25 | host_list = utils.parse_hosts(args.config, section='xengine') 26 | else: 27 | host_list = [] 28 | 29 | fpgas = [] 30 | for host_ctr, host in enumerate(host_list): 31 | f = xhost_fpga.FpgaXHostVaccDebug(host, host_ctr) 32 | f.get_system_information() 33 | fpgas.append(f) 34 | 35 | casper_utils.threaded_fpga_operation( 36 | fpgas, 10, 37 | lambda fpga: fpga.tvg_data_value(1)) 38 | 39 | print(casper_utils.threaded_fpga_operation( 40 | fpgas, 10, 41 | lambda fpga: fpga.tvg_control(data_sel=1, inj_vector=0)) 42 | 43 | # _pref = 'sys0_vacc_tvg0' 44 | # 45 | # regname = '%s_n_pulses' % _pref 46 | # fpga.registers[regname].write_int(10240) 47 | # 48 | # regname = '%s_n_per_group' % _pref 49 | # fpga.registers[regname].write_int(40) 50 | # 51 | # regname = '%s_group_period' % _pref 52 | # fpga.registers[regname].write_int(80) 53 | 54 | # reset the ctrs -------------------------------------------------------------------------------- /src/host.py: -------------------------------------------------------------------------------- 1 | """ 2 | Created on Feb 28, 2013 3 | 4 | @author: paulp 5 | """ 6 | import logging 7 | 8 | LOGGER = logging.getLogger(__name__) 9 | 10 | 11 | class Host(object): 12 | """ 13 | A processing host - ROACH board, PC, etc. 14 | Hosts processing engines and communicates via a TCP/IP network. 15 | """ 16 | 17 | def __init__(self, host, katcp_port): 18 | """Constructor 19 | @param host: the unique hostname/identifier for this Host 20 | @param katcp_port: and its KATCP port. 21 | """ 22 | self.host = host 23 | self.katcp_port = katcp_port 24 | self.engines = {} 25 | 26 | def host_okay(self): 27 | """ 28 | Is this host/LRU okay? 29 | :return: 30 | """ 31 | raise NotImplementedError 32 | 33 | def add_engine(self, new_engine): 34 | """ 35 | Add an compute engine to this node. 36 | :param new_engine: 37 | :return: 38 | """ 39 | if new_engine.engine_id in self.engines.keys(): 40 | raise ValueError('engine_id %s already on host %s' % (new_engine.engine_id, self.host)) 41 | new_engine.set_host(self) 42 | self.engines[new_engine.engine_id] = new_engine 43 | 44 | def get_engine(self, engine_id): 45 | """ 46 | Get an engine based on engine_id. If no engine_id is passed, all engines will be returned. 47 | :param engine_id: the unique id of the engine to return. 48 | :return: 49 | """ 50 | return self.engines[engine_id] 51 | 52 | def __str__(self): 53 | return '%s@%s' % (self.host, self.katcp_port) 54 | # end 55 | -------------------------------------------------------------------------------- /debug/mystery_packet.py: -------------------------------------------------------------------------------- 1 | import time 2 | import casperfpga 3 | from casperfpga import spead as casperspead 4 | 5 | f = casperfpga.KatcpFpga('roach020815') 6 | f.get_system_information() 7 | 8 | 9 | f.registers.gbesnapctrl.write(snap_arm=0) 10 | f.snapshots.gbedata0_ss.arm(circular_capture=True) 11 | f.snapshots.gbedata1_ss.arm(circular_capture=True) 12 | f.registers.gbesnapctrl.write(snap_arm=1) 13 | 14 | time.sleep(2) 15 | 16 | d0 = f.snapshots.gbedata0_ss.read(arm=False)['data'] 17 | d1 = f.snapshots.gbedata1_ss.read(arm=False)['data'] 18 | 19 | d0.update(d1) 20 | 21 | # for ctr in range(len(d0[d0.keys()[0]])): 22 | # print('%5i' % ctr, 23 | # for key in d0.keys(): 24 | # print('%s(%i)' % (key, d0[key][ctr]), 25 | # print('' 26 | 27 | gbe_packets = casperfpga.snap.Snap.packetise_snapdata(d0, 'eof') 28 | gbe_data = [] 29 | pkt_lens = [] 30 | 31 | # print(len(gbe_packets) 32 | pktctr = 1 33 | broken_pkt = -1 34 | for pkt in gbe_packets[1:-1]: 35 | pktlen = len(pkt['eof']) 36 | if pktlen not in pkt_lens: 37 | pkt_lens.append(pktlen) 38 | gbe_data.append(d0['gbedata']) 39 | if pkt['gbedata'][0] != 5981908429847920651L: 40 | print('BROKEN PACKET AT ', pktctr, '-', pktlen) 41 | broken_pkt = pktctr 42 | pktctr += 1 43 | 44 | if broken_pkt != -1: 45 | for ctr in range(broken_pkt-2, broken_pkt+3): 46 | pktdata = gbe_packets[ctr]['gbedata'] 47 | hdrs = casperspead.SpeadPacket.decode_headers(pktdata)[0] 48 | # print(ctr, pktdata[0] 49 | # for hdritem, hdrval in hdrs.items(): 50 | # print('\t', '0x%05x' % hdritem), hdrval 51 | 52 | # spead_processor = casperspead.SpeadProcessor(4, '64,48') 53 | # spead_processor.process_data(gbe_data) 54 | 55 | import IPython 56 | IPython.embed() 57 | 58 | # end 59 | -------------------------------------------------------------------------------- /unused_src/sdk.py: -------------------------------------------------------------------------------- 1 | __author__ = 'paulp' 2 | 3 | sx = 9 4 | sy = 9 5 | numblks = sx * sy 6 | 7 | board = numblks * [[]] 8 | possibles = numblks * [range(0, sx)] 9 | values = numblks * [-1] 10 | 11 | values = [ 12 | 6, 5, -1, -1, -1, -1, -1, -1, 9, 13 | -1, -1, -1, -1, -1, 7, 5, -1, 1, 14 | -1, 7, 3, -1, -1, 5, 4, -1, -1, 15 | -1, 4, 9, -1, -1, -1, -1, -1, -1, 16 | -1, -1, -1, -1, 5, -1, -1, -1, -1, 17 | -1, -1, -1, -1, -1, -1, 2, 6, -1, 18 | -1, -1, 6, 8, -1, -1, 7, 1, -1, 19 | 7, -1, 1, 4, -1, -1, -1, -1, -1, 20 | 4, -1, -1, -1, -1, -1, -1, 9, 8 21 | ] 22 | 23 | def row_col_cell_from_index(idx): 24 | r = int(idx / sx) 25 | c = idx - (r * sx) 26 | cellc = int(r/3) 27 | cellr = int(c/3) 28 | return r, c, cellr + (3*cellc) 29 | 30 | 31 | def idxs_in_row(r): 32 | return range(r * sx, (r+1) * sx) 33 | 34 | 35 | def idxs_in_col(c): 36 | return range(c, numblks, sx) 37 | 38 | 39 | def idxs_in_cell(cell): 40 | start_idx = ((cell/3)*27) + ((cell%3)*3) 41 | rv = range(start_idx, start_idx + 3) 42 | start_idx += 9 43 | rv.extend(range(start_idx, start_idx + 3)) 44 | start_idx += 9 45 | rv.extend(range(start_idx, start_idx + 3)) 46 | return rv 47 | 48 | # set up the board 49 | for idx in range(0, numblks): 50 | r, c, cell = row_col_cell_from_index(idx) 51 | rowmates = idxs_in_row(r) 52 | colmates = idxs_in_col(c) 53 | cellmates = idxs_in_cell(cell) 54 | for l in [rowmates, colmates, cellmates]: 55 | l.pop(l.index(idx)) 56 | board[idx] = [r, c, cell, rowmates, colmates, cellmates] 57 | try: 58 | print values[idx] 59 | print possibles[idx] 60 | possibles[idx].pop(possibles[idx].index(values[idx])) 61 | except ValueError: 62 | pass 63 | 64 | print possibles -------------------------------------------------------------------------------- /debug/corr2_clocks.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | """ 3 | Script for checking the approximate clock rate of correlator FPGAs. 4 | """ 5 | from __future__ import print_function 6 | import sys 7 | import argparse 8 | import os 9 | 10 | from casperfpga import utils as fpgautils 11 | from corr2 import utils 12 | 13 | if __name__ == '__main__': 14 | parser = argparse.ArgumentParser( 15 | description='Ping a list of hosts by connecting to them.', 16 | formatter_class=argparse.ArgumentDefaultsHelpFormatter) 17 | parser.add_argument( 18 | '--hosts', dest='hosts', type=str, action='store', default='', 19 | help='comma-delimited list of hosts, or a corr2 config file') 20 | parser.add_argument( 21 | '--loglevel', dest='log_level', action='store', default='', 22 | help='log level to use, default None, options INFO, DEBUG, ERROR') 23 | args = parser.parse_args() 24 | 25 | if args.log_level != '': 26 | import logging 27 | log_level = args.log_level.strip() 28 | try: 29 | logging.basicConfig(level=eval('logging.%s' % log_level)) 30 | except AttributeError: 31 | raise RuntimeError('No such log level: %s' % log_level) 32 | else: 33 | args = {} 34 | 35 | try: 36 | print('Connecting...', end='') 37 | sys.stdout.flush() 38 | fpgas = utils.script_get_fpgas(args) 39 | print('done.') 40 | 41 | print('Calculating all clocks...', end='') 42 | sys.stdout.flush() 43 | results = fpgautils.threaded_fpga_function(fpgas, 10, 'estimate_fpga_clock') 44 | print('done.') 45 | for fpga_ in fpgas: 46 | print('%s: %.0f Mhz' % (fpga_.host, results[fpga_.host])) 47 | 48 | fpgautils.threaded_fpga_function(fpgas, 10, 'disconnect') 49 | except: 50 | import IPython 51 | IPython.embed() 52 | 53 | # end 54 | -------------------------------------------------------------------------------- /debug/xeng_35_vacc_snapcheck.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | """ 4 | """ 5 | import argparse 6 | import os 7 | 8 | from casperfpga import utils as fpgautils 9 | from casperfpga import memory 10 | from corr2 import utils 11 | import casperfpga 12 | 13 | TRIG_COMBO = 0 14 | TRIG_NEWACC = 1 15 | TRIG_PKTRDY = 2 16 | TRIG_VALID = 3 17 | TRIG_RBDONE = 4 18 | TRIG_FETCH = 5 19 | TRIG_MANUAL = 6 20 | 21 | DV_COMBO = 0 22 | DV_NEWACC = 1 23 | DV_PKTRDY = 2 24 | DV_VALID = 3 25 | DV_RBDONE = 4 26 | DV_FETCH = 5 27 | 28 | MAN_VALID = False 29 | 30 | f = casperfpga.KatcpFpga('roach02081a') 31 | f.get_system_information() 32 | 33 | # set the dv and trigger sources 34 | f.registers.snapctrl.write(ctrdv_sel=1, dv_sel=DV_NEWACC, trigsel=TRIG_MANUAL) 35 | 36 | # arm the snaps, select man_valid above 37 | f.snapshots.vacc_snap0_ss.arm(man_valid=MAN_VALID) 38 | f.snapshots.vacc_snap1_ss.arm(man_valid=MAN_VALID) 39 | 40 | # reset the counter 41 | f.registers.snapctrl.write(rst_ctr='pulse') 42 | 43 | #f.registers.snapctrl.write(trig_vacc='pulse') 44 | 45 | # switch to the selected trigger selection 46 | f.registers.snapctrl.write(trigsel=TRIG_NEWACC) 47 | 48 | # read the snaps 49 | d = f.snapshots.vacc_snap0_ss.read(arm=False)['data'] 50 | d1 = f.snapshots.vacc_snap1_ss.read(arm=False)['data'] 51 | d.update(d1) 52 | 53 | # print(the info 54 | 55 | last_ctr = 0 56 | 57 | diffs = {} 58 | 59 | for ctr in range(len(d[d.keys()[0]])): 60 | print(ctr, 61 | for k in d.keys(): 62 | print('{}({})'.format(k, d[k][ctr]), 63 | if d['rdbone'][ctr] == 1: 64 | diff = d['ctr32'][ctr] - last_ctr 65 | if diff < 0: 66 | diff += 2**32 67 | if diff not in diffs: 68 | diffs[diff] = 0 69 | diffs[diff] += 1 70 | print('cdiff({})'.format(diff), 71 | last_ctr = d['ctr32'][ctr] 72 | print('' 73 | 74 | print(diffs 75 | -------------------------------------------------------------------------------- /debug/deng_fake_dig_control.py: -------------------------------------------------------------------------------- 1 | __author__ = 'paulp' 2 | 3 | import argparse 4 | import sys 5 | import signal 6 | 7 | 8 | parser = argparse.ArgumentParser(description='Control a TVG digitiser on a ROACH2.', 9 | formatter_class=argparse.ArgumentDefaultsHelpFormatter) 10 | parser.add_argument(dest='host', type=str, action='store', default='', help='the host to use') 11 | parser.add_argument('--reset_ctrs', dest='rst_ctrs', action='store_true', default=False, 12 | help='reset counters on the fake dig') 13 | parser.add_argument('--output_select', dest='output_select', action='store', default=0, type=int, 14 | help='select the fake dig output: 0(tvg), 1(tvg), 2(grng)') 15 | parser.add_argument('--loglevel', dest='log_level', action='store', default='INFO', 16 | help='log level to use, default None, options INFO, DEBUG, ERROR') 17 | args = parser.parse_args() 18 | 19 | if args.log_level != '': 20 | import logging 21 | log_level = args.log_level.strip() 22 | try: 23 | logging.basicConfig(level=eval('logging.%s' % log_level)) 24 | except AttributeError: 25 | raise RuntimeError('No such log level: %s' % log_level) 26 | LOGGER = logging.getLogger(__name__) 27 | 28 | def exit_gracefully(signal, frame): 29 | fpga.disconnect() 30 | sys.exit(0) 31 | signal.signal(signal.SIGINT, exit_gracefully) 32 | 33 | # make the fake dig 34 | fpga = CasperFpga(args.host) 35 | fpga.get_system_information() 36 | 37 | # do stuff 38 | if args.rst_ctrs: 39 | if LOGGER: 40 | LOGGER.info('Pulsing counter reset line') 41 | fpga.registers.control.write(clr_status='pulse') 42 | 43 | current_dsel = fpga.registers.control.read()['data']['tvg_select0'] 44 | if args.output_select != current_dsel: 45 | fpga.registers.control.write(tvg_select0=args.output_select) 46 | LOGGER.info('Output select set to %i' % args.output_select) 47 | 48 | fpga.disconnect() 49 | -------------------------------------------------------------------------------- /debug/frt_aa_unpack_snap.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # pylint: disable-msg=C0103 4 | # pylint: disable-msg=C0301 5 | """ 6 | @author: paulp 7 | """ 8 | import argparse 9 | 10 | 11 | parser = argparse.ArgumentParser(description='Read raw incoming data on the f-engines.', 12 | formatter_class=argparse.ArgumentDefaultsHelpFormatter) 13 | parser.add_argument(dest='host', type=str, action='store', 14 | help='f-engine host') 15 | parser.add_argument('--eof', dest='eof', action='store_true', 16 | default=False, 17 | help='show only eofs') 18 | parser.add_argument('--comms', dest='comms', action='store', default='katcp', type=str, 19 | help='katcp (default) or dcp?') 20 | parser.add_argument('--loglevel', dest='log_level', action='store', default='', 21 | help='log level to use, default None, options INFO, DEBUG, ERROR') 22 | args = parser.parse_args() 23 | 24 | if args.log_level != '': 25 | import logging 26 | log_level = args.log_level.strip() 27 | try: 28 | logging.basicConfig(level=eval('logging.%s' % log_level)) 29 | except AttributeError: 30 | raise RuntimeError('No such log level: %s' % log_level) 31 | 32 | if args.comms == 'katcp': 33 | HOSTCLASS = CasperFpga 34 | else: 35 | HOSTCLASS = dcp_fpga.DcpFpga 36 | 37 | # create the device and connect to it 38 | fpga = HOSTCLASS(args.host) 39 | fpga.get_system_information() 40 | 41 | #snapdata = fpga.snapshots.unpack_output_ss.read(man_trig=True, man_valid=True)['data'] 42 | snapdata = fpga.snapshots.unpack_output_ss.read(man_valid=True)['data'] 43 | 44 | #snapdata = fpga.snapshots.syncgen_output_ss.read()['data'] 45 | 46 | for ctr in range(0, len(snapdata['dv'])): 47 | for key in snapdata.keys(): 48 | print('%s(%d)\t' % (key, snapdata[key][ctr]), 49 | print('' 50 | 51 | # handle exits cleanly 52 | fpga.disconnect() 53 | # end 54 | -------------------------------------------------------------------------------- /src/termcolors.py: -------------------------------------------------------------------------------- 1 | """ 2 | termcolors.py 3 | -- Taken from corr 4 | """ 5 | 6 | color_names = ('black', 'red', 'green', 'yellow', 'blue', 'magenta', 'cyan', 'white') 7 | foreground = dict([(color_names[x], '3%s' % x) for x in range(8)]) 8 | background = dict([(color_names[x], '4%s' % x) for x in range(8)]) 9 | 10 | RESET = '0' 11 | opt_dict = {'bold': '1', 'underscore': '4', 'blink': '5', 'reverse': '7', 'conceal': '8'} 12 | 13 | 14 | def colorize(text='', opts=(), **kwargs): 15 | """ 16 | Returns your text, enclosed in ANSI graphics codes. 17 | 18 | Depends on the keyword arguments 'fg' and 'bg', and the contents of 19 | the opts tuple/list. 20 | 21 | Returns the RESET code if no parameters are given. 22 | 23 | Valid colors: 24 | 'black', 'red', 'green', 'yellow', 'blue', 'magenta', 'cyan', 'white' 25 | 26 | Valid options: 27 | 'bold' 28 | 'underscore' 29 | 'blink' 30 | 'reverse' 31 | 'conceal' 32 | 'noreset' - string will not be auto-terminated with the RESET code 33 | 34 | Examples: 35 | colorize('hello', fg='red', bg='blue', opts=('blink',)) 36 | colorize() 37 | colorize('goodbye', opts=('underscore',)) 38 | print colorize('first line', fg='red', opts=('noreset',)) 39 | print 'this should be red too' 40 | print colorize('and so should this') 41 | print 'this should not be red' 42 | """ 43 | code_list = [] 44 | if text == '' and len(opts) == 1 and opts[0] == 'reset': 45 | return '\x1b[%sm' % RESET 46 | for k, v in kwargs.iteritems(): 47 | if k == 'fg': 48 | code_list.append(foreground[v]) 49 | elif k == 'bg': 50 | code_list.append(background[v]) 51 | for o in opts: 52 | if o in opt_dict: 53 | code_list.append(opt_dict[o]) 54 | if 'noreset' not in opts: 55 | text = text + '\x1b[%sm' % RESET 56 | return ('\x1b[%sm' % ';'.join(code_list)) + text 57 | -------------------------------------------------------------------------------- /debug/corr2_get_baselines.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | Get the list of baselines for a given configuration. 6 | """ 7 | 8 | import argparse 9 | import os 10 | 11 | from corr2 import utils 12 | 13 | parser = argparse.ArgumentParser( 14 | description='Print out the list of baselines for this correlator config.', 15 | formatter_class=argparse.ArgumentDefaultsHelpFormatter) 16 | parser.add_argument( 17 | '--config', dest='config', type=str, action='store', default='', 18 | help='the config file to parse, $CORR2INI will be used if this is not ' 19 | 'specified') 20 | parser.add_argument( 21 | '--loglevel', dest='log_level', action='store', default='INFO', 22 | help='log level to use, default None, options INFO, DEBUG, ERROR') 23 | args = parser.parse_args() 24 | 25 | if args.log_level != '': 26 | import logging 27 | log_level = args.log_level.strip() 28 | try: 29 | logging.basicConfig(level=eval('logging. %s' % log_level)) 30 | except AttributeError: 31 | raise RuntimeError('No such log level: %s' % log_level) 32 | 33 | configfile = args.config 34 | if 'CORR2INI' in os.environ.keys() and configfile == '': 35 | configfile = os.environ['CORR2INI'] 36 | if configfile == '': 37 | raise RuntimeError('No good carrying on without a config file') 38 | 39 | configd = utils.parse_ini_file(configfile) 40 | baselines = utils.baselines_from_config(config=configd) 41 | fhosts = utils.hosts_from_config(config=configd, section='fengine') 42 | sources = utils.sources_from_config(config=configd) 43 | source_to_host = utils.source_to_host(sources, config=configd) 44 | 45 | bls_hosts = [] 46 | for ctr, baseline in enumerate(baselines): 47 | bls_hosts.append((source_to_host[baseline[0]], 48 | source_to_host[baseline[1]])) 49 | 50 | for ctr, baseline in enumerate(baselines): 51 | ax = 'A' if baseline[0] == baseline[1] else '' 52 | print('%i: %s - %s %s' % (ctr, str(baseline), str(bls_hosts[ctr]), ax)) 53 | 54 | # end 55 | -------------------------------------------------------------------------------- /src/data_source.py: -------------------------------------------------------------------------------- 1 | from casperfpga.network import IpAddress 2 | import logging 3 | 4 | LOGGER = logging.getLogger(__name__) 5 | 6 | raise DeprecationWarning 7 | 8 | class DataSource(object): 9 | """ 10 | A data source from an IP. Holds all the information we need to use 11 | that data source. 12 | """ 13 | def __init__(self, name, ip_string, ip_range, port): 14 | """ 15 | 16 | :param name: the name of this data source 17 | :param ip_string: the ip address at which it can be found - a dotted 18 | decimal STRING 19 | :param ip_range: the consecutive number of IPs over which it is spread 20 | :param port: the port to which it is sent 21 | :return: 22 | """ 23 | self.name = name 24 | self.ip_address = IpAddress(ip_string) 25 | self.ip_range = ip_range 26 | self.port = port 27 | 28 | @classmethod 29 | def from_mcast_string(cls, mcast_string): 30 | try: 31 | _bits = mcast_string.split(':') 32 | port = int(_bits[1]) 33 | if '+' in _bits[0]: 34 | address, number = _bits[0].split('+') 35 | number = int(number) + 1 36 | else: 37 | address = _bits[0] 38 | number = 1 39 | assert(len(address.split('.')) == 4) 40 | except ValueError: 41 | raise RuntimeError('The address %s is not correctly formed. Expect ' 42 | '1.2.3.4+50:7777. Bailing.', mcast_string) 43 | return cls('', address, number, port) 44 | 45 | def is_multicast(self): 46 | """ 47 | Does the data source's IP address begin with 239? 48 | :return: 49 | """ 50 | return self.ip_address.is_multicast() 51 | 52 | def __repr__(self): 53 | return self.__str__() 54 | 55 | def __str__(self): 56 | return 'DataSource(%s) @ %s+%i port(%i)' % ( 57 | self.name, self.ip_address, self.ip_range-1, self.port) 58 | -------------------------------------------------------------------------------- /debug/corr2_startcorr.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """ 3 | Start a correlator. It is recommended to do this via corr2_servlet instead! 4 | 5 | @author: paulp 6 | """ 7 | 8 | import argparse 9 | import os 10 | import time 11 | 12 | from corr2 import fxcorrelator 13 | 14 | parser = argparse.ArgumentParser( 15 | description='Start a correlator.', 16 | formatter_class=argparse.ArgumentDefaultsHelpFormatter) 17 | parser.add_argument( 18 | '--config', dest='config', type=str, action='store', default='', 19 | help='corr2 config file') 20 | parser.add_argument( 21 | '--noprogram', dest='noprogram', action='store_true', default=False, 22 | help='do NOT program the FPGAs, and everything that goes with that') 23 | parser.add_argument( 24 | '--noconfig', dest='no_config', action='store_true', default=False, 25 | help='configure the system') 26 | parser.add_argument( 27 | '--ipython', dest='ipython', action='store_true', default=False, 28 | help='start an ipython session after completion/error') 29 | parser.add_argument( 30 | '--loglevel', dest='log_level', action='store', default='INFO', 31 | help='log level to use, default None, options INFO, DEBUG, ERROR') 32 | args = parser.parse_args() 33 | 34 | log_level = 'INFO' 35 | if args.log_level: 36 | import logging 37 | log_level = args.log_level.strip() 38 | try: 39 | logging.basicConfig(level=getattr(logging, log_level)) 40 | except AttributeError: 41 | raise RuntimeError('No such log level: %s' % log_level) 42 | 43 | if 'CORR2INI' in os.environ.keys() and args.config == '': 44 | args.config = os.environ['CORR2INI'] 45 | 46 | c = fxcorrelator.FxCorrelator('correlator', config_source=args.config) 47 | try: 48 | _tic = time.time() 49 | c.initialise(program=not args.noprogram, configure=not args.no_config) 50 | print('Intialisation took %.3f seconds.' % (time.time() - _tic)) 51 | except Exception as e: 52 | print(e) 53 | 54 | if args.ipython: 55 | import IPython 56 | IPython.embed() 57 | 58 | # end 59 | -------------------------------------------------------------------------------- /debug/xeng_40_vacc_tvg.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | """ 4 | """ 5 | import argparse 6 | import os 7 | 8 | from casperfpga import utils as fpgautils 9 | from casperfpga import memory 10 | from corr2 import utils 11 | import casperfpga 12 | 13 | f = casperfpga.KatcpFpga('roach02081a') 14 | 15 | PROGRAM = True 16 | 17 | if PROGRAM: 18 | 19 | # f.upload_to_ram_and_program('/tmp/vacc_only_001_2016_Apr_13_1622.fpg') 20 | # f.upload_to_ram_and_program('/tmp/vacc_only_001_2016_Apr_14_1103.fpg') 21 | 22 | #f.upload_to_ram_and_program('/tmp/vacc_only_001_2016_Apr_14_1159.fpg') 23 | f.upload_to_ram_and_program('/home/paulp/tmp/vacc_only_001_2016_Apr_15_1633.fpg') 24 | 25 | # f.upload_to_ram_and_program('/tmp/test_qdr_vacc5_2016_Apr_13_1632.fpg') 26 | # f.upload_to_ram_and_program('/tmp/test_qdr_vacc5_2016_Apr_14_0931.fpg') 27 | # f.upload_to_ram_and_program('/tmp/test_qdr_vacc5_2016_Apr_14_0959.fpg') 28 | 29 | # f.upload_to_ram_and_program('/tmp/test_qdr_vacc5_2016_Apr_07_1408.fpg') 30 | # print(f.qdrs.qv_mk_qdr.qdr_cal() 31 | 32 | # f.upload_to_ram_and_program('/tmp/test_qdr_vacc5o_2016_Apr_14_0903.fpg') 33 | print(f.qdrs.sys0_vacc_qv_qdr.qdr_cal() 34 | 35 | f.registers.acc_len.write(reg=816) 36 | else: 37 | f.get_system_information() 38 | 39 | # reset all the TVGs 40 | f.registers.vacctvg_control.write_int(0) 41 | 42 | # write the constant to the data reg and enable the test data 43 | f.registers.sys0_vacc_tvg0_write.write_int(1) 44 | f.registers.vacctvg_control.write(data_sel=True) 45 | 46 | # switch everything over to the constants 47 | # f.registers.vacc_pretvg_ctrl.write(selsync=True, 48 | # seldata=True, 49 | # selvalid=True, 50 | # selflag=True, 51 | # selrben=True, 52 | # selrst=True, 53 | # # rst='pulse', 54 | # en_gating=False) 55 | -------------------------------------------------------------------------------- /debug/snaptest.py: -------------------------------------------------------------------------------- 1 | import casperfpga 2 | 3 | HOST = 'somehost' 4 | FPG = 'snap.fpg' 5 | 6 | f = casperfpga.CasperFpga(HOST) 7 | f.upload_to_ram_and_program(FPG) 8 | 9 | # read the snaps using fabric we/dv and trig 10 | f.registers.snap_control.write(snap_arm=False) 11 | f.snapshots.snap0_ss.arm() 12 | f.snapshots.snap1_ss.arm() 13 | f.registers.snap_control.write(snap_arm=True) 14 | d = f.snapshots.snap0_ss.arm().read(arm=False)['data'] 15 | d.update(f.snapshots.snap1_ss.arm().read(arm=False)['data']) 16 | f.registers.snap_control.write(snap_arm=False) 17 | 18 | # read the snaps with man_trig, but not man_valid 19 | # the man_trig has to be done via a register to get both snaps 20 | # to trigger at the same time 21 | f.registers.snap_control.write(snap_arm=False, snap_trigsel=1) 22 | f.snapshots.snap0_ss.arm() 23 | f.snapshots.snap1_ss.arm() 24 | f.registers.snap_control.write(snap_arm=True, snap_trig='pulse') 25 | d = f.snapshots.snap0_ss.arm().read(arm=False)['data'] 26 | d.update(f.snapshots.snap1_ss.arm().read(arm=False)['data']) 27 | f.registers.snap_control.write(snap_arm=False, snap_trigsel=0) 28 | 29 | # man_valid, but not man_trig 30 | f.registers.snap_control.write(snap_arm=False) 31 | f.snapshots.snap0_ss.arm(man_valid=True) 32 | f.snapshots.snap1_ss.arm(man_valid=True) 33 | f.registers.snap_control.write(snap_arm=True) 34 | d = f.snapshots.snap0_ss.arm().read(arm=False)['data'] 35 | d.update(f.snapshots.snap1_ss.arm().read(arm=False)['data']) 36 | f.registers.snap_control.write(snap_arm=False) 37 | 38 | # man_valid and man_trig 39 | f.registers.snap_control.write(snap_arm=False, snap_trigsel=1) 40 | f.snapshots.snap0_ss.arm(man_valid=True) 41 | f.snapshots.snap1_ss.arm(man_valid=True) 42 | f.registers.snap_control.write(snap_arm=True, snap_trig='pulse') 43 | d = f.snapshots.snap0_ss.arm().read(arm=False)['data'] 44 | d.update(f.snapshots.snap1_ss.arm().read(arm=False)['data']) 45 | f.registers.snap_control.write(snap_arm=False, snap_trigsel=0) 46 | 47 | # circular capture and start delay are as for a single snap, but you pass 48 | # the args to arm(), not read() 49 | 50 | # end 51 | -------------------------------------------------------------------------------- /debug/corr2_filter_start.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # pylint: disable-msg=C0103 4 | # pylint: disable-msg=C0301 5 | """ 6 | Start the filter boards. 7 | 8 | @author: paulp 9 | """ 10 | import argparse 11 | import os 12 | 13 | from casperfpga import utils as fpgautils 14 | from corr2 import utils, filthost_fpga 15 | 16 | parser = argparse.ArgumentParser(description='Set up the filter boards, check RX and start TX.', 17 | formatter_class=argparse.ArgumentDefaultsHelpFormatter) 18 | parser.add_argument('--config', dest='config', type=str, action='store', default='', 19 | help='a corr2 config file') 20 | parser.add_argument('--loglevel', dest='log_level', action='store', default='INFO', 21 | help='log level to use, default None, options INFO, DEBUG, ERROR') 22 | args = parser.parse_args() 23 | 24 | import logging 25 | if args.log_level != '': 26 | log_level = args.log_level.strip() 27 | try: 28 | logging.basicConfig(level=eval('logging.%s' % log_level)) 29 | except AttributeError: 30 | raise RuntimeError('No such log level: %s' % log_level) 31 | LOGGER = logging.getLogger(__name__) 32 | 33 | # parse the config file 34 | cfgsrc = utils.parse_ini_file(args.config) 35 | 36 | if 'CORR2INI' in os.environ.keys() and args.config == '': 37 | args.config = os.environ['CORR2INI'] 38 | hosts = utils.parse_hosts(args.config, section='filter') 39 | if len(hosts) == 0: 40 | raise RuntimeError('No good carrying on without filter hosts.') 41 | 42 | THREADED_FPGA_OP = fpgautils.threaded_fpga_operation 43 | THREADED_FPGA_FUNC = fpgautils.threaded_fpga_function 44 | 45 | # make the FPGA objects 46 | fpgas = [] 47 | for ctr, h in enumerate(hosts): 48 | _fpga = filthost_fpga.FpgaFilterHost(ctr, cfgsrc) 49 | fpgas.append(_fpga) 50 | 51 | # program the boards 52 | THREADED_FPGA_FUNC(fpgas, timeout=10, target_function=('upload_to_ram_and_program', (fpgas[0].bitstream,),)) 53 | 54 | # initialise them 55 | THREADED_FPGA_FUNC(fpgas, timeout=10, target_function=('initialise', (),)) 56 | 57 | # end 58 | -------------------------------------------------------------------------------- /debug/xeng_08_x_new_b_reorder_insidesnap.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """ 3 | """ 4 | import argparse 5 | 6 | 7 | parser = argparse.ArgumentParser(description='View the reorder snap block on an x-engine.', 8 | formatter_class=argparse.ArgumentDefaultsHelpFormatter) 9 | parser.add_argument(dest='host', type=str, action='store', 10 | help='x-engine host') 11 | parser.add_argument('--comms', dest='comms', action='store', default='katcp', type=str, 12 | help='katcp (default) or dcp?') 13 | parser.add_argument('--loglevel', dest='log_level', action='store', default='', 14 | help='log level to use, default None, options INFO, DEBUG, ERROR') 15 | args = parser.parse_args() 16 | 17 | if args.log_level != '': 18 | import logging 19 | log_level = args.log_level.strip() 20 | try: 21 | logging.basicConfig(level=eval('logging.%s' % log_level)) 22 | except AttributeError: 23 | raise RuntimeError('No such log level: %s' % log_level) 24 | 25 | if args.comms == 'katcp': 26 | HOSTCLASS = CasperFpga 27 | else: 28 | HOSTCLASS = dcp_fpga.DcpFpga 29 | 30 | # create the device and connect to it 31 | xeng_fpga = HOSTCLASS(args.host) 32 | xeng_fpga.get_system_information() 33 | 34 | snapdata = xeng_fpga.snapshots.snap_inreord0_ss.read(man_valid=True, circular_capture=True)['data'] 35 | #snapdata = xeng_fpga.snapshots.snap_inreord0_ss.read(man_valid=True)['data'] 36 | #snapdata = xeng_fpga.snapshots.snap_inreord0_ss.read()['data'] 37 | snapkeys = snapdata.keys() 38 | snaplen = len(snapdata[snapkeys[0]]) 39 | print('Read %d values from snapblock\n' % snaplen 40 | for ctr in range(0, snaplen): 41 | print('%5d:' % ctr, 42 | for key in snapkeys: 43 | if (snapdata['oc_rden'][ctr] == 1) and (snapdata['out_recv'][ctr] == 0): 44 | missingpainahfuck = True 45 | else: 46 | missingpainahfuck = False 47 | print('%s(%d) ' % (key, snapdata[key][ctr]), 48 | print('%s' % 'MISSING PAIN AH FUCK' if missingpainahfuck == True else 'A-OKAY' 49 | print(50 * '*' 50 | 51 | xeng_fpga.disconnect() 52 | 53 | # end 54 | -------------------------------------------------------------------------------- /unused_src/fengine.py: -------------------------------------------------------------------------------- 1 | """ 2 | @author: paulp 3 | """ 4 | 5 | import logging 6 | from engine import Engine 7 | 8 | LOGGER = logging.getLogger(__name__) 9 | 10 | 11 | class Fengine(Engine): 12 | """ 13 | A Frequency Engine. 14 | Channelises data from an antenna. 15 | """ 16 | 17 | def __init__(self, host_device, engine_id, ant_id, config_source): 18 | """ 19 | :param ant_id: antenna input identity of data being processed 20 | :return: 21 | """ 22 | 23 | raise NotImplementedError 24 | 25 | Engine.__init__(self, host_device, engine_id, config_source) 26 | self.ant_id = ant_id 27 | 28 | # check that we have all the required attributes for an f-engine 29 | assert hasattr(self, 'sample_bits'), 'f-engine must have the number of bits the ADC data uses' 30 | assert hasattr(self, 'adc_demux_factor'), 'f-engine must have the ADC demux factor (how many ADC samples' \ 31 | 'we receive in parallel)' 32 | assert hasattr(self, 'bandwidth'), 'f-engine must have a specified bandwidth that is processed (from baseband)' 33 | assert hasattr(self, 'true_cf'), 'f-engine must have a specified center frequency' 34 | assert hasattr(self, 'n_chans'), 'f-engine must have a specified number of output channels' 35 | assert hasattr(self, 'min_load_time'), 'f-engine must have a minimum load time for delay tracking' 36 | assert hasattr(self, 'network_latency_adjust'), 'f-engine, network_latency_adjust config item missing' 37 | 38 | def set_delay(self, delay=0, delay_delta=0, phase=0, phase_delta=0, load_time=None): 39 | """ Apply delay correction coefficients to polarisation specified from time specified 40 | @param delay: delay in samples 41 | @param delay_delta: change in delay in samples per ADC sample 42 | @param phase: initial phase offset TODO units 43 | @param phase_delta: change in phase TODO units 44 | @param load_time: time to load values in ADC samples since epoch. If None load immediately 45 | """ 46 | raise NotImplementedError 47 | 48 | # end 49 | -------------------------------------------------------------------------------- /src/log.py: -------------------------------------------------------------------------------- 1 | import logging 2 | 3 | 4 | class Corr2LogHandler(logging.Handler): 5 | """ 6 | Log handler for corr2 log messages 7 | """ 8 | 9 | def __init__(self, max_len=1000): 10 | """ 11 | Create a Corr2LogHandler. 12 | :param max_len: how many log messages should be stored in the FIFO 13 | :return: 14 | """ 15 | raise DeprecationWarning 16 | logging.Handler.__init__(self) 17 | self._max_len = max_len 18 | self._records = [] 19 | 20 | def emit(self, record): 21 | """ 22 | Handle the arrival of a log message. 23 | """ 24 | if len(self._records) >= self._max_len: 25 | self._records.pop(0) 26 | self._records.append(record) 27 | 28 | def clear_log(self): 29 | """ 30 | Clear the log messages the handler is storing. 31 | """ 32 | self._records = [] 33 | 34 | def set_max_len(self, max_len): 35 | """ 36 | Change the maximum number of log messages this handler stores. 37 | :param max_len: 38 | :return: 39 | """ 40 | self._max_len = max_len 41 | 42 | def get_log_strings(self, num_to_print=-1): 43 | """ 44 | Get the log record as strings 45 | :return: 46 | """ 47 | log_list = [] 48 | for ctr, record in enumerate(self._records): 49 | if ctr == num_to_print: 50 | break 51 | if record.exc_info: 52 | log_list.append('%s: %s Exception: ' % (record.name, record.msg)) 53 | else: 54 | log_list.append('%s: %s' % (record.name, record.msg)) 55 | return log_list 56 | 57 | def print_messages(self, num_to_print=-1): 58 | """ 59 | Print the last num_to_print(messages. -1 is all of them. 60 | :return: 61 | """ 62 | for ctr, record in enumerate(self._records): 63 | if ctr == num_to_print: 64 | break 65 | if record.exc_info: 66 | print('%s: %s Exception: ' % (record.name, record.msg)) 67 | else: 68 | print('%s: %s' % (record.name, record.msg)) 69 | -------------------------------------------------------------------------------- /debug/test_f_tx.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Mon Apr 14 17:06:22 2014 4 | 5 | @author: paulp 6 | """ 7 | 8 | from corr2.katcp_client_fpga import KatcpClientFpga 9 | from corr2.fpgadevice import tengbe 10 | import corr2.misc as misc 11 | 12 | import time 13 | 14 | hostname = 'roach02091b' 15 | 16 | fpga = KatcpClientFpga(hostname) 17 | fpga.get_system_information() 18 | 19 | packet_length = 128 + 5 + 4 20 | 21 | read_counter = 0 22 | while True: 23 | coredata = fpga.tengbes.gbe0.read_txsnap() 24 | errors = {} 25 | errors['valid'] = 0 26 | errors['packet_length'] = 0 27 | errors['data_step'] = 0 28 | num_packets = 0 29 | packet_counter = 0 30 | packet_lengths = [] 31 | for ctr in range(0, len(coredata[coredata.keys()[0]])): 32 | data = coredata['data'][ctr] 33 | eof = coredata['eof'][ctr] 34 | valid = coredata['valid'][ctr] 35 | if not valid: 36 | errors['valid'] += 1 37 | packet_counter += 1 38 | if eof: 39 | if packet_counter != packet_length: 40 | print(time.time(), 'AIIIIIIIIIIIEEEEEEEE - packet length should be %d, is actually %d - now %d errors' % (packet_length, packet_counter, errors['packet_length']) 41 | errors['packet_length'] += 1 42 | else: 43 | if packet_counter not in packet_lengths: 44 | packet_lengths.append(packet_counter) 45 | packet_counter = 0 46 | num_packets += 1 47 | if read_counter % 10 == 0: 48 | print(read_counter, 49 | read_counter += 1 50 | 51 | # if (errors['valid'] > 0) or (errors['packet_length'] > 1): 52 | # packet_counter = 0 53 | # for ctr in range(0, len(coredata[coredata.keys()[0]])): 54 | # data = coredata['data'][ctr] 55 | # eof = coredata['eof'][ctr] 56 | # valid = coredata['valid'][ctr] 57 | # print('%3d: vld(%1d) eof(%1d)' % (packet_counter, valid, eof) 58 | # packet_counter += 1 59 | # if eof: 60 | # packet_counter = 0 61 | # print(errors 62 | # break 63 | # read_counter += 1 64 | # print(read_counter, num_packets, packet_lengths 65 | -------------------------------------------------------------------------------- /debug/xeng_preprocess_snapshot.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # pylint: disable-msg=C0103 4 | # pylint: disable-msg=C0301 5 | """ 6 | @author: paulp 7 | """ 8 | import logging 9 | import argparse 10 | 11 | logger = logging.getLogger(__name__) 12 | #logging.basicConfig(level=logging.INFO) 13 | 14 | from casperfpga.katcp_fpga import KatcpFpga 15 | 16 | parser = argparse.ArgumentParser(description='Display reorder preprocess snapblock info.', 17 | formatter_class=argparse.ArgumentDefaultsHelpFormatter) 18 | parser.add_argument(dest='host', type=str, action='store', 19 | help='x-engine host') 20 | parser.add_argument('--eof', dest='eof', action='store_true', 21 | default=False, 22 | help='show only eofs') 23 | args = parser.parse_args() 24 | 25 | xeng_host = args.host 26 | 27 | # create the device and connect to it 28 | xeng_fpga = KatcpFpga(xeng_host) 29 | xeng_fpga.get_system_information() 30 | board_id = xeng_fpga.registers.board_id.read()['data']['reg'] 31 | numchans = 4096 32 | numx = 32 33 | fperx = numchans / numx 34 | frange = [] 35 | for bid in range(board_id, board_id + 4): 36 | fmin = bid * fperx 37 | fmax = fmin + fperx - 1 38 | frange.append((fmin, fmax)) 39 | print(frange 40 | snapdata = [] 41 | snapdata.append(xeng_fpga.snapshots.snap_unpack0_ss.read()['data']) 42 | snapdata.append(xeng_fpga.snapshots.snap_unpack1_ss.read()['data']) 43 | snapdata.append(xeng_fpga.snapshots.snap_unpack2_ss.read()['data']) 44 | snapdata.append(xeng_fpga.snapshots.snap_unpack3_ss.read()['data']) 45 | for ctr in range(0, len(snapdata[0]['eof'])): 46 | if (snapdata[0]['eof'][ctr] == 1) or (not args.eof): 47 | for bid, snap in enumerate(snapdata): 48 | assert snap['freq'][ctr] >= frange[bid][0] 49 | assert snap['freq'][ctr] <= frange[bid][1] 50 | print('valid(%i) fengid(%i) eof(%i) freq(%i) time(%i) |' % ( 51 | snap['valid'][ctr], 52 | snap['feng_id'][ctr], 53 | snap['eof'][ctr], 54 | snap['freq'][ctr], 55 | snap['time'][ctr], ), 56 | print('' 57 | 58 | # handle exits cleanly 59 | xeng_fpga.disconnect() 60 | # end 61 | -------------------------------------------------------------------------------- /debug/fengct_txips.py: -------------------------------------------------------------------------------- 1 | import IPython 2 | import time 3 | import feng_utils 4 | import casperfpga 5 | 6 | BASE_IP = int(casperfpga.network.IpAddress('239.2.1.64')) 7 | 8 | hosts = feng_utils.setup_fhosts() 9 | feng_utils.ct_tvg(hosts, 1) 10 | 11 | # check the error registers 12 | while True: 13 | try: 14 | feng_utils.print_err_regs(hosts) 15 | time.sleep(1) 16 | except KeyboardInterrupt: 17 | print('') 18 | break 19 | 20 | # read the snap 21 | man_trig = False 22 | man_valid = True 23 | circular_capture = False 24 | f = hosts[feng_utils.HOST_UUT] 25 | 26 | 27 | def calc_ip(d, ctr): 28 | xeng = d['d12'][ctr] / 256 29 | cip = BASE_IP + xeng + 2 30 | if cip > int(casperfpga.network.IpAddress('239.2.1.79')): 31 | cip -= 15 32 | cip = casperfpga.network.IpAddress(cip) 33 | return cip 34 | 35 | 36 | def get_snap_data(fpga, data=None, verbose=False): 37 | d = data or fpga.snapshots.txips_ss.read(man_trig=True)['data'] 38 | ip_errors = [] 39 | for ctr in range(len(d['dv'])): 40 | xeng = d['d12'][ctr] / 256 41 | ip = casperfpga.network.IpAddress(d['ip'][ctr]) 42 | cip = calc_ip(d, ctr) 43 | prtstr = '%5i d(%5i) xeng(%2i) calc_ip(%s) sent_ip(%s) dv(%i) eof(%i)' \ 44 | ' gbe_err(%i,%i,%i)' % ( 45 | ctr, d['d12'][ctr], xeng, cip, ip, d['dv'][ctr], 46 | d['eof'][ctr], d['gbe_full'][ctr], d['gbe_of'][ctr], 47 | d['gbe_txerr'][ctr]) 48 | if ip != cip: 49 | prtstr += ' IP_ERR(%s != %s)' % (ip, cip) 50 | ip_errors.append(ctr) 51 | if verbose: 52 | print(prtstr) 53 | return d, ip_errors 54 | 55 | loopctr = 0 56 | while True: 57 | tic = time.time() 58 | d = { 59 | host.host: get_snap_data(host) for host in hosts 60 | } 61 | toc = time.time() 62 | print loopctr, toc, toc - tic 63 | error = False 64 | for host in hosts: 65 | data, errors = d[host.host] 66 | if len(errors) > 0: 67 | errpos = errors[0] 68 | cip = calc_ip(data, errpos) 69 | txip = casperfpga.network.IpAddress(data['ip'][errpos]) 70 | print host.host, ':', errpos, cip, txip 71 | # get_snap_data(host, data, True) 72 | error = True 73 | if error: 74 | break 75 | 76 | # end 77 | -------------------------------------------------------------------------------- /debug/corr2_deprogram.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """ 3 | Deprogram one or more ROACHs. 4 | 5 | @author: paulp 6 | """ 7 | import argparse 8 | import os 9 | 10 | from casperfpga import utils as fpgautils 11 | from corr2 import utils 12 | 13 | parser = argparse.ArgumentParser( 14 | description='Deprogram one or more CASPER devices', 15 | formatter_class=argparse.ArgumentDefaultsHelpFormatter) 16 | parser.add_argument( 17 | '--hosts', dest='hosts', type=str, action='store', default='', 18 | help='comma-delimited list of hosts, or a corr2 config file') 19 | parser.add_argument( 20 | '--class', dest='hclass', action='store', default='', 21 | help='start/stop a class: fengine or xengine') 22 | parser.add_argument( 23 | '--dnsmasq', dest='dnsmasq', action='store_true', default=False, 24 | help='search for roach/skarab hostnames in /var/lib/misc/dnsmasq.leases') 25 | parser.add_argument( 26 | '--reboot', action='store_true', default=False, 27 | help='reboot roach in /var/lib/misc/dnsmasq.leases') 28 | parser.add_argument( 29 | '--loglevel', dest='log_level', action='store', default='', 30 | help='log level to use, default None, options INFO, DEBUG, ERROR') 31 | args = parser.parse_args() 32 | 33 | if args.log_level != '': 34 | import logging 35 | log_level = args.log_level.strip() 36 | try: 37 | logging.basicConfig(level=eval('logging.%s' % log_level)) 38 | except AttributeError: 39 | raise RuntimeError('No such log level: %s' % log_level) 40 | 41 | # look for hosts in the leases file 42 | if args.dnsmasq: 43 | hosts, lease_filename = fpgautils.hosts_from_dhcp_leases() 44 | print('Found %i roaches in %s.' % (len(hosts), lease_filename)) 45 | for host in hosts: 46 | print('\t%s' % host) 47 | else: 48 | # are we doing it by class? 49 | if 'CORR2INI' in os.environ.keys() and args.hosts == '': 50 | args.hosts = os.environ['CORR2INI'] 51 | if args.hclass != '': 52 | if args.hclass == 'fengine': 53 | hosts = utils.parse_hosts(args.hosts, section='fengine') 54 | elif args.hclass == 'xengine': 55 | hosts = utils.parse_hosts(args.hosts, section='xengine') 56 | else: 57 | raise RuntimeError('No such host class: %s' % args.hclass) 58 | else: 59 | hosts = utils.parse_hosts(args.hosts) 60 | 61 | fpgautils.deprogram_hosts(hosts) 62 | 63 | # end 64 | -------------------------------------------------------------------------------- /debug/fengct_out_bram.py: -------------------------------------------------------------------------------- 1 | import time 2 | import feng_utils 3 | import struct 4 | from casperfpga.network import IpAddress 5 | 6 | hosts = feng_utils.setup_hosts() 7 | # feng_utils.ct_tvg(hosts, 1) 8 | # feng_utils.print_err_regs(hosts) 9 | # feng_utils.bypass_cd(hosts, 1) 10 | 11 | findex = 0 12 | 13 | f = hosts[findex] 14 | 15 | ct_sync = f.registers.ct_sync_time.read()['data']['reg'] 16 | pack_sync = f.registers.pack_sync_time.read()['data']['reg'] 17 | print('CT sync time: %s' % ct_sync) 18 | print('Pack sync time: %s' % pack_sync) 19 | print('Diff: %i' % (pack_sync - ct_sync)) 20 | print('\nCtrl+C to continue...\n') 21 | 22 | while True: 23 | try: 24 | time.sleep(1) 25 | except KeyboardInterrupt: 26 | break 27 | 28 | 29 | def read_all(): 30 | out0 = f.read('gbe_out_bram0', 32768 * 8) 31 | out1 = f.read('gbe_out_bram1', 32768 * 16) 32 | out2 = f.read('gbe_out_bram2', 32768 * 16) 33 | out0 = struct.unpack('>32768Q', out0) 34 | out1_raw = struct.unpack('>65536Q', out1) 35 | out2_raw = struct.unpack('>65536Q', out2) 36 | out1 = [] 37 | out2 = [] 38 | for ctr in range(0, len(out1_raw), 2): 39 | out1.append((out1_raw[ctr], out1_raw[ctr + 1])) 40 | out2.append((out2_raw[ctr], out2_raw[ctr + 1])) 41 | return out0, out1, out2 42 | 43 | out0, out1, out2 = read_all() 44 | read_time = int(time.time()) 45 | 46 | 47 | def print_out_sync(): 48 | print('*' * 75) 49 | dvctr = 0 50 | for ctr in range(len(out0)): 51 | dv = (out0[ctr] >> 0) & 0x01 52 | of = (out0[ctr] >> 1) & 0x01 53 | eof = (out0[ctr] >> 2) & 0x01 54 | port = (out0[ctr] >> 3) & 0xffff 55 | ip = (out0[ctr] >> 19) & 0xffffffff 56 | ip = IpAddress(ip) 57 | sync = (out0[ctr] >> 51) & 0x01 58 | word_msb = (out1[ctr][0] << 64) + out1[ctr][1] 59 | word_lsb = (out2[ctr][0] << 64) + out2[ctr][1] 60 | prtstr = '%5i' % ctr 61 | prtstr += ' sync(%i) dv(%i) eof(%i) of(%i) ip(%s:%i) d(%032x, %032x) ' \ 62 | 'freq(%i)' % ( 63 | sync, dv, eof, of, str(ip), port, word_msb, 64 | word_lsb, word_lsb & 0xfff) 65 | if eof: 66 | prtstr += ' EOF' 67 | if of: 68 | prtstr += ' ERROR_OF' 69 | print(prtstr) 70 | if dv: 71 | dvctr += 1 72 | if sync: 73 | dvctr = 0 74 | 75 | import IPython 76 | IPython.embed() 77 | 78 | # end 79 | -------------------------------------------------------------------------------- /debug/fengct_dvout.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | import feng_utils 4 | 5 | findex = 0 6 | circ = False 7 | if len(sys.argv) > 1: 8 | findex = int(sys.argv[1]) 9 | if len(sys.argv) > 2: 10 | arg = sys.argv[2].strip() 11 | circ = arg == '1' 12 | 13 | hosts = feng_utils.setup_hosts() 14 | feng_utils.ct_tvg(hosts, 1) 15 | feng_utils.print_err_regs(hosts) 16 | 17 | 18 | def get_data(data=None, verbose=False, verbose_limits=(-1, -1)): 19 | # get a snapshot of the output 20 | if data is None: 21 | f = hosts[findex] 22 | d = data or f.snapshots.ct_dv_out_ss.read(man_trig=True, 23 | circular_capture=circ)['data'] 24 | dvs = [] 25 | for d128 in d['dv128']: 26 | dvs.extend(feng_utils.decode(d128, 128)) 27 | ctr = 0 28 | while dvs[ctr] == 1: 29 | ctr += 1 30 | dvs = dvs[ctr:] 31 | else: 32 | dvs = data 33 | one_lens = {} 34 | zero_lens = {} 35 | last_rising = -1 36 | last_falling = -1 37 | one_len_errors = [] 38 | for ctr in range(1, len(dvs)): 39 | prtstr = '%5i %i' % (ctr, dvs[ctr]) 40 | if (dvs[ctr] == 1) and (dvs[ctr - 1] == 0): 41 | # rising edge 42 | zlen = ctr - last_falling 43 | if zlen not in zero_lens: 44 | zero_lens[zlen] = 0 45 | zero_lens[zlen] += 1 46 | prtstr += ' ZLEN(%i)' % zlen 47 | last_rising = ctr 48 | elif (dvs[ctr] == 0) and (dvs[ctr - 1] == 1): 49 | # falling edge 50 | olen = ctr - last_rising 51 | if olen not in one_lens: 52 | one_lens[olen] = 0 53 | one_lens[olen] += 1 54 | prtstr += ' OLEN(%i)' % olen 55 | if olen != 32: 56 | one_len_errors.append(ctr) 57 | last_falling = ctr 58 | if verbose: 59 | if ((verbose_limits[0] == -1) or (ctr > verbose_limits[0])) and \ 60 | ((verbose_limits[1] == -1) or (ctr < verbose_limits[1])): 61 | print(prtstr) 62 | print('ONE_LENS: %s' % one_lens) 63 | print('ZERO_LENS: %s' % zero_lens) 64 | print('ONE_LEN_ERRORS: %s' % one_len_errors) 65 | return dvs, one_len_errors 66 | 67 | data, errors = get_data() 68 | if len(errors) > 0: 69 | err_start = errors[0] - 50 70 | err_end = err_start + 100 71 | a = get_data(data, True, (err_start, err_end)) 72 | 73 | import IPython 74 | IPython.embed() 75 | 76 | # end 77 | -------------------------------------------------------------------------------- /debug/skarab_feng_000_rx_pc.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | """ 4 | Check the SPEAD error counter and valid counter in the 5 | unpack section of the F-engines. 6 | 7 | @author: paulp 8 | """ 9 | import logging 10 | import socket 11 | import struct 12 | 13 | from casperfpga import spead as casperspead 14 | 15 | logging.basicConfig(level=logging.INFO) 16 | 17 | # open a RX socket and bind to the port 18 | sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 19 | sock.settimeout(1) 20 | sock.bind(('', 30000)) 21 | # receive a bunch of packets and save them in a list 22 | pkts = [] 23 | try: 24 | for ctr in range(100): 25 | pkts.append(sock.recvfrom(10000)) 26 | except socket.timeout: 27 | raise RuntimeError('ERROR: socket timed out waiting for ' 28 | 'packets from TX FPGA.') 29 | finally: 30 | sock.close() 31 | 32 | for ctr, pkt in enumerate(pkts): 33 | print(ctr, len(pkt[0])) 34 | 35 | pkt_len = len(pkts[0][0]) 36 | 37 | # format the packets into gbe_packets 38 | gbe_packets = [] 39 | for pkt in pkts: 40 | pkt64_wrong = struct.unpack('>%iQ' % (pkt_len/8), pkt[0]) 41 | pkt64 = [] 42 | for ctr in range(0, len(pkt64_wrong), 4): 43 | tmp = [pkt64_wrong[ctr+3], pkt64_wrong[ctr+2], 44 | pkt64_wrong[ctr+1], pkt64_wrong[ctr+0]] 45 | pkt64.extend(tmp) 46 | gbe_packets.append(pkt64) 47 | 48 | # process SPEAD 49 | spead_processor = casperspead.SpeadProcessor() 50 | spead_processor.process_data(gbe_packets) 51 | 52 | # sort the packets 53 | sorted_packets = [spead_processor.packets[0]] 54 | for ctr, packet in enumerate(spead_processor.packets[1:]): 55 | for ctr2, sp in enumerate(sorted_packets): 56 | if packet.headers[0x1600] <= sp.headers[0x1600]: 57 | break 58 | sorted_packets = sorted_packets[0:ctr2] + [packet] + sorted_packets[ctr2:] 59 | 60 | # check the packets for the ramp 61 | last_hdr_time = 0 62 | for ctr, packet in enumerate(sorted_packets): 63 | prtstr = '%5i' % ctr 64 | prtstr += ' %16i' % packet.headers[0x1600] 65 | prtstr += ' %10i' % (packet.headers[0x1600] - last_hdr_time) 66 | prtstr += ' pol%1i' % packet.headers[0x3101] 67 | last_hdr_time = packet.headers[0x1600] 68 | if packet.headers[0x1600] != packet.headers[0x1]: 69 | prtstr += ' ID_ERROR' 70 | if packet.data != range(640): 71 | prtstr += ' DATA_ERROR' 72 | print(prtstr) 73 | import IPython 74 | IPython.embed() 75 | 76 | import IPython 77 | IPython.embed() 78 | 79 | # end 80 | -------------------------------------------------------------------------------- /debug/corr2_ping_hosts.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | """ 4 | Ping a list of hosts by connecting to them. 5 | 6 | @author: paulp 7 | """ 8 | import time 9 | import argparse 10 | 11 | from casperfpga import utils as fpgautils 12 | from corr2 import utils 13 | 14 | parser = argparse.ArgumentParser( 15 | description='Ping a list of hosts by connecting to them.', 16 | formatter_class=argparse.ArgumentDefaultsHelpFormatter) 17 | parser.add_argument('--hosts', dest='hosts', type=str, action='store', 18 | default='', help='comma-delimited list of hosts') 19 | parser.add_argument('--config', type=str, action='store', default='', help= 20 | 'corr2 config file. (default: Use CORR2INI env var)') 21 | parser.add_argument('--loglevel', dest='log_level', action='store', default='', 22 | help='log level to use, default None, options INFO, ' 23 | 'DEBUG, ERROR') 24 | args = parser.parse_args() 25 | 26 | raise RuntimeError('Not working with Skarabs yet.') 27 | 28 | if args.log_level != '': 29 | import logging 30 | log_level = args.log_level.strip() 31 | try: 32 | logging.basicConfig(level=eval('logging.%s' % log_level)) 33 | except AttributeError: 34 | raise RuntimeError('No such log level: %s' % log_level) 35 | 36 | 37 | def pingfpga(fpga): 38 | timeout = 0.5 39 | stime = time.time() 40 | while (not fpga.is_connected()) and (time.time() - stime < timeout): 41 | time.sleep(0.1) 42 | fpga.connect() 43 | if not fpga.is_connected(): 44 | return 'unavailable' 45 | try: 46 | fpga.test_connection() 47 | return 'programmed' 48 | except: 49 | return 'connected' 50 | 51 | # create the devices and connect to them 52 | fpgas = utils.script_get_fpgas(args) 53 | 54 | # ping them 55 | connected = [] 56 | programmed = [] 57 | unavailable = [] 58 | responses = fpgautils.threaded_fpga_operation(fpgas, 10, pingfpga) 59 | for host, response in responses.items(): 60 | if response == 'unavailable': 61 | unavailable.append(host) 62 | elif response == 'programmed': 63 | programmed.append(host) 64 | elif response == 'connected': 65 | connected.append(host) 66 | 67 | fpgautils.threaded_fpga_function(fpgas, 10, 'disconnect') 68 | 69 | sconn = set(connected) 70 | sprog = set(programmed) 71 | connected = list(sconn.difference(sprog)) 72 | print('%d hosts:' % len(fpgas)) 73 | print('\tProgrammed: %s' % programmed) 74 | print('\tConnected: %s' % connected) 75 | print('\tUnavailable: %s' % unavailable) 76 | 77 | # end 78 | -------------------------------------------------------------------------------- /debug/spead2test.py: -------------------------------------------------------------------------------- 1 | import spead2 2 | import spead2.send as sptx 3 | import numpy 4 | 5 | ig = sptx.ItemGroup(flavour=spead2.Flavour(4, 64, 48)) 6 | 7 | streamconfig = sptx.StreamConfig(max_packet_size=9200, 8 | max_heaps=8) 9 | speadstream = sptx.UdpStream(spead2.ThreadPool(), 10 | '127.0.0.1', 11 | 7890, 12 | streamconfig, 13 | 51200000) 14 | 15 | # how is one meant to send single-value numpy.dtypes? as below? 16 | ig.add_item(name='a_number', id=0x1025, 17 | description='A 32-bit unsigned number.', 18 | shape=(), 19 | dtype=numpy.uint32, 20 | value=17) 21 | 22 | # this works, too 23 | ig.add_item(name='another_number', id=0x1026, 24 | description='Another number.', 25 | shape=[], 26 | format=[('u', 32)], 27 | value=18) 28 | 29 | # this one breaks the receiver 30 | str_to_send = numpy.array('i am string, hear me roar') 31 | ig.add_item(name='a_first_string', id=0x1027, 32 | description='a string that we need to send', 33 | shape=str_to_send.shape, 34 | dtype=str_to_send.dtype, 35 | value=str_to_send) 36 | 37 | # this one is okay 38 | str_to_send = 'i am only a secondstring' 39 | ig.add_item(name='a_nother_string', id=0x1028, 40 | description='a string that we do not need to send', 41 | shape=(None,), 42 | format=[('c', 8)], 43 | value=str_to_send) 44 | 45 | # list of strings? 46 | alistofstrings = ['this is a string', 'this is a string as well'] 47 | b = numpy.array(alistofstrings) 48 | ig.add_item(name='list_of_strings', id=0x1029, 49 | description='a list of strings', 50 | shape=b.shape, 51 | dtype=b.dtype, 52 | value=b) 53 | 54 | # list of numbers 55 | alist = [1, 2, 3, 4] 56 | b = numpy.array(alist) 57 | ig.add_item(name='alistofnumbers', id=0x1030, 58 | description='A list of numbers?', 59 | shape=b.shape, 60 | dtype=b.dtype, 61 | value=b) 62 | 63 | heap = ig.get_heap() 64 | 65 | speadstream.send_heap(heap) 66 | 67 | print('sent heapspead2test.py' 68 | 69 | # list of strings? 70 | alistofstrings = ['so short', 'abcde'] 71 | b = numpy.array(alistofstrings) 72 | ig.add_item(name='list_of_strings', id=0x1029, 73 | description='a list of strings', 74 | shape=b.shape, 75 | dtype=b.dtype, 76 | value=b) 77 | 78 | heap = ig.get_heap() 79 | 80 | speadstream.send_heap(heap) 81 | 82 | 83 | print('sent heap again' 84 | -------------------------------------------------------------------------------- /debug/digitiser_receiver.py: -------------------------------------------------------------------------------- 1 | import logging 2 | import time 3 | 4 | import casperfpga 5 | from casperfpga.transport_skarab import SkarabTransport, \ 6 | SkarabReorderError, SkarabReorderWarning 7 | 8 | from host_fpga import FpgaHost 9 | 10 | LOGGER = logging.getLogger(__name__) 11 | 12 | 13 | class DigitiserStreamReceiver(FpgaHost): 14 | """ 15 | The RX section of a fengine and filter engine are the same - receive 16 | the digitiser data. 17 | """ 18 | def __init__(self, host, katcp_port=7147, bitstream=None, connect=True): 19 | super(DigitiserStreamReceiver, self).__init__( 20 | host=host, katcp_port=katcp_port, bitstream=bitstream, 21 | connect=connect, transport=SkarabTransport) 22 | 23 | def get_rx_reorder_status(self): 24 | """ 25 | Read the reorder block counters 26 | :return: 27 | """ 28 | if 'reorder_ctrs' in self.registers.names(): 29 | reorder_ctrs = self.registers.reorder_ctrs.read()['data'] 30 | LOGGER.debug('found reorder_ctrs') 31 | else: 32 | reorder_ctrs = self.registers.reorder_status.read()['data'] 33 | LOGGER.debug('found reorder_status'.format(reorder_ctrs)) 34 | try: 35 | reorder_ctrs.update(self.registers.reorder_status1.read()['data']) 36 | LOGGER.debug('found reorder_status1'.format(reorder_ctrs)) 37 | except (AttributeError, KeyError): 38 | pass 39 | return reorder_ctrs 40 | 41 | def get_local_time(self): 42 | """ 43 | Get the local timestamp of this board, received from the digitiser 44 | :return: time in samples since the digitiser epoch 45 | """ 46 | _msw = self.registers.local_time_msw 47 | _lsw = self.registers.local_time_lsw 48 | first_msw = _msw.read()['data']['timestamp_msw'] 49 | while _msw.read()['data']['timestamp_msw'] == first_msw: 50 | time.sleep(0.01) 51 | lsw = _lsw.read()['data']['timestamp_lsw'] 52 | msw = _msw.read()['data']['timestamp_msw'] 53 | if msw != first_msw + 1: 54 | raise RuntimeError( 55 | '%s get_local_time() - network is too slow to allow accurate ' 56 | 'time read (%i -> %i)' % (self.host, first_msw, msw)) 57 | rv = (msw << 32) | lsw 58 | return rv 59 | 60 | def clear_status(self): 61 | """ 62 | Clear the status registers and counters on this host 63 | :return: 64 | """ 65 | self.registers.control.write(status_clr='pulse', gbe_cnt_rst='pulse', 66 | cnt_rst='pulse') 67 | # self.registers.control.write(gbe_cnt_rst='pulse') 68 | LOGGER.debug('{}: status cleared.'.format(self.host)) 69 | 70 | # end 71 | -------------------------------------------------------------------------------- /debug/xeng_reord_snapshot.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # pylint: disable-msg=C0103 4 | # pylint: disable-msg=C0301 5 | """ 6 | @author: paulp 7 | """ 8 | import argparse 9 | 10 | 11 | parser = argparse.ArgumentParser(description='Display reorder preprocess snapblock info.', 12 | formatter_class=argparse.ArgumentDefaultsHelpFormatter) 13 | parser.add_argument(dest='host', type=str, action='store', 14 | help='x-engine host') 15 | parser.add_argument('--eof', dest='eof', action='store_true', 16 | default=False, 17 | help='show only eofs') 18 | parser.add_argument('--comms', dest='comms', action='store', default='katcp', type=str, 19 | help='katcp (default) or dcp?') 20 | parser.add_argument('--loglevel', dest='log_level', action='store', default='', 21 | help='log level to use, default None, options INFO, DEBUG, ERROR') 22 | args = parser.parse_args() 23 | 24 | if args.log_level != '': 25 | import logging 26 | log_level = args.log_level.strip() 27 | try: 28 | logging.basicConfig(level=eval('logging.%s' % log_level)) 29 | except AttributeError: 30 | raise RuntimeError('No such log level: %s' % log_level) 31 | 32 | if args.comms == 'katcp': 33 | HOSTCLASS = CasperFpga 34 | else: 35 | HOSTCLASS = dcp_fpga.DcpFpga 36 | 37 | xeng_host = args.host 38 | 39 | # create the device and connect to it 40 | xeng_fpga = HOSTCLASS(xeng_host) 41 | xeng_fpga.get_system_information() 42 | board_id = xeng_fpga.registers.board_id.read()['data']['reg'] 43 | numchans = 4096 44 | numx = 32 45 | fperx = numchans / numx 46 | frange = [] 47 | for bid in range(board_id, board_id + 4): 48 | fmin = bid * fperx 49 | fmax = fmin + fperx - 1 50 | frange.append((fmin, fmax)) 51 | print(frange 52 | snapdata = [] 53 | snapdata.append(xeng_fpga.snapshots.snap_unpack0_ss.read()['data']) 54 | # snapdata.append(xeng_fpga.snapshots.snap_unpack1_ss.read()['data']) 55 | # snapdata.append(xeng_fpga.snapshots.snap_unpack2_ss.read()['data']) 56 | # snapdata.append(xeng_fpga.snapshots.snap_unpack3_ss.read()['data']) 57 | for ctr in range(0, len(snapdata[0]['eof'])): 58 | if (snapdata[0]['eof'][ctr] == 1) or (not args.eof): 59 | for bid, snap in enumerate(snapdata): 60 | assert snap['freq'][ctr] >= frange[bid][0] 61 | assert snap['freq'][ctr] <= frange[bid][1] 62 | print('valid(%i) fengid(%i) eof(%i) freq(%i) time(%i) |' % ( 63 | snap['valid'][ctr], 64 | snap['feng_id'][ctr], 65 | snap['eof'][ctr], 66 | snap['freq'][ctr], 67 | snap['time'][ctr], ), 68 | print('' 69 | 70 | # handle exits cleanly 71 | xeng_fpga.disconnect() 72 | # end 73 | -------------------------------------------------------------------------------- /debug/corr2_issue_spead_metadata.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | """ 4 | Issue spead metadata for a data product. 5 | 6 | BE CAREFUL WITH THIS! Much metadata will change as the instrument is 7 | set up and used. These changes WILL NOT REFLECT in a base instrument created 8 | from the config file, which is what this will give you. 9 | 10 | It is recommended that you use ?capture-meta against your running instrument! 11 | 12 | @author: paulp 13 | """ 14 | import argparse 15 | import os 16 | 17 | from corr2 import fxcorrelator 18 | 19 | parser = argparse.ArgumentParser( 20 | description='Issue SPEAD metadata for a data product on this instrument.', 21 | formatter_class=argparse.ArgumentDefaultsHelpFormatter) 22 | parser.add_argument( 23 | '-product', dest='product', action='store', default='', 24 | help='the name of the product on which to act') 25 | parser.add_argument( 26 | '--listproducts', dest='listproducts', action='store_true', default=False, 27 | help='list available products and exit') 28 | parser.add_argument( 29 | '--config', dest='config', type=str, action='store', 30 | default='', help='corr2 config file') 31 | parser.add_argument( 32 | '--ipython', dest='ipython', action='store_true', default=False, 33 | help='start an ipython session after completion/error') 34 | parser.add_argument( 35 | '--loglevel', dest='log_level', action='store', 36 | default='INFO', 37 | help='log level to use, default None, options INFO, DEBUG, ERROR') 38 | args = parser.parse_args() 39 | 40 | if args.log_level != '': 41 | import logging 42 | log_level = args.log_level.strip() 43 | try: 44 | logging.basicConfig(level=eval('logging.%s' % log_level)) 45 | except AttributeError: 46 | raise RuntimeError('No such log level: %s' % log_level) 47 | 48 | if 'CORR2INI' in os.environ.keys() and args.config == '': 49 | args.config = os.environ['CORR2INI'] 50 | 51 | # make the correlator object and send the metadata 52 | c = fxcorrelator.FxCorrelator('corr', config_source=args.config) 53 | c.standard_log_config() 54 | c.initialise(program=False) 55 | 56 | prod_list = [] 57 | 58 | if args.product == '': 59 | prod_list = c.data_products.values() 60 | else: 61 | if args.product not in c.data_products: 62 | print('ERROR: %s not in data products for this ' 63 | 'instrument.' % args.product) 64 | else: 65 | prod_list = [c.data_products[args.product]] 66 | 67 | if args.listproducts or (len(prod_list) == 0): 68 | print('Available products:') 69 | for prod in c.data_products.values(): 70 | print('\t%s' % prod) 71 | import sys 72 | sys.exit() 73 | 74 | for prod in prod_list: 75 | prod.meta_issue() 76 | 77 | if args.ipython: 78 | import IPython 79 | IPython.embed() 80 | 81 | # end 82 | -------------------------------------------------------------------------------- /debug/corr2_program.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """ 3 | Program one or more ROACHs. 4 | 5 | @author: paulp 6 | """ 7 | import argparse 8 | import os 9 | 10 | from casperfpga import utils as fpgautils 11 | from corr2 import utils 12 | 13 | parser = argparse.ArgumentParser( 14 | description='Program one or more CASPER devices', 15 | formatter_class=argparse.ArgumentDefaultsHelpFormatter) 16 | parser.add_argument( 17 | '--hosts', dest='hosts', type=str, action='store', default='', 18 | help='comma-delimited list of hosts, or a corr2 config file') 19 | parser.add_argument( 20 | '--dnsmasq', dest='dnsmasq', action='store_true', default=False, 21 | help='search for roach hostnames in /var/lib/misc/dnsmasq.leases') 22 | parser.add_argument( 23 | '--comms', dest='comms', action='store', default='katcp', type=str, 24 | help='katcp (default) or dcp?') 25 | parser.add_argument( 26 | '--loglevel', dest='log_level', action='store', default='', 27 | help='log level to use, default None, options INFO, DEBUG, ERROR') 28 | parser.add_argument( 29 | dest='fpg', action='store', default='', 30 | help='.fpg file to program') 31 | args = parser.parse_args() 32 | 33 | raise RuntimeError('Not working with Skarabs yet.') 34 | 35 | if args.log_level != '': 36 | import logging 37 | log_level = args.log_level.strip() 38 | try: 39 | logging.basicConfig(level=eval('logging.%s' % log_level)) 40 | except AttributeError: 41 | raise RuntimeError('No such log level: %s' % log_level) 42 | 43 | # look for hosts in the leases file 44 | if args.dnsmasq: 45 | hosts, lease_filename = utils.hosts_from_dhcp_leases() 46 | print('Found %i roaches in %s.' % (len(hosts), lease_filename)) 47 | for host in hosts: 48 | print('\t%s' % host) 49 | else: 50 | # are we doing it by class? 51 | if 'CORR2INI' in os.environ.keys() and args.hosts == '': 52 | args.hosts = os.environ['CORR2INI'] 53 | if args.hclass != '': 54 | if args.hclass == 'fengine': 55 | hosts = utils.parse_hosts(args.hosts, section='fengine') 56 | elif args.hclass == 'xengine': 57 | hosts = utils.parse_hosts(args.hosts, section='xengine') 58 | else: 59 | raise RuntimeError('No such host class: %s' % args.hclass) 60 | else: 61 | hosts = utils.parse_hosts(args.hosts) 62 | 63 | if len(hosts) == 0: 64 | raise RuntimeError('No good carrying on without hosts.') 65 | 66 | # create the devices and program them 67 | fpgas = fpgautils.threaded_create_fpgas_from_hosts(hosts) 68 | running = fpgautils.threaded_fpga_function(fpgas, 10, 'is_running') 69 | fpgautils.threaded_fpga_function(fpgas, 10, 70 | 'upload_to_ram_and_program', args.fpg) 71 | fpgautils.threaded_fpga_function(fpgas, 10, 'disconnect') 72 | 73 | # end 74 | -------------------------------------------------------------------------------- /debug/plot_line2.py: -------------------------------------------------------------------------------- 1 | import matplotlib as mpl 2 | mpl.use('TkAgg') 3 | import matplotlib.pyplot as plt 4 | import numpy as np 5 | import time 6 | import sys 7 | 8 | DATA_LEN = 32768 9 | TIME_START = 0 10 | ION = False 11 | DONE = False 12 | 13 | # import matplotlib.rcsetup as rcsetup 14 | # print(rcsetup.all_backends) 15 | 16 | assert mpl.rcParams['backend'] == 'TkAgg' 17 | 18 | 19 | class Corr2Plot(object): 20 | 21 | def __init__(self, figure, data_source, plot_function, animated=True): 22 | 23 | self.figure = figure 24 | self.data_source = data_source 25 | self.plot_function = plot_function 26 | self.animated = animated 27 | self.done = None 28 | 29 | self.figure.canvas.mpl_connect('close_event', self.on_close) 30 | self.figure.canvas.mpl_connect('key_release_event', self.redraw) 31 | 32 | def run(self): 33 | self.done = False 34 | self.figure.canvas.manager.window.after(50, self.plot_function, self) 35 | try: 36 | plt.show() 37 | except AttributeError: 38 | pass 39 | 40 | def redraw(self, key_event): 41 | if self.animated: 42 | return 43 | if key_event.key == 'x': 44 | self.figure.canvas.manager.window.after( 45 | 50, self.plot_function, self) 46 | 47 | def on_close(self, close_event): 48 | self.done = True 49 | 50 | def running(self): 51 | return not self.done 52 | 53 | 54 | def tic(task): 55 | global TICTOC 56 | TICTOC = (time.time(), task) 57 | 58 | 59 | def toc(): 60 | global TICTOC 61 | print('tictoc \'%s\'' % TICTOC[1], time.time() - TICTOC[0] 62 | sys.stdout.flush() 63 | 64 | 65 | def get_data(): 66 | time.sleep(np.random.rand() * 2) 67 | return np.random.randn(DATA_LEN), np.random.randn(DATA_LEN) 68 | 69 | 70 | def plot_func(plot_object): 71 | figure = plot_object.figure 72 | 73 | tic('get_data') 74 | (a, b) = plot_object.data_source() 75 | toc() 76 | 77 | figure.axes[0].clear() 78 | figure.axes[1].clear() 79 | 80 | tic('plotting') 81 | figure.axes[0].plot(a) 82 | figure.axes[1].plot(b) 83 | toc() 84 | 85 | figure.axes[0].grid(True) 86 | figure.axes[1].grid(True) 87 | 88 | tic('canvas_draw') 89 | figure.canvas.draw() 90 | toc() 91 | 92 | if plot_object.animated: 93 | figure.canvas.manager.window.after(10, plot_func, plot_object) 94 | 95 | 96 | fig = plt.figure() 97 | fig.add_subplot(2, 1, 1) 98 | fig.add_subplot(2, 1, 2) 99 | 100 | c2plt = Corr2Plot(fig, get_data, plot_func, True) 101 | c2plt.run() 102 | 103 | while True: 104 | try: 105 | if not c2plt.running(): 106 | break 107 | time.sleep(0.5) 108 | except KeyboardInterrupt: 109 | break 110 | -------------------------------------------------------------------------------- /debug/plot_line3.py: -------------------------------------------------------------------------------- 1 | import matplotlib as mpl 2 | mpl.use('TkAgg') 3 | import matplotlib.pyplot as plt 4 | import numpy as np 5 | import time 6 | import sys 7 | 8 | DATA_LEN = 32768 9 | TIME_START = 0 10 | ION = False 11 | DONE = False 12 | 13 | # import matplotlib.rcsetup as rcsetup 14 | # print(rcsetup.all_backends) 15 | 16 | assert mpl.rcParams['backend'] == 'TkAgg' 17 | 18 | 19 | class Corr2Plot(object): 20 | 21 | def __init__(self, figure, data_source, plot_function, animated=True): 22 | 23 | self.figure = figure 24 | self.data_source = data_source 25 | self.plot_function = plot_function 26 | self.animated = animated 27 | self.done = None 28 | 29 | self.figure.canvas.mpl_connect('close_event', self.on_close) 30 | self.figure.canvas.mpl_connect('key_release_event', self.redraw) 31 | 32 | def run(self): 33 | self.done = False 34 | self.figure.canvas.manager.window.after(50, self.plot_function, self) 35 | try: 36 | plt.show() 37 | except AttributeError: 38 | pass 39 | 40 | def redraw(self, key_event): 41 | if self.animated: 42 | return 43 | if key_event.key == 'x': 44 | self.figure.canvas.manager.window.after( 45 | 50, self.plot_function, self) 46 | 47 | def on_close(self, close_event): 48 | self.done = True 49 | 50 | def running(self): 51 | return not self.done 52 | 53 | 54 | def tic(task): 55 | global TICTOC 56 | TICTOC = (time.time(), task) 57 | 58 | 59 | def toc(): 60 | global TICTOC 61 | print('tictoc \'%s\'' % TICTOC[1], time.time() - TICTOC[0] 62 | sys.stdout.flush() 63 | 64 | 65 | def get_data(): 66 | time.sleep(np.random.rand() * 2) 67 | return np.random.randn(DATA_LEN), np.random.randn(DATA_LEN) 68 | 69 | 70 | def plot_func(plot_object): 71 | figure = plot_object.figure 72 | 73 | tic('get_data') 74 | (a, b) = plot_object.data_source() 75 | toc() 76 | 77 | figure.axes[0].clear() 78 | figure.axes[1].clear() 79 | 80 | tic('plotting') 81 | figure.axes[0].plot(a) 82 | figure.axes[1].plot(b) 83 | toc() 84 | 85 | figure.axes[0].grid(True) 86 | figure.axes[1].grid(True) 87 | 88 | tic('canvas_draw') 89 | figure.canvas.draw() 90 | toc() 91 | 92 | if plot_object.animated: 93 | figure.canvas.manager.window.after(10, plot_func, plot_object) 94 | 95 | 96 | fig = plt.figure() 97 | fig.add_subplot(1, 1, 1) 98 | plt.show() 99 | 100 | loop_ctr = 0 101 | while True: 102 | try: 103 | 104 | fig = plt.figure() 105 | fig.add_subplot(1, 1, 1) 106 | plt.show() 107 | 108 | print('bip', loop_ctr 109 | loop_ctr += 1 110 | time.sleep(0.5) 111 | except KeyboardInterrupt: 112 | break 113 | -------------------------------------------------------------------------------- /debug/mcast.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # Send/receive UDP multicast packets. 4 | # Requires that your OS kernel supports IP multicast. 5 | # 6 | # Usage: 7 | # mcast -s (sender, IPv4) 8 | # mcast -s -6 (sender, IPv6) 9 | # mcast (receivers, IPv4) 10 | # mcast -6 (receivers, IPv6) 11 | 12 | MYPORT = 8888 13 | #MYPORT = 7148 14 | #MYGROUP_4 = '225.0.1.100' 15 | #MYGROUP_4 = '239.0.0.68' 16 | MYGROUP_4 = '239.2.0.100' 17 | MYGROUP_6 = 'ff15:7079:7468:6f6e:6465:6d6f:6d63:6173' 18 | MYTTL = 1 # Increase to reach other networks 19 | BIND_ADDR = '10.100.0.1' 20 | #BIND_ADDR = '' # all interfaces 21 | 22 | import time 23 | import struct 24 | import socket 25 | import sys 26 | 27 | def main(): 28 | group = MYGROUP_6 if "-6" in sys.argv[1:] else MYGROUP_4 29 | 30 | if "-s" in sys.argv[1:]: 31 | sender(group) 32 | else: 33 | receiver(group) 34 | 35 | 36 | def sender(group): 37 | addrinfo = socket.getaddrinfo(group, None)[0] 38 | 39 | s = socket.socket(addrinfo[0], socket.SOCK_DGRAM) 40 | 41 | ## Bind it to the port 42 | #s.bind((BIND_ADDR, MYPORT)) 43 | 44 | 45 | # Set Time-to-live (optional) 46 | ttl_bin = struct.pack('@i', MYTTL) 47 | if addrinfo[0] == socket.AF_INET: # IPv4 48 | s.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, ttl_bin) 49 | else: 50 | s.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_MULTICAST_HOPS, ttl_bin) 51 | 52 | while True: 53 | data = repr(time.time()) 54 | s.sendto(data + '\0', (addrinfo[4][0], MYPORT)) 55 | #s.send(data + '\0',); 56 | time.sleep(1) 57 | 58 | 59 | def receiver(group): 60 | # Look up multicast group address in name server and find out IP version 61 | addrinfo = socket.getaddrinfo(group, None)[0] 62 | 63 | # Create a socket 64 | s = socket.socket(addrinfo[0], socket.SOCK_DGRAM) 65 | 66 | # Allow multiple copies of this program on one machine 67 | # (not strictly needed) 68 | s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 69 | 70 | # Bind it to the port 71 | s.bind((BIND_ADDR, MYPORT)) 72 | print("Receiver bound to address %s." % BIND_ADDR) 73 | 74 | group_bin = socket.inet_pton(addrinfo[0], addrinfo[4][0]) 75 | # Join group 76 | if addrinfo[0] == socket.AF_INET: # IPv4 77 | mreq = group_bin + struct.pack('=I', socket.INADDR_ANY) 78 | s.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq) 79 | print("Subscribing to %s." % group) 80 | else: 81 | mreq = group_bin + struct.pack('@I', 0) 82 | s.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_JOIN_GROUP, mreq) 83 | 84 | # Loop, printing any data we receive 85 | while True: 86 | data, sender = s.recvfrom(1500) 87 | while data[-1:] == '\0': data = data[:-1] # Strip trailing \0's 88 | print(str(sender) + ' ' + repr(data)) 89 | 90 | 91 | if __name__ == '__main__': 92 | main() 93 | 94 | 95 | -------------------------------------------------------------------------------- /debug/corr2_bf_partition_select.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | """ 4 | Issue spead metadata for this correlator 5 | 6 | @author: paulp 7 | """ 8 | import argparse 9 | import os 10 | 11 | from corr2 import fxcorrelator 12 | 13 | parser = argparse.ArgumentParser( 14 | description='Activate/deactivate partitions on the beamformer.', 15 | formatter_class=argparse.ArgumentDefaultsHelpFormatter) 16 | parser.add_argument( 17 | '--config', dest='config', type=str, action='store', 18 | default='', help='corr2 config file') 19 | # parser.add_argument( 20 | # '--beam', dest='beamname', type=str, action='store', default='', 21 | # help='beam on which to act, default: ALL beams') 22 | # parser.add_argument( 23 | # '--listbeams', dest='listbeams', action='store_true', default=False, 24 | # help='show the beams on this beamformer') 25 | parser.add_argument( 26 | '--activate', dest='activate', type=str, action='store', 27 | default='', help='the partitions to activate, a comma-separated list. e.g.' 28 | '3,4,5,6. all means ALL.') 29 | parser.add_argument( 30 | '--deactivate', dest='deactivate', type=str, action='store', 31 | default='', help='the partitions to deactivate, a comma-separated list. ' 32 | 'e.g. 7,8,9. all means ALL.') 33 | parser.add_argument( 34 | '--loglevel', dest='log_level', action='store', 35 | default='INFO', 36 | help='log level to use, default None, options INFO, DEBUG, ERROR') 37 | args = parser.parse_args() 38 | 39 | if args.log_level != '': 40 | import logging 41 | log_level = args.log_level.strip() 42 | try: 43 | logging.basicConfig(level=eval('logging.%s' % log_level)) 44 | except AttributeError: 45 | raise RuntimeError('No such log level: %s' % log_level) 46 | 47 | if 'CORR2INI' in os.environ.keys() and args.config == '': 48 | args.config = os.environ['CORR2INI'] 49 | 50 | if args.activate == '' and args.deactivate == '': 51 | raise RuntimeError('Cowardly refusing to do nothing!') 52 | elif args.activate == 'all' and args.deactivate == 'all': 53 | raise RuntimeError('Activate EVERYTHING and deactivate EVERYTHING? Que?') 54 | 55 | # make the correlator object and send the metadata 56 | c = fxcorrelator.FxCorrelator('corr', config_source=args.config) 57 | c.standard_log_config() 58 | c.initialise(program=False) 59 | 60 | if args.activate == 'all': 61 | c.bops.partitions_activate() 62 | elif args.activate != '': 63 | argslist = args.activate.strip().split(',') 64 | partlist = [int(arg) for arg in argslist] 65 | if len(partlist) > 0: 66 | c.bops.partitions_activate(partlist) 67 | 68 | if args.deactivate == 'all': 69 | c.bops.partitions_deactivate() 70 | elif args.deactivate != '': 71 | argslist = args.deactivate.strip().split(',') 72 | partlist = [int(arg) for arg in argslist] 73 | if len(partlist) > 0: 74 | c.bops.partitions_deactivate(partlist) 75 | 76 | # end 77 | -------------------------------------------------------------------------------- /debug/deng_check_unpack.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Thu May 8 15:35:52 2014 4 | 5 | @author: paulp 6 | """ 7 | 8 | import time 9 | import argparse 10 | 11 | 12 | dhost = 'roach020958' 13 | #fhosts = ['roach02091b', 'roach020914', 'roach020915', 'roach020922'] 14 | 15 | parser = argparse.ArgumentParser(description='Display the data unpack counters on the dengine.', 16 | formatter_class=argparse.ArgumentDefaultsHelpFormatter) 17 | parser.add_argument(dest='hosts', type=str, action='store', 18 | help='comma-delimited list of d-engine hosts') 19 | parser.add_argument('-p', '--polltime', dest='polltime', action='store', 20 | default=0.5, type=float, 21 | help='time at which to poll dengine data, in seconds') 22 | parser.add_argument('-r', '--reset_count', dest='rstcnt', action='store_true', 23 | default=False, 24 | help='reset all counters at script startup') 25 | args = parser.parse_args() 26 | 27 | fdig = CasperFpga(dhost) 28 | fdig.get_system_information() 29 | if args.rstcnt: 30 | fdig.registers.control.write(cnt_rst='pulse') 31 | 32 | ffs = [] 33 | #for fhost in fhosts: 34 | # fpga = KatcpClientFpga(fhost) 35 | # fpga.get_system_information() 36 | # ffs.append(fpga) 37 | 38 | start_time = time.time() 39 | 40 | while True: 41 | got_errors = False 42 | print('%.2f' % (time.time() - start_time), 43 | for interface in [0,1,2,3]: 44 | errors = fdig.registers['up_err_%i' % interface].read()['data'] 45 | if (errors['cnt'] > 0) or (errors['time'] > 0) or (errors['timestep'] > 0): 46 | got_errors = True 47 | print('%s(%i,%i,%i)' % (fdig.host, errors['cnt'], errors['time'], errors['timestep']), 48 | # for fpga in ffs: 49 | # for interface in [0,1,2,3]: 50 | # err_cnt = fpga.device_by_name('unpack_err_pktcnt%i' % interface).read()['data']['reg'] 51 | # err_time = fpga.device_by_name('unpack_err_pkttime%i' % interface).read()['data']['reg'] 52 | # err_timestep = fpga.device_by_name('unpack_err_timestep%i' % interface).read()['data']['reg'] 53 | # if (err_cnt > 0) or (err_time > 0) or (err_timestep > 0): 54 | # print('(%i, %i, %i)' % (err_cnt, err_time, err_timestep), 55 | # for interface in [0,1]: 56 | # err_cnt = fpga.device_by_name('unpack_err_repktcnt%i' % interface).read()['data']['reg'] 57 | # err_time = fpga.device_by_name('unpack_err_repkttime%i' % interface).read()['data']['reg'] 58 | # err_timestep = fpga.device_by_name('unpack_err_retimestep%i' % interface).read()['data']['reg'] 59 | # if (err_cnt > 0) or (err_time > 0) or (err_timestep > 0): 60 | # print('(%i, %i, %i)' % (err_cnt, err_time, err_timestep), 61 | if got_errors == True: 62 | print('' 63 | else: 64 | print('' 65 | time.sleep(args.polltime) 66 | 67 | # end 68 | -------------------------------------------------------------------------------- /debug/feng_delay_test_fhost_level.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # pylint: disable-msg=C0103 4 | """ 5 | Test delay tracking from fhost level 6 | 7 | Created on Tuesday Oct 6 2015 8 | 9 | @author: andrew 10 | """ 11 | import corr2, os, time, logging 12 | import matplotlib.pyplot as plt 13 | 14 | logging.basicConfig(level=logging.INFO) 15 | 16 | ant_name = 'ant0_x' 17 | stream_offset = 1 18 | 19 | sample_rate = 1712*(10**6) 20 | shift_bits = 23 21 | sleep_time = 2 22 | ld_time = 1 23 | wait_time = 2 24 | 25 | offset = 1 26 | load_check_wait_time = None 27 | load_check = False 28 | 29 | #delay 30 | delay_val = 2.9999999999999 31 | 32 | #delta delay 33 | delta_delay_val_samples = 0 34 | delta_delay_val = float(delta_delay_val_samples) / (float(sleep_time) * sample_rate) 35 | 36 | #phase 37 | phase_val = 0 38 | 39 | #delta phase 40 | delta_phase_val_samples = 0 41 | delta_phase_val = float(delta_phase_val_samples) / (float(sleep_time) * sample_rate) 42 | 43 | c = corr2.fxcorrelator.FxCorrelator('rts wbc', config_source=os.environ['CORR2INI']) 44 | c.initialise(qdr_cal=False,program=False) 45 | c.est_sync_epoch() 46 | f = c.fhosts[stream_offset] 47 | 48 | # set up tvg 49 | f.registers.impulse1.write(amplitude=0.5, offset=offset) 50 | f.registers.control.write(tvg_adc=1) 51 | 52 | # capture data before setting up delays 53 | x_0 = f.snapshots.snap_quant1_ss.read(man_valid=False, man_trig=False)['data'] 54 | 55 | mcnt = None 56 | if ld_time is not None: 57 | mcnt = c.mcnt_from_time(time.time() + float(ld_time)) 58 | 59 | # set delay 60 | 61 | f.set_delay(1, delay_val, delta_delay_val, phase_val, delta_phase_val, mcnt, load_check_wait_time, load_check) 62 | vals = f.write_delays_all() 63 | 64 | #vals = f.write_delay(ant_name, delay_val, delta_delay_val, phase_val, delta_phase_val, mcnt, load_check_wait_time, load_check) 65 | 66 | # capture data just after setting up delays 67 | x_1 = f.snapshots.snap_quant1_ss.read(man_valid=False, man_trig=False)['data'] 68 | 69 | print('delay after = %f'%vals[stream_offset]['act_delay']) 70 | print('delta delay after = %f'%vals[stream_offset]['act_delta_delay']) 71 | print('phase offset after = %f'%vals[stream_offset]['act_phase_offset']) 72 | print('delta phase offset after = %f'%vals[stream_offset]['act_delta_phase_offset']) 73 | 74 | status_before = f.registers.tl_cd1_status.read()['data'] 75 | print('counters before: arm => %d load => %d'%(status_before['arm_count'], status_before['arm_count'])) 76 | 77 | # sleep 78 | time.sleep(sleep_time+wait_time) 79 | 80 | status_after = f.registers.tl_cd1_status.read()['data'] 81 | print('counters after: arm => %d load => %d'%(status_after['arm_count'], status_after['arm_count'])) 82 | 83 | # capture data after 84 | x_2 = f.snapshots.snap_quant1_ss.read(man_valid=False, man_trig=False)['data'] 85 | 86 | plt.figure() 87 | plt.plot(x_0['real0']) 88 | plt.plot(x_0['imag0']) 89 | 90 | plt.figure() 91 | plt.plot(x_1['real0']) 92 | plt.plot(x_1['imag0']) 93 | 94 | plt.figure() 95 | plt.plot(x_2['real0']) 96 | plt.plot(x_2['imag0']) 97 | plt.show() 98 | -------------------------------------------------------------------------------- /unused_src/numbers.py: -------------------------------------------------------------------------------- 1 | __author__ = 'paulp' 2 | 3 | import numpy 4 | import struct 5 | 6 | 7 | def float2str(self, coeffs, n_bits, bin_pt=0, signed=True): 8 | """ Convert floating point coeffs into a string with n_bits of resolution and a binary point at bin_pt 9 | @param coeffs: floating point coefficients 10 | @param n_bits: fixed point number of bits 11 | @param bin_pt: binary point 12 | @param signed: if data should be signed 13 | @return: string ready for writing to BRAM 14 | """ 15 | 16 | if len(coeffs) == 0: 17 | raise RuntimeError('Passing empty coeffs list') 18 | if bin_pt < 0: 19 | raise RuntimeError('Binary point cannot be less than 0') 20 | 21 | step = 1/(2**bin_pt) # coefficient resolution 22 | 23 | if signed: 24 | min_val = -(2**(n_bits-bin_pt-1)) 25 | max_val = -(min_val)-step 26 | else: 27 | min_val = 0 28 | max_val = 2**(n_bits-bin_pt)-step 29 | 30 | if numpy.max(coeffs) > max_val or numpy.min(coeffs) < min_val: 31 | raise RuntimeError('Coeffs out of range') 32 | 33 | is_complex = numpy.iscomplexobj(coeffs) 34 | if is_complex: 35 | n_coeffs = len(coeffs)*2 36 | coeffs = numpy.array(coeffs, dtype = numpy.complex128) 37 | else: 38 | n_coeffs = len(coeffs) 39 | coeffs = numpy.array(coeffs, dtype = numpy.float64) 40 | 41 | # compensate for fractional bits 42 | coeffs = (coeffs * 2**bin_pt) 43 | 44 | byte_order = '>' # big endian 45 | 46 | if n_bits == 16: 47 | if signed: 48 | pack_type = 'h' 49 | else: 50 | pack_type = 'H' 51 | else: 52 | raise RuntimeError('Don''t know how to pack data type with %i bits' % n_bits) 53 | 54 | coeff_str = struct.pack('%s%i%s' %(byte_order, n_coeffs, pack_type), *coeffs.view(dtype=numpy.float64)) 55 | return coeff_str 56 | 57 | 58 | def _str2float(self, string, n_bits, bin_pt=0, iscomplex=True, signed=True): 59 | """ Unpack string according to format specified. Return array of floats 60 | @param string: string as read from BRAM 61 | @param n_bits: resolution 62 | @param iscomplex: whether the data is complex 63 | @param bin_pt: binary point 64 | @param signed: whether the data is signed 65 | """ 66 | 67 | byte_order = '>' # big endian for CASPER data 68 | 69 | n_vals = len(string)/(n_bits/8) 70 | 71 | if n_bits == 16: 72 | if signed: 73 | pack_type = 'h' 74 | else: 75 | pack_type = 'H' 76 | else: 77 | raise RuntimeError('Don''t know how to pack data type with %i bits' % n_bits) 78 | 79 | coeffs = struct.unpack('%s%i%s'%(byte_order, n_vals, pack_type), string) 80 | coeffs_na = numpy.array(coeffs, dtype = numpy.float64) 81 | 82 | coeffs = coeffs_na/(2**bin_pt) # scale by binary points 83 | 84 | if iscomplex: 85 | # change view to 64 bit floats packed as complex 128 bit values 86 | coeffs = coeffs.view(dtype = numpy.complex128) 87 | 88 | return coeffs 89 | -------------------------------------------------------------------------------- /debug/feng_delay_test_fengops_level.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # pylint: disable-msg=C0103 4 | """ 5 | Test delay tracking from fhost level 6 | 7 | Created on Tuesday Oct 6 2015 8 | 9 | @author: andrew 10 | """ 11 | import corr2, os, time, numpy, logging 12 | import matplotlib.pyplot as plt 13 | 14 | logging.basicConfig(level=logging.INFO) 15 | 16 | ant_name = 'ant0_y' 17 | sample_rate = 1712*(10**6) 18 | shift_bits = 23 19 | sleep_time = 0.5 20 | ld_offset = 0.5 21 | offset = 1 22 | 23 | #delay 24 | delay_val_seconds = float(2) / float(sample_rate) 25 | #delay_val_seconds = 0 26 | 27 | #delta delay 28 | #delta_delay_val_seconds_per_second = float(2) / (float(sample_rate) * sleep_time) 29 | delta_delay_val_seconds_per_second = 0 30 | 31 | #phase 32 | #phase_val_radians = 0.5*numpy.pi 33 | phase_val_radians = 0 34 | 35 | #delta phase 36 | #delta_phase_val_radians_per_second = (numpy.pi/2) / sleep_time 37 | delta_phase_val_radians_per_second = 0 38 | 39 | c = corr2.fxcorrelator.FxCorrelator('rts wbc', config_source=os.environ['CORR2INI']) 40 | c.initialise(qdr_cal=False,program=False) 41 | c.est_sync_epoch() 42 | f = c.fhosts[0] 43 | 44 | # set up tvg 45 | f.registers.impulse1.write(amplitude=0.5, offset=offset) 46 | f.registers.control.write(tvg_adc=1) 47 | 48 | # capture data before setting up delays 49 | x_0 = f.snapshots.snap_quant1_ss.read(man_valid=False, man_trig=False)['data'] 50 | 51 | # set delay 52 | 53 | # defaults of 0 54 | coeffs=[] 55 | for cnt in range(len(c.fengine_sources)): 56 | delay_coeffs = [0,0] 57 | phase_coeffs = [0,0] 58 | coeffs.append([delay_coeffs, phase_coeffs]) 59 | 60 | coeffs[1] = [[delay_val_seconds, delta_delay_val_seconds_per_second], 61 | [phase_val_radians, delta_phase_val_radians_per_second]] 62 | 63 | return_vals = c.fops.set_delays_all(time.time()+ld_offset, coeffs) 64 | 65 | actual_val = return_vals[1] 66 | print('actual delay = %es'%actual_val['act_delay']) 67 | print('actual delta delay = %fs/s'%actual_val['act_delta_delay']) 68 | print('actual phase offset = %f radians'%actual_val['act_phase_offset']) 69 | print('actual delta phase offset = %f radians/s'%actual_val['act_delta_phase_offset']) 70 | 71 | # set delay 72 | #ld_time=time.time()+ld_offset 73 | #c.fops.set_delay(ant_name, delay=delay_val_seconds, delta_delay=delta_delay_val_seconds_per_second, 74 | # phase_offset=phase_val_radians, delta_phase_offset=delta_phase_val_radians_per_second, 75 | # ld_time=ld_time, ld_check=False) 76 | 77 | # capture data just after setting up delaysa 78 | x_1 = f.snapshots.snap_quant1_ss.read(man_valid=False, man_trig=False)['data'] 79 | 80 | # sleep 81 | time.sleep(sleep_time+ld_offset) 82 | 83 | # capture data after 84 | x_2 = f.snapshots.snap_quant1_ss.read(man_valid=False, man_trig=False)['data'] 85 | 86 | plt.figure() 87 | plt.plot(x_0['real0']) 88 | plt.plot(x_0['imag0']) 89 | 90 | plt.figure() 91 | plt.plot(x_1['real0']) 92 | plt.plot(x_1['imag0']) 93 | 94 | plt.figure() 95 | plt.plot(x_2['real0']) 96 | plt.plot(x_2['imag0']) 97 | plt.show() 98 | -------------------------------------------------------------------------------- /src/sensors_periodic.py: -------------------------------------------------------------------------------- 1 | import logging 2 | import time 3 | import tornado.gen as gen 4 | 5 | from tornado.ioloop import IOLoop 6 | from concurrent import futures 7 | 8 | from sensors import Corr2Sensor 9 | import sensors_periodic_fhost as sensors_fhost 10 | import sensors_periodic_xhost as sensors_xhost 11 | import sensors_periodic_bhost as sensors_bhost 12 | import sensor_scheduler 13 | 14 | host_offset_lookup = {} 15 | 16 | def setup_sensors(sensor_manager): 17 | """ 18 | INSTRUMENT-STATE-INDEPENDENT sensors to be reported to CAM 19 | :param sensor_manager: A SensorManager instance 20 | :return: 21 | """ 22 | # make the mapping of hostnames to host offsets 23 | #TODO are these assert statements a wise idea? I think they should be refactored away in favour of something proper. 24 | for ctr, host in enumerate(sensor_manager.instrument.xhosts): 25 | assert host.host not in host_offset_lookup 26 | host_offset_lookup[host.host] = 'xhost{:02}'.format(ctr) 27 | 28 | for ctr, host in enumerate(sensor_manager.instrument.fhosts): 29 | assert host.host not in host_offset_lookup 30 | host_offset_lookup[host.host] = 'fhost{:02}'.format(ctr) 31 | 32 | sensor_poll_interval = sensor_manager.instrument.sensor_poll_interval; 33 | sensor_scheduler.sensor_call_gap_time_s = sensor_poll_interval; 34 | sensor_scheduler.logger = sensor_manager.logger; 35 | 36 | # Set up a one-worker pool per host to serialise interactions with each host 37 | host_executors = { 38 | host.host: futures.ThreadPoolExecutor(max_workers=1) 39 | for host in sensor_manager.instrument.fhosts + 40 | sensor_manager.instrument.xhosts 41 | } 42 | general_executor = futures.ThreadPoolExecutor(max_workers=1) 43 | if not sensor_manager.instrument.initialised(): 44 | raise RuntimeError('Cannot set up sensors until instrument is ' 45 | 'initialised.') 46 | ioloop = getattr(sensor_manager.instrument, 'ioloop', None) 47 | if not ioloop: 48 | ioloop = getattr(sensor_manager.katcp_server, 'ioloop', None) 49 | if not ioloop: 50 | raise RuntimeError('IOLoop-containing katcp version required. Can go ' 51 | 'no further.') 52 | 53 | sensor_manager.sensors_clear() 54 | args = [sensor_manager, general_executor, 55 | host_executors, ioloop, host_offset_lookup] 56 | 57 | # create 'static' sensors 58 | sensor = sensor_manager.do_sensor( 59 | Corr2Sensor.string, 60 | 'hostname-functional-mapping', 61 | 'On which hostname is which functional host?', 62 | Corr2Sensor.NOMINAL, '', None) 63 | sensor.set_value(str(host_offset_lookup)) 64 | 65 | # setup periodic sensors 66 | sensors_fhost.setup_sensors_fengine(*args) 67 | sensors_xhost.setup_sensors_xengine(*args) 68 | sensors_bhost.setup_sensors_bengine(*args) 69 | 70 | all_hosts = sensor_manager.instrument.fhosts + sensor_manager.instrument.xhosts 71 | 72 | # end 73 | -------------------------------------------------------------------------------- /debug/frt_a_d80_snap.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # pylint: disable-msg=C0103 4 | # pylint: disable-msg=C0301 5 | """ 6 | @author: paulp 7 | """ 8 | import sys 9 | import signal 10 | import argparse 11 | 12 | 13 | parser = argparse.ArgumentParser(description='Read raw incoming data on the f-engines.', 14 | formatter_class=argparse.ArgumentDefaultsHelpFormatter) 15 | parser.add_argument(dest='host', type=str, action='store', 16 | help='f-engine host') 17 | parser.add_argument('--eof', dest='eof', action='store_true', 18 | default=False, 19 | help='show only eofs') 20 | parser.add_argument('--comms', dest='comms', action='store', default='katcp', type=str, 21 | help='katcp (default) or dcp?') 22 | parser.add_argument('--loglevel', dest='log_level', action='store', default='', 23 | help='log level to use, default None, options INFO, DEBUG, ERROR') 24 | parser.add_argument('--verbose', dest='verbose', action='store_true', default=False, 25 | help='Be verbose!') 26 | args = parser.parse_args() 27 | 28 | if args.log_level != '': 29 | import logging 30 | log_level = args.log_level.strip() 31 | try: 32 | logging.basicConfig(level=eval('logging.%s' % log_level)) 33 | except AttributeError: 34 | raise RuntimeError('No such log level: %s' % log_level) 35 | 36 | if args.comms == 'katcp': 37 | HOSTCLASS = CasperFpga 38 | else: 39 | HOSTCLASS = dcp_fpga.DcpFpga 40 | 41 | # create the device and connect to it 42 | fpga = HOSTCLASS(args.host) 43 | fpga.get_system_information() 44 | 45 | 46 | def exit_gracefully(signal, frame): 47 | fpga.disconnect() 48 | sys.exit(0) 49 | signal.signal(signal.SIGINT, exit_gracefully) 50 | 51 | while True: 52 | # arm them 53 | fpga.snapshots.p0_data_ss.arm() 54 | fpga.snapshots.p1_data_ss.arm() 55 | 56 | # trigger them snap 57 | fpga.registers.control.write(unpack_arm='pulse') 58 | 59 | # read the snaps without arming them 60 | p0d = fpga.snapshots.p0_data_ss.read(arm=False) 61 | p1d = fpga.snapshots.p1_data_ss.read(arm=False) 62 | 63 | time_msb = p0d['extra_value']['data']['time36_msb'] 64 | time_lsb = p1d['extra_value']['data']['time36_lsb'] 65 | time36 = (time_msb << 4) | time_lsb 66 | p0d = p0d['data'] 67 | p0d.update(p1d['data']) 68 | 69 | p0time_from_data = p0d['p0_80'][0] >> 44 70 | if not p0time_from_data == time36: 71 | print('ERROR: timestamp does NOT match tvg time in the data! %d != %d' % (p0d['p0_80'][0], time36) 72 | else: 73 | print('Time matches okay - %d.' % time36 74 | 75 | if args.verbose: 76 | for ctr in range(0, len(p0d['p0_80'])): 77 | print(ctr, ':', 78 | for key in p0d.keys(): 79 | if key == 'p0_80': 80 | print('%s(%d)\t' % (key, p0d[key][ctr] >> 44), 81 | else: 82 | print('%s(%d)\t' % (key, p0d[key][ctr]), 83 | print('' 84 | 85 | fpga.disconnect() 86 | # end 87 | -------------------------------------------------------------------------------- /debug/corr2_start_stop_product.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | """ 4 | Start and stop data products. 5 | 6 | It is recommended that you use ?capture-[start/stop] against your 7 | running instrument! 8 | 9 | @author: paulp 10 | """ 11 | 12 | import argparse 13 | import os 14 | 15 | from corr2 import fxcorrelator 16 | 17 | parser = argparse.ArgumentParser( 18 | description='Start or stop a data product.', 19 | formatter_class=argparse.ArgumentDefaultsHelpFormatter) 20 | parser.add_argument( 21 | '-product', dest='product', action='store', default='all', 22 | help='the name of the product on which to act, default is ALL of them') 23 | parser.add_argument( 24 | '--start', dest='start', action='store_true', default=False, 25 | help='start TX') 26 | parser.add_argument( 27 | '--stop', dest='stop', action='store_true', default=False, 28 | help='stop TX') 29 | parser.add_argument( 30 | '--listproducts', dest='listproducts', action='store_true', default=False, 31 | help='list available products and exit') 32 | parser.add_argument( 33 | '--config', dest='config', type=str, action='store', 34 | default='', help='corr2 config file') 35 | parser.add_argument( 36 | '--ipython', dest='ipython', action='store_true', default=False, 37 | help='start an ipython session after completion/error') 38 | parser.add_argument( 39 | '--loglevel', dest='log_level', action='store', default='INFO', 40 | help='log level to use, default None, options INFO, DEBUG, ERROR') 41 | args = parser.parse_args() 42 | 43 | if args.log_level: 44 | import logging 45 | log_level = args.log_level.strip() 46 | try: 47 | logging.basicConfig(level=getattr(logging, log_level)) 48 | except AttributeError: 49 | raise RuntimeError('No such log level: %s' % log_level) 50 | 51 | if not (args.stop or args.start or args.listproducts): 52 | print('Cowardly refusing to do nothing!') 53 | import sys 54 | sys.exit() 55 | 56 | if 'CORR2INI' in os.environ.keys() and args.config == '': 57 | args.config = os.environ['CORR2INI'] 58 | 59 | c = fxcorrelator.FxCorrelator('correlator', 60 | config_source=args.config) 61 | c.standard_log_config(log_level=eval('logging.%s' % log_level)) 62 | c.initialise(program=False, qdr_cal=False) 63 | 64 | if (args.product != '') and (args.product != 'all') and \ 65 | (args.product not in c.data_products): 66 | print('ERROR: %s not in data products for this instrument.' % args.product) 67 | args.listproducts = True 68 | 69 | if args.listproducts: 70 | print('Available products:') 71 | for prod in c.data_products.values(): 72 | print('\t%s' % str(prod)) 73 | import sys 74 | sys.exit() 75 | 76 | if args.product == 'all': 77 | prods = c.data_products.keys() 78 | else: 79 | prods = args.product.split(',') 80 | 81 | if args.start: 82 | for prod in prods: 83 | c.data_products[prod].tx_enable() 84 | elif args.stop: 85 | for prod in prods: 86 | c.data_products[prod].tx_disable() 87 | 88 | if args.ipython: 89 | import IPython 90 | IPython.embed() 91 | 92 | # end 93 | -------------------------------------------------------------------------------- /debug/fake_xeng_data.py: -------------------------------------------------------------------------------- 1 | import argparse 2 | import logging 3 | import spead2 4 | import spead2.send as s2tx 5 | import socket 6 | import struct 7 | import time 8 | import numpy 9 | 10 | parser = argparse.ArgumentParser(description='Set up the simple narrowband filters.', 11 | formatter_class=argparse.ArgumentDefaultsHelpFormatter) 12 | parser.add_argument('--config', dest='config', type=str, action='store', default='', 13 | help='the config file to use') 14 | parser.add_argument('--comms', dest='comms', action='store', default='katcp', type=str, 15 | help='katcp (default) or dcp?') 16 | parser.add_argument('--loglevel', dest='log_level', action='store', default='', 17 | help='log level to use, default None, options INFO, DEBUG, ERROR') 18 | args = parser.parse_args() 19 | 20 | if args.log_level != '': 21 | import logging 22 | log_level = args.log_level.strip() 23 | try: 24 | logging.basicConfig(level=eval('logging.%s' % log_level)) 25 | except AttributeError: 26 | raise RuntimeError('No such log level: %s' % log_level) 27 | 28 | log_level = 'INFO' 29 | try: 30 | logging.basicConfig(level=eval('logging.%s' % log_level)) 31 | except AttributeError: 32 | raise RuntimeError('No such log level: %s' % log_level) 33 | LOGGER = logging.getLogger(__name__) 34 | 35 | SPEAD_ADDRSIZE = 48 36 | 37 | speadig = s2tx.ItemGroup( 38 | flavour=spead2.Flavour(4, 64, SPEAD_ADDRSIZE)) 39 | 40 | streamconfig = s2tx.StreamConfig(max_packet_size=4096, 41 | max_heaps=8) 42 | streamsocket = socket.socket(family=socket.AF_INET, 43 | type=socket.SOCK_DGRAM, 44 | proto=socket.IPPROTO_IP) 45 | ttl_bin = struct.pack('@i', 2) 46 | streamsocket.setsockopt( 47 | socket.IPPROTO_IP, 48 | socket.IP_MULTICAST_TTL, 49 | ttl_bin) 50 | speadtx = s2tx.UdpStream(spead2.ThreadPool(), 51 | '127.0.0.1', 52 | 8889, 53 | streamconfig, 54 | 51200000, 55 | streamsocket) 56 | 57 | # add metadata that the receiver is expecting 58 | speadig.add_item( 59 | name='xeng_raw', id=0x1800, 60 | description='Raw data for %i xengines in the system. This item ' 61 | 'represents a full spectrum (all frequency channels) ' 62 | 'assembled from lowest frequency to highest ' 63 | 'frequency. Each frequency channel contains the data ' 64 | 'for all baselines (n_bls given by SPEAD ID 0x100b). ' 65 | 'Each value is a complex number -- two (real and ' 66 | 'imaginary) unsigned integers.' % 32, 67 | dtype=numpy.int32, 68 | shape=[4096, 69 | 10, 70 | 2]) 71 | 72 | # send the metadata 73 | speadtx.send_heap(speadig.get_heap()) 74 | 75 | # send some fake data in a loop 76 | while True: 77 | 78 | # make some data 79 | data = numpy.array() 80 | 81 | speadig.add_item( 82 | name='xeng_raw', id=0x1800, 83 | value=data) 84 | 85 | speadtx.send_heap(speadig.get_heap()) 86 | 87 | time.sleep(1) 88 | -------------------------------------------------------------------------------- /debug/spead_receiver_example.py: -------------------------------------------------------------------------------- 1 | import numpy, logging, sys 2 | 3 | import spead64_48 as spead 4 | 5 | logging.basicConfig(level=logging.INFO) 6 | PORT = 8888 7 | 8 | heapdata = [] 9 | 10 | 11 | def receive(): 12 | timesdone = 0 13 | f = open('/tmp/woo', 'w') 14 | f.close() 15 | print('RX: Initializing...' 16 | t = spead.TransportUDPrx(PORT) 17 | ig = spead.ItemGroup() 18 | last_timestamp = 0 19 | timestamp = 0 20 | for heap in spead.iterheaps(t): 21 | #print(spead.readable_heap(heap) 22 | ig.update(heap) 23 | print('Got heap cnt(%d):' % ig.heap_cnt 24 | for name in ig.keys(): 25 | print(' ', name 26 | item = ig.get_item(name) 27 | print(' Description: ', item.description 28 | print(' Format: ', item.format 29 | print(' Shape: ', item.shape 30 | # print(' Value: ', ig[name] 31 | if ig[name] is not None: 32 | if name == 'timestamp': 33 | last_timestamp = timestamp 34 | timestamp = ig[name] 35 | elif name == 'xeng_raw': 36 | global heapdata 37 | heapdata = [] 38 | heapdata[:] = ig[name] 39 | f = open('/tmp/woo', 'a') 40 | f.write('timestamp(%d) timediff(%d)\n' % (timestamp, timestamp - last_timestamp)) 41 | for data in heapdata: 42 | for bls_ctr, data_ in enumerate(data): 43 | fstr = 'acc_ctr(%010d) baseline(%02d) freq(%04d) ' % (data_[1], data_[0] & 63, 44 | (data_[0] >> 6) & 4095) 45 | f.write('%s\n' % fstr) 46 | # print(data 47 | # data = int(data) 48 | # timestep = data & 0xffffffff 49 | # bls = (data >> 32) & 63 50 | # freq = (data >> 38) & 4095 51 | # f.write('%5i\t%3i\t%10i\n' % (freq, bls, timestep)) 52 | f.close() 53 | timesdone += 1 54 | if timesdone == 2: 55 | del ig 56 | del t 57 | return 58 | print('RX: Done.' 59 | 60 | 61 | def transmit(): 62 | print('TX: Initializing...' 63 | tx = spead.Transmitter(spead.TransportUDPtx('127.0.0.1', PORT)) 64 | ig = spead.ItemGroup() 65 | 66 | ig.add_item(name='Var1', description='Description for Var1', 67 | shape=[], fmt=spead.mkfmt(('u',32),('u',32),('u',32)), 68 | init_val=(1,2,3)) 69 | tx.send_heap(ig.get_heap()) 70 | ig['Var1'] = (4,5,6) 71 | tx.send_heap(ig.get_heap()) 72 | 73 | ig.add_item(name='Var2', description='Description for Var2', 74 | shape=[100,100], fmt=spead.mkfmt(('u',32))) 75 | data = numpy.arange(100*100); data.shape = (100,100) 76 | ig['Var2'] = data 77 | tx.send_heap(ig.get_heap()) 78 | 79 | tx.end() 80 | print('TX: Done.' 81 | 82 | if sys.argv[-1] == 'tx': transmit() 83 | elif sys.argv[-1] == 'rx': receive() 84 | else: raise ValueError('Argument must be rx or tx') 85 | -------------------------------------------------------------------------------- /debug/deng_unpack_packet_capture.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import time 4 | import sys 5 | import logging 6 | import argparse 7 | 8 | import dpkt 9 | import bitstring 10 | 11 | import numpy as np 12 | 13 | from corr2.utils import UnpackDengPacketCapture 14 | 15 | logger = logging.getLogger() 16 | 17 | parser = argparse.ArgumentParser( 18 | description=""" 19 | Unpack a raw digitiser SPEAD stream to adc samples. Assumes that all the 20 | packets are for a single polarisation. 21 | 22 | Capture packets using a standard packet capture tool. You need to ensure 23 | that your capture solution is fast enough to keep up! You also need to 24 | ensure that the digitiser is set up to transmit it's data to the machine and 25 | interface used to capture the packets, or if multicast is used you must 26 | ensure that the capture interface is subscribed to the multicast group in 27 | question. Also make sure only one polarisation is directed at the capture 28 | machine. 29 | 30 | An example using the fake digitiser's "pulse" mode and wireshark's dumpcap 31 | tool. Assuming you are capturing polarisation 0. Also assumes the 32 | environment variable CORR2INI is set to a configuration file with a 33 | [dsimengine] section that configures the fake digitiser to send the pol0 34 | data to the capture machine interface and 10gbe_port = 8888. Assumes that 35 | the capture interface is "eth2" You'll need two separate shell sessions: 36 | 37 | (shell 1) $ corr2_dsim_control --program 38 | (shell 1) $ corr2_dsim_control --sine-source 0 0.5 100e6 --output-type 0 signal \\ 39 | --output-scale 0 0.5 40 | (shell 2) $ dumpcap -P -i eth2 -B 100 -f 'udp port 8888' -w digitiser.pcap 41 | (shell 1) $ corr2_dsim_control --resync --pulse 42 | (shell 2) Push ctrl-C 43 | (shell 2) $ deng_unpack_packet_capture.py digitiser.pcap output.csv 44 | """, 45 | 46 | formatter_class=argparse.RawDescriptionHelpFormatter 47 | ) 48 | 49 | parser.add_argument(dest='pcap', type=str, action='store', 50 | help='Name of pcap file with captured digitiser packets. ' 51 | 'Expected in libpcap, not pcap-ng format. Your packet ' 52 | 'capture tool might need command line parameters to force ' 53 | 'this.') 54 | parser.add_argument(dest='csv', type=str, action='store', 55 | help='Name of output csv file with sample data.') 56 | parser.add_argument('--loglevel', dest='log_level', action='store', default='', 57 | help='log level to use, default None, options INFO, DEBUG, ERROR') 58 | 59 | args = parser.parse_args() 60 | 61 | if args.log_level != '': 62 | log_level = args.log_level.strip() 63 | try: 64 | logging.basicConfig(level=eval('logging.%s' % log_level)) 65 | except AttributeError: 66 | raise RuntimeError('No such log level: %s' % log_level) 67 | 68 | 69 | unpacker = UnpackDengPacketCapture(args.pcap) 70 | _, data = unpacker.decode() 71 | 72 | # NM (2015-07-09) Note, numpy.savetxt is horrendously slow, the pandas module 73 | # has much faster csv handling code but I don't want to introduce more 74 | # dependencies just yet 75 | logger.info('Writing csv file') 76 | np.savetxt(args.csv, data, delimiter=',') 77 | 78 | -------------------------------------------------------------------------------- /debug/fengct_txspectrum.py: -------------------------------------------------------------------------------- 1 | import IPython 2 | import time 3 | import feng_utils 4 | 5 | hosts = feng_utils.setup_fhosts() 6 | feng_utils.ct_tvg(hosts, 1) 7 | 8 | # check the error registers 9 | while True: 10 | try: 11 | feng_utils.print_err_regs(hosts) 12 | time.sleep(1) 13 | except KeyboardInterrupt: 14 | print('') 15 | break 16 | 17 | # read the snap 18 | man_trig = False 19 | man_valid = True 20 | circular_capture = False 21 | f = hosts[feng_utils.HOST_UUT] 22 | 23 | # get a snapshot of the TX outputs - are the packets going to the correct place? 24 | f.registers.x_setup.write(snap_arm=False) 25 | # f.registers.ct_debug.write(gbe_mux=4) 26 | 27 | f.snapshots.gbe_in_msb_ss.arm(man_valid=man_valid, circular_capture=circ) 28 | f.snapshots.gbe_in_lsb_ss.arm(man_valid=man_valid, circular_capture=circ) 29 | f.snapshots.gbe_in_misc_ss.arm(man_valid=man_valid, circular_capture=circ) 30 | f.registers.x_setup.write(snap_arm=True) 31 | d0 = f.snapshots.gbe_in_msb_ss.read(arm=False)['data'] 32 | d1 = f.snapshots.gbe_in_lsb_ss.read(arm=False)['data'] 33 | d2 = f.snapshots.gbe_in_misc_ss.read(arm=False)['data'] 34 | f.registers.x_setup.write(snap_arm=False) 35 | d = [] 36 | for ctr in range(len(d0['d_msb'])): 37 | if d2['valid_raw'][ctr]: 38 | d.append(d0['d_msb'][ctr] >> 64) 39 | d.append(d0['d_msb'][ctr] & (2**64-1)) 40 | d.append(d1['d_lsb'][ctr] >> 64) 41 | d.append(d1['d_lsb'][ctr] & (2 ** 64 - 1)) 42 | 43 | dv_prev = d2['valid_raw'][0] 44 | zeros = {} 45 | ones = {} 46 | eofs = {} 47 | eofs_dv = {} 48 | gbe_errors = [] 49 | prev_ctr = 0 50 | prev_eof = 0 51 | eof_dv_ctr = 0 52 | for ctr in range(1, len(d0['d_msb'])): 53 | prtstr = '%5i' % ctr 54 | dv = d2['valid_raw'][ctr] 55 | prtstr += ' 0x%032x' % d0['d_msb'][ctr] 56 | prtstr += ' 0x%032x' % d1['d_lsb'][ctr] 57 | dword0 = (d0['d_msb'][ctr]) & 0xffff 58 | prtstr += ' d0(%i)' % dword0 59 | ip = IpAddress(d2['src_ip'][ctr]) 60 | prtstr += ' %s:%i' % (ip, d2['src_port'][ctr]) 61 | prtstr += ' dv(%i)' % d2['valid_raw'][ctr] 62 | prtstr += ' eof(%i)' % d2['eof'][ctr] 63 | if dv: 64 | eof_dv_ctr += 1 65 | if dv != dv_prev: 66 | diff = ctr - prev_ctr 67 | if dv: 68 | collection = zeros 69 | else: 70 | collection = ones 71 | if diff not in collection: 72 | collection[diff] = 0 73 | collection[diff] += 1 74 | prev_ctr = ctr 75 | prtstr += ' DV_CHANGE(%i)' % diff 76 | dv_prev = dv 77 | if d2['eof'][ctr]: 78 | diff = ctr - prev_eof 79 | if diff not in eofs: 80 | eofs[diff] = 0 81 | eofs[diff] += 1 82 | if eof_dv_ctr not in eofs_dv: 83 | eofs_dv[eof_dv_ctr] = 0 84 | eofs_dv[eof_dv_ctr] += 1 85 | prev_eof = ctr 86 | prtstr += ' EOF(%i,%i)' % (diff, eof_dv_ctr) 87 | eof_dv_ctr = 0 88 | if d2['gbe_err'][ctr] or d2['gbe_full'][ctr] or d2['gbe_of'][ctr]: 89 | prtstr += ' GBE_ERROR' 90 | gbe_errors.append(ctr) 91 | 92 | print prtstr 93 | 94 | 95 | print gbe_errors 96 | 97 | print 'ones:', ones 98 | print 'zeros:', zeros 99 | print 'eofs:', eofs 100 | print 'eofs_dv:', eofs_dv 101 | 102 | # end 103 | -------------------------------------------------------------------------------- /debug/corr2_fengine_sync.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # pylint: disable-msg=C0103 4 | # pylint: disable-msg=C0301 5 | """ 6 | View the status of a given xengine. 7 | 8 | Created on Fri Jan 3 10:40:53 2014 9 | 10 | @author: paulp 11 | """ 12 | 13 | from __future__ import print_function 14 | import time 15 | import argparse 16 | 17 | from casperfpga import utils as fpgautils 18 | from corr2 import utils 19 | 20 | parser = argparse.ArgumentParser( 21 | description='Sync MeerKAT F-engines.', 22 | formatter_class=argparse.ArgumentDefaultsHelpFormatter) 23 | parser.add_argument( 24 | '--hosts', dest='hosts', type=str, action='store', default='', 25 | help='comma-delimited list of hosts, or a corr2 config file') 26 | parser.add_argument( 27 | '--retry', dest='retry', action='store', default=10, type=int, 28 | help='how many times should we try to sync?') 29 | parser.add_argument( 30 | '--force', dest='force', action='store_true', default=False, 31 | help='force a sync even if they are already synced') 32 | parser.add_argument( 33 | '--checkonly', dest='checkonly', action='store_true', default=False, 34 | help='check sync only, do not try to sync') 35 | parser.add_argument( 36 | '--loglevel', dest='log_level', action='store', default='', 37 | help='log level to use, default None, options INFO, DEBUG, ERROR') 38 | args = parser.parse_args() 39 | 40 | if args.log_level != '': 41 | import logging 42 | log_level = args.log_level.strip() 43 | try: 44 | logging.basicConfig(level=eval('logging.%s' % log_level)) 45 | except AttributeError: 46 | raise RuntimeError('No such log level: %s' % log_level) 47 | 48 | # make the fpgas 49 | fpgas = utils.feng_script_get_fpgas(args) 50 | 51 | 52 | def get_sync(fpga): 53 | temp1 = fpga.registers.sync_timestamp_msw.read()['data']['reg'] 54 | temp2 = fpga.registers.sync_timestamp_lsw.read()['data']['time_lsw'] 55 | return (temp1 << 4) | (temp2 & 0x0f) 56 | 57 | 58 | def check_sync(all_fpgas): 59 | synctimes = fpgautils.threaded_fpga_operation(all_fpgas, 10, get_sync) 60 | if args.log_level != '': 61 | logging.info(synctimes) 62 | synctime = synctimes[synctimes.keys()[0]] 63 | for stime in synctimes.values(): 64 | if stime != synctime: 65 | return False, synctimes 66 | return True, synctimes 67 | 68 | # check the current sync times 69 | synced, times = check_sync(fpgas) 70 | print('Current F-engine sync times:') 71 | for host, synctime in times.items(): 72 | print('\t%s: %i' % (host, synctime)) 73 | 74 | if ((not synced) or args.force) and (not args.checkonly): 75 | # sync the F-engines 76 | tries = 0 77 | while tries < args.retry: 78 | print('Syncing...', end='') 79 | fpgautils.threaded_fpga_operation(fpgas, 10, lambda fpga_: fpga_.registers.control.write(sys_rst='pulse')) 80 | print('checking...', end='') 81 | time.sleep(1) 82 | synced, times = check_sync(fpgas) 83 | if synced: 84 | print('done. Synced at %d.' % times[times.keys()[0]]) 85 | break 86 | print('failed. Trying again. %s' % times) 87 | if tries == args.retry: 88 | if args.log_level != '': 89 | logging.error('FAILED to sync!') 90 | print('FAILED to sync!') 91 | 92 | fpgautils.threaded_fpga_function(fpgas, 10, 'disconnect') 93 | -------------------------------------------------------------------------------- /debug/speadtest.py: -------------------------------------------------------------------------------- 1 | import spead64_48 as spead 2 | 3 | import spead2 4 | import spead2.send as sptx 5 | import numpy 6 | 7 | ig = spead.ItemGroup() 8 | stx = spead.Transmitter(spead.TransportUDPtx('127.0.0.1', 8887)) 9 | 10 | ig2 = sptx.ItemGroup(flavour=spead2.Flavour(4, 64, 48)) 11 | streamconfig = sptx.StreamConfig(max_packet_size=9200, 12 | max_heaps=8) 13 | speadstream2 = sptx.UdpStream(spead2.ThreadPool(), 14 | '127.0.0.1', 15 | 8888, 16 | streamconfig, 17 | 51200000) 18 | 19 | # xraw_array = numpy.dtype(numpy.int32), (4096, 40, 2) 20 | # ig.add_item( 21 | # name='xeng_raw', id=0x1800, 22 | # description='Raw data for %i xengines in the system. This item ' 23 | # 'represents a full spectrum (all frequency channels) ' 24 | # 'assembled from lowest frequency to highest ' 25 | # 'frequency. Each frequency channel contains the data ' 26 | # 'for all baselines (baselines given by SPEAD ID 0x100C). ' 27 | # 'Each value is a complex number -- two (real and ' 28 | # 'imaginary) unsigned integers.' % 32, 29 | # ndarray=xraw_array) 30 | # 31 | # ig.add_item( 32 | # name='xeng_raw', id=0x1800, 33 | # description='Raw data for %i xengines in the system. This item ' 34 | # 'represents a full spectrum (all frequency channels) ' 35 | # 'assembled from lowest frequency to highest ' 36 | # 'frequency. Each frequency channel contains the data ' 37 | # 'for all baselines (baselines given by SPEAD ID 0x100C). ' 38 | # 'Each value is a complex number -- two (real and ' 39 | # 'imaginary) unsigned integers.' % 32, 40 | # shape=[4096, 40, 2], fmt=spead.mkfmt(('i', 32))) 41 | # ig['xeng_raw'] = numpy.arange(4096*40*2) 42 | # ig['xeng_raw'].shape = (4096,40,2) 43 | # 44 | ig2.add_item( 45 | name='xeng_raw', id=0x1800, 46 | description='Raw data for %i xengines in the system. This item ' 47 | 'represents a full spectrum (all frequency channels) ' 48 | 'assembled from lowest frequency to highest ' 49 | 'frequency. Each frequency channel contains the data ' 50 | 'for all baselines (baselines given by SPEAD ID ' 51 | '0x100C). Each value is a complex number -- two (real ' 52 | 'and imaginary) unsigned integers.' % 32, 53 | # dtype=numpy.int32, 54 | dtype=numpy.dtype('>i4'), 55 | shape=[4096, 40, 2]) 56 | 57 | # ig2.add_item( 58 | # name='xeng_raw', id=0x1800, 59 | # description='Raw data for %i xengines in the system. This item ' 60 | # 'represents a full spectrum (all frequency channels) ' 61 | # 'assembled from lowest frequency to highest ' 62 | # 'frequency. Each frequency channel contains the data ' 63 | # 'for all baselines (baselines given by SPEAD ID ' 64 | # '0x100C). Each value is a complex number -- two (real ' 65 | # 'and imaginary) unsigned integers.' % 32, 66 | # format=[('i', 32)], 67 | # # dtype=numpy.int32, 68 | # shape=[4096, 40, 2]) 69 | 70 | # send the heaps 71 | stx.send_heap(ig.get_heap()) 72 | speadstream2.send_heap(ig2.get_heap()) 73 | print('sent heaps' 74 | -------------------------------------------------------------------------------- /debug/xeng_16_x_nd_vacc_tvg_test.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | """ 4 | """ 5 | import argparse 6 | import os 7 | 8 | from casperfpga import utils as fpgautils 9 | from casperfpga import memory 10 | from corr2 import utils 11 | 12 | parser = argparse.ArgumentParser( 13 | description='Set up the x-engine VACCs.', 14 | formatter_class=argparse.ArgumentDefaultsHelpFormatter) 15 | parser.add_argument('--hosts', dest='hosts', type=str, action='store', 16 | default='', help='comma-delimited list of x-engine hosts') 17 | parser.add_argument('-p', '--polltime', dest='polltime', action='store', 18 | default=1, type=int, 19 | help='time at which to poll fengine data, in seconds') 20 | parser.add_argument('-r', '--reset_count', dest='rstcnt', action='store_true', 21 | default=False, 22 | help='reset all counters at script startup') 23 | parser.add_argument('--comms', dest='comms', action='store', default='katcp', 24 | type=str, help='katcp (default) or dcp?') 25 | parser.add_argument('--loglevel', dest='log_level', action='store', default='', 26 | help='log level to use, default None, options INFO, ' 27 | 'DEBUG, ERROR') 28 | args = parser.parse_args() 29 | 30 | polltime = args.polltime 31 | 32 | if args.log_level != '': 33 | import logging 34 | log_level = args.log_level.strip() 35 | try: 36 | logging.basicConfig(level=eval('logging.%s' % log_level)) 37 | except AttributeError: 38 | raise RuntimeError('No such log level: %s' % log_level) 39 | 40 | if 'CORR2INI' in os.environ.keys() and args.hosts == '': 41 | args.hosts = os.environ['CORR2INI'] 42 | hosts = utils.parse_hosts(args.hosts, section='xengine') 43 | if len(hosts) == 0: 44 | raise RuntimeError('No good carrying on without hosts.') 45 | 46 | # create the devices and connect to them 47 | fpgas = fpgautils.threaded_create_fpgas_from_hosts(hosts) 48 | fpgautils.threaded_fpga_function(fpgas, 15, 'get_system_information') 49 | 50 | print(fpgautils.threaded_fpga_operation( 51 | fpgas, 10, 52 | lambda fpga_: 53 | fpga_.registers.vacctvg_control.read()['data'], ) 54 | 55 | # write nothing to the tvg control reg 56 | fpgautils.threaded_fpga_operation( 57 | fpgas, 10, 58 | lambda fpga_: 59 | fpga_.registers.vacctvg_control.write_int(0), ) 60 | 61 | # reset all the TVGs 62 | fpgautils.threaded_fpga_operation( 63 | fpgas, 10, 64 | lambda fpga_: 65 | fpga_.registers.vacctvg_control.write(ctr_en=False, sync_sel=False, 66 | valid_sel=False, data_sel=False, 67 | reset='pulse'), ) 68 | 69 | # write the constant to the data reg 70 | # CLUDGE 71 | # for ctr in range(1): 72 | for ctr in range(4): 73 | regname = 'sys%i_vacc_tvg0_write' % ctr 74 | fpgautils.threaded_fpga_operation( 75 | fpgas, 10, 76 | lambda fpga_: fpga_.registers[regname].write_int(1), ) 77 | 78 | # and enable the constant instead of the real data 79 | fpgautils.threaded_fpga_operation( 80 | fpgas, 10, 81 | lambda fpga_: 82 | fpga_.registers.vacctvg_control.write(data_sel=True), ) 83 | 84 | # fpgautils.threaded_fpga_operation( 85 | # fpgas, 10, 86 | # lambda fpga_: 87 | # fpga_.registers.vacc_pretvg_ctrl.write(en_gating=False), ) 88 | -------------------------------------------------------------------------------- /debug/filt_00_adc_hist.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | """ 4 | Collect the output of a post-unpack snapshot and do an FFT on it. 5 | 6 | @author: paulp 7 | """ 8 | import argparse 9 | import sys 10 | import signal 11 | import matplotlib.pyplot as pyplot 12 | 13 | from corr2.utils import AdcData 14 | 15 | parser = argparse.ArgumentParser(description='Show a histogram of the incoming samples.', 16 | formatter_class=argparse.ArgumentDefaultsHelpFormatter) 17 | parser.add_argument('--host', dest='host', type=str, action='store', default='', 18 | help='the host to query') 19 | parser.add_argument('--filtered', dest='filtered', action='store_true', default=False, 20 | help='plot filtered data, not raw ADC data') 21 | parser.add_argument('--loglevel', dest='log_level', action='store', default='', 22 | help='log level to use, default None, options INFO, DEBUG, ERROR') 23 | args = parser.parse_args() 24 | 25 | import logging 26 | if args.log_level != '': 27 | log_level = args.log_level.strip() 28 | try: 29 | logging.basicConfig(level=eval('logging.%s' % log_level)) 30 | except AttributeError: 31 | raise RuntimeError('No such log level: %s' % log_level) 32 | LOGGER = logging.getLogger(__name__) 33 | 34 | def exit_gracefully(signal, frame): 35 | fpga.disconnect() 36 | sys.exit(0) 37 | signal.signal(signal.SIGINT, exit_gracefully) 38 | 39 | # make the FPGA objects 40 | fpga = CasperFpga(args.host) 41 | fpga.get_system_information() 42 | 43 | # check for the required snapshot 44 | if 'snapadc0_ss' not in fpga.snapshots.names(): 45 | raise RuntimeError('ADC0 snap not available!') 46 | if 'snapadc1_ss' not in fpga.snapshots.names(): 47 | raise RuntimeError('ADC1 snap not available!') 48 | 49 | def get_data(): 50 | fpga.snapshots.snapadc0_ss.arm() 51 | fpga.snapshots.snapadc1_ss.arm() 52 | fpga.registers.ctrl2.write(trig_adc_snaps='pulse') 53 | snapdata_p0 = fpga.snapshots.snapadc0_ss.read(arm=False)['data'] 54 | snapdata_p1 = fpga.snapshots.snapadc1_ss.read(arm=False)['data'] 55 | snapdata_p1['p1'] = [] 56 | for ctr, msb_data in enumerate(snapdata_p0['p1_msb']): 57 | snapdata_p1['p1'].append((msb_data << 32) + snapdata_p1['p1_lsb'][ctr]) 58 | data_p0 = AdcData.eighty_to_ten(snapdata_p0['p0']) 59 | data_p1 = AdcData.eighty_to_ten(snapdata_p1['p1']) 60 | return {'p0': data_p0, 'p1': data_p1} 61 | 62 | def get_data_filtered(): 63 | snapdata = fpga.snapshots.filtout_ss.read(man_trig=True)['data'] 64 | return snapdata 65 | 66 | def plot_func(figure, sub_plots): 67 | if args.filtered: 68 | unpacked_data = get_data_filtered() 69 | else: 70 | unpacked_data = get_data() 71 | for pol in ['p0', 'p1']: 72 | sub_plots[pol].cla() 73 | sub_plots[pol].set_title(pol) 74 | sub_plots[pol].hist(unpacked_data[pol], 49) 75 | figure.canvas.draw() 76 | fig.canvas.manager.window.after(100, plot_func, figure, sub_plots) 77 | 78 | # set up the figure with a subplot to be plotted 79 | fig = pyplot.figure() 80 | subplots = {'p0': fig.add_subplot(2, 1, 1), 81 | 'p1': fig.add_subplot(2, 1, 2)} 82 | fig.canvas.manager.window.after(100, plot_func, fig, subplots) 83 | pyplot.show() 84 | print('Plot started.' 85 | 86 | # wait here so that the plot can be viewed 87 | print('Press Ctrl-C to exit...' 88 | sys.stdout.flush() 89 | import time 90 | while True: 91 | time.sleep(1) 92 | 93 | # end 94 | -------------------------------------------------------------------------------- /debug/skarab_deng_000_setup.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | """ 4 | Check the SPEAD error counter and valid counter in the 5 | unpack section of the F-engines. 6 | 7 | @author: paulp 8 | """ 9 | import os 10 | import logging 11 | import time 12 | 13 | from casperfpga import casperfpga, network 14 | 15 | logging.basicConfig(level=logging.INFO) 16 | 17 | program_skarab = True 18 | setup_skarab = True 19 | 20 | f = casperfpga.CasperFpga(os.environ['SKARAB_DSIM']) 21 | 22 | if program_skarab: 23 | res = f.upload_to_ram_and_program(os.environ['SKARAB_DSIM_FPG']) 24 | if not res: 25 | print('Could not program SKARAB.') 26 | import sys 27 | sys.exit(0) 28 | print('Done programming SKARAB.') 29 | else: 30 | f.get_system_information(os.environ['SKARAB_DSIM_FPG']) 31 | 32 | if setup_skarab: 33 | 34 | f.registers.gbe_control.write_int(0) 35 | f.registers.receptor_id.write(pol0_id=0, pol1_id=1) 36 | 37 | f.registers.control.write(tvg_select0=1, tvg_select1=1) 38 | 39 | # ramp 80 or ramp 64? 40 | f.registers.ramp_control.write(sel_ramp80=0, rst_ramp80='pulse', 41 | sel_munge=0, sel_insert_time=0) 42 | 43 | f.registers.pol_tx_always_on.write(pol0_tx_always_on=1, pol1_tx_always_on=1) 44 | f.registers.src_sel_cntrl.write(src_sel_0=1, src_sel_1=1) 45 | 46 | f.registers.control.write(mrst='pulse') 47 | f.registers.control.write(msync='pulse') 48 | f.registers.control.write(gbe_rst=0, gbe_txen=1) 49 | 50 | gbe = f.gbes.keys()[0] 51 | gbe = f.gbes[gbe] 52 | # if gbe.get_port() != 30000: 53 | # gbe.set_port(30000) 54 | # f.registers.gbe_porttx.write(reg=30000) 55 | # ip = network.IpAddress('10.99.1.1') 56 | # ip = network.IpAddress(os.environ['CORR2UUT']) 57 | # ip = network.IpAddress('10.100.101.111') 58 | # for ctr in range(4): 59 | # f.registers['gbe_iptx%i' % ctr].write(reg=ip.ip_int) 60 | 61 | if gbe.get_port() != 7148: 62 | gbe.set_port(7148) 63 | f.registers.gbe_porttx.write(reg=7148) 64 | f.registers['gbe_iptx0'].write(reg=int(network.IpAddress('239.2.0.64'))) 65 | f.registers['gbe_iptx1'].write(reg=int(network.IpAddress('239.2.0.65'))) 66 | f.registers['gbe_iptx2'].write(reg=int(network.IpAddress('239.2.0.66'))) 67 | f.registers['gbe_iptx3'].write(reg=int(network.IpAddress('239.2.0.67'))) 68 | 69 | # f.registers.control.write(gbe_rst='pulse') 70 | f.registers.gbe_control.write_int(15) 71 | # f.registers.gbe_control.write_int(1) 72 | print('Done setting up SKARAB.') 73 | 74 | f.registers.speadsnap_control.write_int(0) 75 | f.snapshots.spead_snap0_ss.arm() 76 | f.snapshots.spead_detail_ss.arm() 77 | f.registers.speadsnap_control.write_int(1) 78 | 79 | time.sleep(1) 80 | 81 | d0 = f.snapshots.spead_snap0_ss.read(arm=False)['data'] 82 | d1 = f.snapshots.spead_detail_ss.read(arm=False)['data'] 83 | 84 | d0.update(d1) 85 | 86 | last_eof = -1 87 | pktlen_errors = 0 88 | for ctr in range(len(d0['d64'])): 89 | prtstr = '%6i %20i %20i %20x' % ( 90 | ctr, d0['we'][ctr], d0['eof'][ctr], d0['d64'][ctr]) 91 | if d0['eof'][ctr]: 92 | pktlen = (ctr - last_eof) 93 | prtstr += ' EOF(%i)' % pktlen 94 | if pktlen != 649: 95 | prtstr += ' ERROR' 96 | pktlen_errors += 1 97 | last_eof = ctr 98 | print(prtstr) 99 | if d0['eof'][ctr]: 100 | print('-' * 100) 101 | 102 | print 'PKTLEN_ERRORS:', pktlen_errors 103 | 104 | # import IPython 105 | # IPython.embed() 106 | 107 | # end 108 | -------------------------------------------------------------------------------- /debug/vaccbug/read_write_info_snap.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | """ 4 | """ 5 | import logging 6 | import argparse 7 | import os 8 | 9 | from casperfpga import utils as casper_utils 10 | from corr2 import utils, xhost_fpga 11 | import IPython 12 | import sys 13 | 14 | logging.basicConfig(level=logging.INFO) 15 | 16 | parser = argparse.ArgumentParser( 17 | description='Set up the TVG on a x-engine VACC.', 18 | formatter_class=argparse.ArgumentDefaultsHelpFormatter) 19 | parser.add_argument( 20 | '--config', dest='config', type=str, action='store', default='', 21 | help='a corr2 config file, will use $CORR2INI if none given') 22 | args = parser.parse_args() 23 | 24 | if 'CORR2INI' in os.environ.keys() and args.config == '': 25 | args.config = os.environ['CORR2INI'] 26 | if args.config != '': 27 | host_list = utils.parse_hosts(args.config, section='xengine') 28 | else: 29 | host_list = [] 30 | 31 | snap = 'snap_vacc_in' 32 | 33 | f = xhost_fpga.FpgaXHostVaccDebug(host_list[0], 0) 34 | f.get_system_information() 35 | 36 | NUM_ACCS = 1633 37 | VEC_LEN = 64 * 40 # 2560 38 | NUM_ADDS = VEC_LEN / 2 39 | BANK0_START = 0 40 | BANK1_START = 2048 41 | 42 | f.registers.snap_trig_val.write_int(NUM_ACCS - 1) 43 | 44 | MAN_VALID = False 45 | 46 | 47 | def analyse_data(): 48 | """ 49 | Look for a mistake in the snap data 50 | :return: 51 | """ 52 | d = f.snapshots.snap_vacc_in_ss.read(man_valid=MAN_VALID)['data'] 53 | keys = d.keys() 54 | bank = d['addr'][0] >= BANK1_START 55 | datalen = len(d['addr']) 56 | error = False 57 | 58 | startpos = -1 59 | for ctr in range(0, datalen, 1): 60 | if d['d32'][ctr] == 1633: 61 | startpos = ctr 62 | break 63 | if startpos == -1: 64 | raise RuntimeError('No start pos found') 65 | endpos = startpos 66 | for ctr in range(startpos, datalen, 1): 67 | if d['d32'][ctr] != 1633: 68 | endpos = ctr 69 | break 70 | if startpos == endpos: 71 | raise RuntimeError('No end pos found') 72 | 73 | if endpos - startpos != VEC_LEN: 74 | for ctr in range(startpos - 10, startpos + VEC_LEN + 10, 1): 75 | # for ctr in range(0, datalen, 1): 76 | print('{}: '.format(ctr), 77 | for k in keys: 78 | print('{}[{}] '.format(k, d[k][ctr]), 79 | print('' 80 | print(startpos, endpos 81 | raise RuntimeError 82 | return 83 | 84 | for ctr in range(0, datalen, 2): 85 | addr0 = d['addr'][ctr] 86 | data0 = d['d32'][ctr] 87 | addr1 = d['addr'][ctr+1] 88 | data1 = d['d32'][ctr+1] 89 | if data0 != data1: 90 | print('%i: DATA ERROR: addr0[%i] addr1[%i] data0[%i] data1[%i]' % ( 91 | ctr, addr0, addr1, data0, data1) 92 | error = True 93 | if addr1 != addr1: 94 | print('%i: ADDR ERROR: addr0[%i] addr1[%i] data0[%i] data1[%i]' % ( 95 | ctr, addr0, addr1, data0, data1) 96 | error = True 97 | 98 | # print('{}: we[{}] addr0[{}] addr1[{}] data0[{}] data1[{}]'.format( 99 | # ctr, d['wren'][ctr], addr0, addr1, data0, data1 100 | # ) 101 | 102 | if error: 103 | IPython.embed() 104 | raise RuntimeError 105 | 106 | loopctr = 0 107 | while True: 108 | try: 109 | analyse_data() 110 | except RuntimeError: 111 | print('ran %i times before error' % loopctr 112 | raise 113 | print('.', 114 | sys.stdout.flush() 115 | loopctr += 1 116 | -------------------------------------------------------------------------------- /debug/feng_check_28_pack_snap.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # pylint: disable-msg=C0103 4 | # pylint: disable-msg=C0301 5 | """ 6 | View the status of a given xengine. 7 | 8 | Created on Fri Jan 3 10:40:53 2014 9 | 10 | @author: paulp 11 | """ 12 | import argparse 13 | 14 | 15 | parser = argparse.ArgumentParser( 16 | description='Read a post-pack snapshot from an fengine.', 17 | formatter_class=argparse.ArgumentDefaultsHelpFormatter) 18 | parser.add_argument( 19 | '--hosts', dest='hosts', type=str, action='store', default='', 20 | help='the host from which to read') 21 | parser.add_argument( 22 | '--wesel', dest='wesel', action='store', type=int, default=0, 23 | help='write-enable select: 0 for window start, 1 for data_valid to SPEAD') 24 | parser.add_argument( 25 | '--offset', dest='offset', action='store', type=int, default=-1, 26 | help='apply a read offset to the snapshot') 27 | parser.add_argument( 28 | '--timestep', dest='timestep', action='store_true', default=False, 29 | help='search for a time boundary crossing') 30 | parser.add_argument( 31 | '--loglevel', dest='log_level', action='store', default='', 32 | help='log level to use, default None, options INFO, DEBUG, ERROR') 33 | args = parser.parse_args() 34 | 35 | if args.timestep and args.wesel==0: 36 | raise RuntimeError('Waiting for a timestep and write-enable ' 37 | 'on window start does not make sense.') 38 | 39 | if args.log_level != '': 40 | import logging 41 | log_level = args.log_level.strip() 42 | try: 43 | logging.basicConfig(level=eval('logging.%s' % log_level)) 44 | except AttributeError: 45 | raise RuntimeError('No such log level: %s' % log_level) 46 | 47 | # create the devices and connect to them 48 | fpga = HOSTCLASS(args.host) 49 | fpga.get_system_information() 50 | if 'wintime_snap_ss' not in fpga.snapshots.names(): 51 | print(fpga.snapshots 52 | fpga.disconnect() 53 | raise RuntimeError('The host %s does not have the necessary snapshot, %s.' % (fpga.host, 'wintime_snap_ss')) 54 | 55 | fpga.registers.control.write(wintime_snap_wesel=args.wesel) 56 | got_time_step = False 57 | while (args.timestep and (not got_time_step)) or (not args.timestep): 58 | snapdata = fpga.snapshots.wintime_snap_ss.read(offset=args.offset)['data'] 59 | lasttime = snapdata['time36'][0] 60 | lastfreq_ctr = -1 61 | lastfreq = snapdata['freqid0'][0] - 128 62 | for ctr in range(0, len(snapdata['time36'])): 63 | this_freq = snapdata['freqid0'][ctr] 64 | this_feng = snapdata['fengid'][ctr] 65 | this_time = snapdata['time36'][ctr] 66 | ending = '' 67 | freqdiff = False 68 | timediff = False 69 | if this_freq != lastfreq: 70 | ending += ' freqdiff(%5d, %5d)' % (this_freq - lastfreq, ctr - lastfreq_ctr) 71 | lastfreq = this_freq 72 | lastfreq_ctr = ctr 73 | freqdiff = True 74 | if this_time != lasttime: 75 | ending += ' timediff(%5d)' % (this_time - lasttime) 76 | timediff = True 77 | got_time_step = True 78 | if timediff and not freqdiff: 79 | if args.wesel == 1: 80 | ending += ' !!!!!!!!!!!!!!!!!!ERROR!!!!!!!!!!!!!!!!!!!' 81 | else: 82 | if this_time - lasttime != 512: # 2^9 - 2^8 from the corner turn and 2^1 from 4k PFB needing 8k samples 83 | ending += ' !!!!!!!!!!!!!!!!!!ERROR!!!!!!!!!!!!!!!!!!!' 84 | print('%5d: freq(%5d) feng(%3d) time(%15d)%s' % (ctr, this_freq, this_feng, this_time, ending) 85 | lasttime = this_time 86 | if not args.timestep: 87 | break 88 | fpga.disconnect() 89 | # end 90 | -------------------------------------------------------------------------------- /debug/corr2_get_mappings.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | Get different mappings in this system 6 | """ 7 | 8 | import argparse 9 | import os 10 | 11 | from corr2 import utils 12 | 13 | parser = argparse.ArgumentParser( 14 | description='Print out different mappings in this system.', 15 | formatter_class=argparse.ArgumentDefaultsHelpFormatter) 16 | 17 | parser.add_argument( 18 | '--host', dest='host', type=str, action='store', 19 | default='', help='given a hostname, return information associated with it') 20 | parser.add_argument( 21 | '--source', dest='source', type=str, action='store', 22 | default='', help='given a source name, return information associated ' 23 | 'with it') 24 | parser.add_argument( 25 | '--baseline_index', dest='baseline_index', type=int, action='store', 26 | default=-1, help='given a baseline index, return information associated ' 27 | 'with it') 28 | parser.add_argument( 29 | '--config', dest='config', type=str, action='store', default='', 30 | help='the config file to parse, $CORR2INI will be used if this is not ' 31 | 'specified') 32 | parser.add_argument( 33 | '--loglevel', dest='log_level', action='store', default='INFO', 34 | help='log level to use, default None, options INFO, DEBUG, ERROR') 35 | args = parser.parse_args() 36 | 37 | if args.log_level != '': 38 | import logging 39 | log_level = args.log_level.strip() 40 | try: 41 | logging.basicConfig(level=eval('logging. %s' % log_level)) 42 | except AttributeError: 43 | raise RuntimeError('No such log level: %s' % log_level) 44 | 45 | configfile = args.config 46 | if 'CORR2INI' in os.environ.keys() and configfile == '': 47 | configfile = os.environ['CORR2INI'] 48 | if configfile == '': 49 | raise RuntimeError('No good carrying on without a config file') 50 | 51 | configd = utils.parse_ini_file(configfile) 52 | baselines = utils.baselines_from_config(config=configd) 53 | fhosts = utils.hosts_from_config(config=configd, section='fengine') 54 | 55 | 56 | def baselines_from_source(source): 57 | rv = {} 58 | for ctr, baseline in enumerate(baselines): 59 | if source == baseline[0] or source == baseline[1]: 60 | rv[ctr] = baseline 61 | return rv 62 | 63 | 64 | # host name 65 | if args.host != '': 66 | host = args.host 67 | print('%s:' % host) 68 | print('\tSources:') 69 | bls = {} 70 | srcs = utils.host_to_sources(host, config=configd) 71 | for ctr, source in enumerate(srcs[host]): 72 | print('\t\t%i: %s' % (ctr, source)) 73 | bls.update(baselines_from_source(source)) 74 | print('\tBaselines:') 75 | for bls_index in bls: 76 | print('\t\t%i: %s' % (bls_index, bls[bls_index])) 77 | 78 | elif args.source != '': 79 | source = args.source 80 | print('%s:' % source) 81 | all_sources = utils.host_to_sources(fhosts, config=configd) 82 | source_host = None 83 | for host in all_sources: 84 | for src in all_sources[host]: 85 | if src == args.source: 86 | source_host = host 87 | break 88 | if not source_host: 89 | print('\tERROR: could not match source %s to system host.' % source) 90 | else: 91 | print('\tMatched to host %s.' % source_host) 92 | bls = baselines_from_source(source) 93 | print('\tBaselines:') 94 | for bls_index in bls: 95 | print('\t\t%i: %s' % (bls_index, bls[bls_index])) 96 | 97 | elif args.baseline_index != -1: 98 | print('Baseline %i: %s' % (args.baseline_index, 99 | baselines[args.baseline_index])) 100 | 101 | # end 102 | -------------------------------------------------------------------------------- /src/sensor_scheduler.py: -------------------------------------------------------------------------------- 1 | import time; 2 | import math; 3 | 4 | 5 | sensor_call_gap_time_s = 0.003; 6 | sensor_loop_runtime = 0; 7 | sensor_loop_running_tasks = 0; 8 | sensor_loop_start_time = round(time.time())+4; 9 | sensor_loop_flow_control_padding = 0; 10 | logger = None; 11 | 12 | class SensorTask: 13 | def __init__(self,function_name,minimum_time_between_calls_s=0): 14 | self.last_runtime_length = 0 15 | self.last_runtime_utc = 0; 16 | self.executed = False; 17 | self.name = function_name; 18 | self.num_time_overruns = 0; 19 | self.flow_control_increments = 0; 20 | self.minimum_time_between_calls_ms = minimum_time_between_calls_s; 21 | logger.debug(self.name) 22 | 23 | def getNextSensorCallTime(self,current_function_runtime=0): 24 | global sensor_loop_runtime; 25 | global sensor_call_gap_time_s; 26 | global sensor_loop_running_tasks; 27 | global sensor_loop_start_time; 28 | global sensor_loop_flow_control_padding; 29 | global logger 30 | 31 | #printTime = False; 32 | last_runtime_length = self.last_runtime_length; 33 | if(self.executed == False): 34 | self.executed = True; 35 | sensor_loop_running_tasks+=1 36 | self.last_runtime_utc = sensor_loop_start_time; 37 | # printTime = True; 38 | 39 | self.last_runtime_length = current_function_runtime 40 | 41 | time_increment = (sensor_loop_running_tasks+sensor_loop_flow_control_padding)*sensor_call_gap_time_s 42 | 43 | #This ensures that a sensor is not called within a specified minimum time - this ensures we play nicely with some CAM 44 | if(time_incrementsensor_call_gap_time_s*(self.flow_control_increments+1)): 56 | self.num_time_overruns+=1; 57 | elif(current_function_runtime 5): 63 | #print("%s took %fs longer to run than allocated - this occured five times in a row, performing flow control"%(self.name,current_function_runtime-(1+self.flow_control_increments)*sensor_call_gap_time_s)) 64 | self.num_time_overruns=0 65 | self.flow_control_increments+=1 66 | sensor_loop_flow_control_padding+=1 67 | 68 | if(self.num_time_overruns < -5): 69 | #print("%s took %fs less to run than allocated - this occured five times in a row, performing flow control"%((1+self.flow_control_increments)*sensor_call_gap_time_s)-self.name,current_function_runtime) 70 | self.num_time_overruns=0 71 | self.flow_control_increments-=1 72 | sensor_loop_flow_control_padding-=1 73 | 74 | logger.debug('{0:} finished at {1:.4f}. Next Call:{2:.4f} Runtime: {3:.5f}.'.format(self.name,time.time(),next_sensor_call_time,current_function_runtime)) 75 | #if(printTime): 76 | # print ("Sensor function: {0:} First Call: {1:.4f} Next Call: {2:.4f}".format(self.name,time.time(),next_sensor_call_time)) 77 | return next_sensor_call_time 78 | 79 | 80 | 81 | 82 | -------------------------------------------------------------------------------- /testing/test_ferrors.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # pylint: disable-msg=C0103 4 | # pylint: disable-msg=C0301 5 | """ 6 | Created on Thu May 8 15:35:52 2014 7 | 8 | Check post-CT errors on the f-engine. 9 | 10 | @author: paulp 11 | """ 12 | import logging, time, argparse 13 | 14 | logger = logging.getLogger(__name__) 15 | #logging.basicConfig(level=logging.INFO) 16 | 17 | from casperfpga import KatcpClientFpga 18 | import casperfpga.scroll as scroll 19 | 20 | fhosts = ['roach02091b', 'roach020914', 'roach020915', 'roach020922'] 21 | 22 | parser = argparse.ArgumentParser(description='Check post-CT errors on the f-engines.', 23 | formatter_class=argparse.ArgumentDefaultsHelpFormatter) 24 | parser.add_argument(dest='hosts', type=str, action='store', 25 | help='comma-delimited list of f-engine hosts') 26 | parser.add_argument('-p', '--polltime', dest='polltime', action='store', 27 | default=1, type=int, 28 | help='time at which to poll fengine data, in seconds') 29 | parser.add_argument('-r', '--reset_counters', dest='reset_counters', action='store_true', 30 | default=False, 31 | help='reset f-engine error counters') 32 | args = parser.parse_args() 33 | polltime = args.polltime 34 | reset_counters = args.reset_counters 35 | 36 | # init the f-engines 37 | ffpgas = [] 38 | for fhost in fhosts: 39 | fpga = KatcpClientFpga(fhost) 40 | fpga.get_system_information() 41 | # fpga.registers.control.write(sys_rst = 'pulse') # breaks other systems for some unknown reason 42 | if reset_counters: 43 | fpga.registers.control.write(cnt_rst = 'pulse') 44 | ffpgas.append(fpga) 45 | 46 | # set up the curses scroll screen 47 | scroller = scroll.Scroll(debug=False) 48 | scroller.screen_setup() 49 | # main program loop 50 | STARTTIME = time.time() 51 | last_refresh = STARTTIME - 3 52 | try: 53 | # loop forever while check the error registers on the f-engines 54 | # the output of these registers will ONLY make sense if the d-engine 55 | # tvg is on. 56 | while True: 57 | # get key presses from ncurses 58 | keypress, character = scroller.on_keypress() 59 | if keypress == -1: 60 | break 61 | elif keypress > 0: 62 | scroller.draw_screen() 63 | if time.time() > last_refresh + polltime: 64 | scroller.clear_buffer() 65 | scroller.add_line('Polling %i fengine%s every %s - %is elapsed. Any numbers indicate errors.' % 66 | (len(ffpgas), '' if len(ffpgas) == 1 else 's', 67 | 'second' if polltime == 1 else ('%i seconds' % polltime), 68 | time.time() - STARTTIME), 0, 0, absolute=True) 69 | scroller.set_ypos(newpos=2) 70 | for fpga in ffpgas: 71 | fstring = '%s: ' % fpga.host 72 | mcnt_nolock = fpga.registers.mcnt_nolock.read()['data']['mcnt_nolock'] 73 | data = fpga.registers.ct_cnt.read()['data'] 74 | sync_cnt = data['synccnt'] 75 | valid_cnt = data['validcnt'] 76 | data = fpga.registers.ct_errcnt.read()['data'] 77 | errcnt0 = data['errcnt0'] 78 | parerrcnt0 = data['parerrcnt0'] 79 | errcnt1 = data['errcnt1'] 80 | parerrcnt1 = data['parerrcnt1'] 81 | fstring += 'syncs(%10d)\tvalids(%10d)\tmcnt_nolock(%10d)\tct_errors(%10d, %10d, %10d, %10d)' % (sync_cnt, valid_cnt, mcnt_nolock, errcnt0, parerrcnt0, errcnt1, parerrcnt1) 82 | scroller.add_line('%s' % fstring) 83 | scroller.draw_screen() 84 | last_refresh = time.time() 85 | except Exception, e: 86 | for fpga in ffpgas: 87 | fpga.disconnect() 88 | scroll.screen_teardown() 89 | raise 90 | 91 | # handle exits cleanly 92 | for fpga in ffpgas: 93 | fpga.disconnect() 94 | scroll.screen_teardown() 95 | # end 96 | -------------------------------------------------------------------------------- /debug/feng_check_02_unpack_spead_errors.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Thu May 22 13:35:29 2014 4 | 5 | This script pulls a snapshot from the unpack block on the f-engine and examines the spead data inside it 6 | to see if it matches D-engine TVG data. 7 | 8 | @author: paulp 9 | """ 10 | 11 | import numpy 12 | import argparse 13 | import os 14 | 15 | from corr2 import utils 16 | 17 | parser = argparse.ArgumentParser(description='Check the SPEAD error counter and valid counter in the ' 18 | 'unpack section of the F-engines.', 19 | formatter_class=argparse.ArgumentDefaultsHelpFormatter) 20 | parser.add_argument('--hosts', dest='hosts', type=str, action='store', default='', 21 | help='comma-delimited list of hosts, or a corr2 config file') 22 | parser.add_argument('-p', '--polltime', dest='polltime', action='store', 23 | default=1, type=int, 24 | help='time at which to poll fengine data, in seconds') 25 | parser.add_argument('-r', '--reset_count', dest='rstcnt', action='store_true', 26 | default=False, 27 | help='reset all counters at script startup') 28 | parser.add_argument('--comms', dest='comms', action='store', default='katcp', type=str, 29 | help='katcp (default) or dcp?') 30 | parser.add_argument('--loglevel', dest='log_level', action='store', default='', 31 | help='log level to use, default None, options INFO, DEBUG, ERROR') 32 | args = parser.parse_args() 33 | 34 | if args.log_level != '': 35 | import logging 36 | log_level = args.log_level.strip() 37 | try: 38 | logging.basicConfig(level=eval('logging.%s' % log_level)) 39 | except AttributeError: 40 | raise RuntimeError('No such log level: %s' % log_level) 41 | 42 | if args.comms == 'katcp': 43 | HOSTCLASS = CasperFpga 44 | else: 45 | HOSTCLASS = dcp_fpga.DcpFpga 46 | 47 | if 'CORR2INI' in os.environ.keys() and args.hosts == '': 48 | args.hosts = os.environ['CORR2INI'] 49 | hosts = utils.parse_hosts(args.hosts, section='fengine') 50 | if len(hosts) == 0: 51 | raise RuntimeError('No good carrying on without hosts.') 52 | 53 | fpga = HOSTCLASS(hosts[0]) 54 | fpga.get_system_information() 55 | snaps = fpga.snapshots.names() 56 | if snaps.count('unpack_spead0_ss') == 0: 57 | fpga.disconnect() 58 | raise RuntimeError('The f-engine does not have the required snapshot, unpack_spead0_ss, compiled into it.') 59 | 60 | # get the snapshot data from the FPGA. 61 | snapdata = fpga.snapshots.unpack_spead0_ss.read(man_trig=True,circular_capture=True)['data'] 62 | fpga.disconnect() 63 | 64 | # check the data 65 | lastval = snapdata['dramp'][0] - 1 66 | errors = False 67 | for ctr, val in enumerate(snapdata['dramp']): 68 | if val == 0: 69 | if lastval != 511: 70 | errors = True 71 | print('ERROR over rollover at %i'%ctr 72 | else: 73 | if val != lastval + 1: 74 | errors = True 75 | print('ERROR in the ramp at %i'%ctr 76 | lastval = val 77 | if errors: 78 | print('DATA RAMP ERRORS ENCOUNTERED' 79 | 80 | # check the time and pkt_time 81 | errors = False 82 | for ctr, p in enumerate(snapdata['dtime']): 83 | if p != snapdata['pkt_time'][ctr]: 84 | print('ERROR:', ctr-1, snapdata['dtime'][ctr-1], numpy.binary_repr(snapdata['dtime'][ctr-1]),\ 85 | snapdata['pkt_time'][ctr-1] 86 | print('ERROR:', ctr, p, numpy.binary_repr(p), snapdata['pkt_time'][ctr] 87 | errors = True 88 | if errors: 89 | print('TIME vs PKT_TIME ERRORS ENCOUNTERED' 90 | 91 | # check the unique times and timestep 92 | errors = False 93 | unique_times = list(numpy.unique(snapdata['pkt_time'])) 94 | for ctr, utime in enumerate(unique_times[1:]): 95 | if utime != unique_times[ctr] + 2: 96 | print('ERROR:', ctr, utime, unique_times[ctr-1] 97 | errors = True 98 | if errors: 99 | print('TIMESTEP ERRORS ENCOUNTERED' 100 | -------------------------------------------------------------------------------- /debug/beng/00_input.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | import time 3 | 4 | from casperfpga.memory import bin2fp, fp2fixed_int 5 | from casperfpga.casperfpga import CasperFpga 6 | 7 | # for /tmp/beng_bw_input_snap2.py 8 | 9 | # /tmp/test_syncgen_2016_Feb_10_1242.fpg 10 | # /tmp/test_syncgen2_2016_Feb_10_1219.fpg 11 | 12 | 13 | hostname = 'roach020818' 14 | 15 | f = CasperFpga(hostname) 16 | f.get_system_information() 17 | 18 | f.registers.bf_config.write(tvg_sel=True) 19 | 20 | XENG_ACC_LEN = 256 21 | NUM_ANT = 4 22 | WORDS_PER_FREQ = XENG_ACC_LEN * NUM_ANT 23 | 24 | freqloopctr = 0 25 | freqctr = 0 26 | 27 | basefreq = 0 28 | 29 | while True: 30 | 31 | offset0 = freqloopctr * f.snapshots.bfsyncgen_snap0_ss.length_bytes 32 | offset1 = freqloopctr * f.snapshots.bfsyncgen_snap1_ss.length_bytes 33 | 34 | f.registers.bf_config.write(snap_arm=False) 35 | 36 | # arm the snaps 37 | f.snapshots.bfsyncgen_snap0_ss.arm(offset=offset0) 38 | f.snapshots.bfsyncgen_snap1_ss.arm(offset=offset1) 39 | 40 | # allow them to trigger 41 | f.registers.bf_config.write(snap_arm=True) 42 | 43 | d = f.snapshots.bfsyncgen_snap0_ss.read(arm=False, man_valid=False)['data'] 44 | d2 = f.snapshots.bfsyncgen_snap1_ss.read(arm=False, man_valid=False)['data'] 45 | d.update(d2) 46 | 47 | print('Reading snap0 at byte offset %i' % offset0) 48 | print('Reading snap1 at byte offset %i' % offset1) 49 | 50 | loop_time = -1 51 | 52 | snaplen = len(d[d.keys()[0]]) 53 | print('Snapshot is %i words long. ' % snaplen) 54 | 55 | last_time = -1 56 | last_freq = -1 57 | this_freq_ctr = 0 58 | error = False 59 | 60 | for dctr in range(snaplen): 61 | print(dctr, end='') 62 | print('IN(%i %i %i %i)' % (d['insync'][dctr], 63 | d['inen'][dctr], 64 | d['intime27'][dctr], 65 | d['infreq12'][dctr]), end='') 66 | print('OUT(%i %i %i %i)' % (d['outsync'][dctr], 67 | d['outen'][dctr], 68 | d['outtime27'][dctr], 69 | d['outfreq12'][dctr]), end='') 70 | 71 | # has the timestamp changed in this packet? 72 | if (last_time != -1) and (last_time != d['outtime27'][dctr]): 73 | print('TIMESTEP', end='') 74 | if offset0 != 0: 75 | print('ERROR(time should not have changed)', end='') 76 | error = True 77 | if d['outsync'][dctr-1] != 1: 78 | print('ERROR(time should change ONLY after a sync)', end='') 79 | error = True 80 | if d['outfreq12'][dctr] != 0: 81 | print('ERROR(freq after a time change MUST be zero, for beng0)', end='') 82 | error = True 83 | 84 | # has the frequency changed in this packet 85 | if (last_freq != -1) and (last_freq != d['outfreq12'][dctr]): 86 | print('FSTEP', end='') 87 | if last_freq != 255: 88 | if last_freq != d['outfreq12'][dctr] - 1: 89 | print('ERROR(odd freq step: %i > %i)' % ( 90 | last_freq, d['outfreq12'][dctr]), end='') 91 | error = True 92 | if this_freq_ctr != 1024: 93 | print('ERROR(not enough of freq %i - only %i samples)' % ( 94 | last_freq, this_freq_ctr), end='') 95 | error = True 96 | this_freq_ctr = 0 97 | 98 | print('') 99 | 100 | if d['outen'][dctr] == 1: 101 | this_freq_ctr += 1 102 | last_time = d['outtime27'][dctr] 103 | last_freq = d['outfreq12'][dctr] 104 | 105 | if error: 106 | print('An error forced a stop.') 107 | break 108 | 109 | freqloopctr += 1 110 | freqctr += (snaplen / WORDS_PER_FREQ) 111 | 112 | if freqctr >= 255: 113 | freqctr = 0 114 | freqloopctr = 0 115 | 116 | time.sleep(1) 117 | -------------------------------------------------------------------------------- /scripts/corr2_adc_levels_plot.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import numpy 3 | import matplotlib.pyplot as plt 4 | import corr2 5 | import casperfpga 6 | import time 7 | import argparse 8 | import os 9 | 10 | parser = argparse.ArgumentParser( 11 | description='Display the input power levels from the DIGs.', 12 | formatter_class=argparse.ArgumentDefaultsHelpFormatter) 13 | parser.add_argument( 14 | '--config', dest='config', type=str, action='store', default='', 15 | help='a corr2 config file.') 16 | parser.add_argument('-d', '--db', dest='plot_db', action='store_true', 17 | default=False, 18 | help='Plot power in dBFS rather than linear raw ADC values.') 19 | args = parser.parse_args() 20 | configfile = args.config 21 | if 'CORR2INI' in os.environ.keys() and configfile == '': 22 | configfile = os.environ['CORR2INI'] 23 | if configfile == '': 24 | raise RuntimeError('No good carrying on without a config file') 25 | c = corr2.fxcorrelator.FxCorrelator('adcplot', config_source=configfile) 26 | 27 | plot_db=args.plot_db 28 | n_bits=10 29 | min_range=20*numpy.log10(1./(2**n_bits)) 30 | 31 | fig, axs = plt.subplots(nrows=1, ncols=2, sharex=True) 32 | plt.ion() 33 | plt.show(False) 34 | plt.draw() 35 | 36 | c.initialise(program=False,configure=False,require_epoch=False) 37 | plt_update=0 38 | 39 | def plot_linear(): 40 | xmean=[[],[]] 41 | xmax=[[],[]] 42 | xmin=[[],[]] 43 | stdev=[[],[]] 44 | for pol in range(2): 45 | xmean[pol]=numpy.zeros(len(results)) 46 | stdev[pol]=numpy.zeros(len(results)) 47 | xmax[pol]=numpy.zeros(len(results)) 48 | xmin[pol]=numpy.zeros(len(results)) 49 | for n,fhost in enumerate(c.fhosts): 50 | xmean[pol][n] = (results[fhost.host]['p%i_min'%pol]+results[fhost.host]['p%i_max'%pol])/2 51 | stdev[pol][n] = 10**(results[fhost.host]['p%i_pwr_dBFS'%pol]/20) 52 | xmax[pol][n] = results[fhost.host]['p%i_max'%pol] 53 | xmin[pol][n] = results[fhost.host]['p%i_min'%pol] 54 | 55 | y = numpy.arange(len(results)) 56 | 57 | ax = axs[0] 58 | ax.hlines(y, xmin[0], xmax[0], color='g',linewidth=2.0) 59 | ax.hlines(y, -stdev[0], stdev[0], color='b',linewidth=3.0) 60 | ax.plot(xmean[0],y,'ro') 61 | ax.set_title('Pol 0') 62 | ax.set_xlim(-1,1) 63 | ax.set_ylim(-1,len(results)) 64 | 65 | ax = axs[1] 66 | ax.hlines(y, xmin[1], xmax[1], color='g',linewidth=2.0) 67 | ax.hlines(y, -stdev[1], stdev[1], color='b',linewidth=3.0) 68 | ax.plot(xmean[1],y,'ro') 69 | ax.set_title('Pol 1') 70 | ax.set_xlim(-1,1) 71 | ax.set_ylim(-1,len(results)) 72 | 73 | def plot_log(): 74 | xmean=[[],[]] 75 | xmax=[[],[]] 76 | for pol in range(2): 77 | xmean[pol]=numpy.zeros(len(results)) 78 | xmax[pol]=numpy.zeros(len(results)) 79 | for n,fhost in enumerate(c.fhosts): 80 | xmean[pol][n] = results[fhost.host]['p%i_pwr_dBFS'%pol] 81 | xmax[pol][n] = 20*numpy.log10(results[fhost.host]['p%i_max'%pol]) 82 | 83 | y = numpy.arange(len(results)) 84 | 85 | ax = axs[0] 86 | ax.clear() 87 | ax.hlines(y, min_range, xmax[0], color='b',linewidth=2.0) 88 | ax.hlines(y, min_range, xmean[0], color='g',linewidth=3.0) 89 | ax.set_title('Pol 0') 90 | ax.set_xlim(min_range,0) 91 | ax.set_ylim(-1,len(results)) 92 | 93 | ax = axs[1] 94 | ax.clear() 95 | ax.hlines(y, min_range, xmax[1], color='b',linewidth=2.0) 96 | ax.hlines(y, min_range, xmean[1], color='g',linewidth=3.0) 97 | ax.set_title('Pol 1') 98 | ax.set_xlim(min_range,0) 99 | ax.set_ylim(-1,len(results)) 100 | 101 | 102 | while(True): 103 | plt_update += 1 104 | results=casperfpga.utils.threaded_fpga_operation(c.fhosts,timeout=10,target_function=(lambda feng_:feng_.get_adc_status(),)) 105 | #fig.canvas.clear() 106 | if plot_db: plot_log() 107 | else: plot_linear() 108 | #from IPython import embed; embed() 109 | fig.canvas.draw() 110 | print 'Update {}'.format(plt_update) 111 | time.sleep(0.1) 112 | 113 | plt.close(fig) 114 | -------------------------------------------------------------------------------- /debug/feng_delay_test_register_level.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # pylint: disable-msg=C0103 4 | """ 5 | Test delay tracking 6 | 7 | Created on Tuesday Oct 6 2015 8 | 9 | @author: andrew 10 | """ 11 | import corr2, os, time, logging 12 | import matplotlib.pyplot as plt 13 | 14 | logging.basicConfig(level=logging.INFO) 15 | 16 | sample_rate = 1712*(10**6) 17 | shift_bits = 23 18 | sleep_time = 1 19 | ld_time = 1 20 | wait_time = 2 21 | offset = 1 22 | 23 | #delay 24 | coarse_delay_val = 0 25 | fractional_delay_val = 0 26 | 27 | #delta delay 28 | delta_delay_val_samples = 0 # the final delay value to reach in the sleep time allocated 29 | delta_delay_val = float(delta_delay_val_samples) / (sleep_time * sample_rate) 30 | delta_delay_val_shifted = delta_delay_val * (2 ** shift_bits) 31 | 32 | #phase 33 | phase_val = 0 34 | 35 | #delta phase 36 | delta_phase_val_samples = 0 37 | delta_phase_val = float(delta_phase_val_samples) / (float(sleep_time) * sample_rate) 38 | delta_phase_val_shifted = delta_phase_val * (2 ** shift_bits) 39 | 40 | c = corr2.fxcorrelator.FxCorrelator('rts wbc', config_source=os.environ['CORR2INI']) 41 | c.initialise(qdr_cal=False,program=False) 42 | c.est_sync_epoch() 43 | f = c.fhosts[0] 44 | 45 | # set up tvg 46 | f.registers.impulse1.write(amplitude=0.5, offset=offset) 47 | f.registers.control.write(tvg_adc=1) 48 | 49 | # capture data before setting up delays 50 | x_0 = f.snapshots.snap_quant1_ss.read(man_valid=False, man_trig=False)['data'] 51 | 52 | # set up delay values 53 | f.registers.coarse_delay1.write(coarse_delay=coarse_delay_val) 54 | f.registers.fractional_delay1.write(initial=fractional_delay_val, delta=delta_delay_val_shifted) 55 | f.registers.phase1.write(initial=phase_val, delta=delta_phase_val_shifted) 56 | 57 | mcnt = None 58 | if ld_time is not None: 59 | mcnt = c.mcnt_from_time(time.time() + float(ld_time)) 60 | mcnt_msw = int(mcnt/(2**32)) 61 | mcnt_lsw = int(mcnt - mcnt_msw*(2**32)) 62 | 63 | status_before = f.registers.tl_cd1_status.read()['data'] 64 | print('cd status before: armed => %d arm count => %d load count => %d'%(status_before['armed'], status_before['arm_count'], status_before['load_count'])) 65 | status_before = f.registers.tl_fd1_status.read()['data'] 66 | print('fd status before: armed => %d arm count => %d load count => %d'%(status_before['armed'], status_before['arm_count'], status_before['load_count'])) 67 | 68 | # trigger values 69 | f.registers.tl_cd1_control.write(load_time_lsw=int(mcnt_lsw)) 70 | f.registers.tl_cd1_control0.write(arm='pulse', load_time_msw=int(mcnt_msw)) 71 | 72 | f.registers.tl_fd1_control.write(load_time_lsw=int(mcnt_lsw)) 73 | f.registers.tl_fd1_control0.write(arm='pulse', load_time_msw=int(mcnt_msw)) 74 | 75 | status_before = f.registers.tl_cd1_status.read()['data'] 76 | print('cd status before: armed => %d arm count => %d load count => %d'%(status_before['armed'], status_before['arm_count'], status_before['load_count'])) 77 | status_before = f.registers.tl_fd1_status.read()['data'] 78 | print('fd status before: armed => %d arm count => %d load count => %d'%(status_before['armed'], status_before['arm_count'], status_before['load_count'])) 79 | 80 | # capture data just after setting up delays 81 | x_1 = f.snapshots.snap_quant1_ss.read(man_valid=False, man_trig=False)['data'] 82 | 83 | # sleep 84 | time.sleep(sleep_time+wait_time) 85 | 86 | status_after = f.registers.tl_cd1_status.read()['data'] 87 | print('cd status after: armed => %d arm count => %d load count => %d'%(status_after['armed'], status_after['arm_count'], status_after['load_count'])) 88 | status_after = f.registers.tl_fd1_status.read()['data'] 89 | print('fd status after: armed => %d arm count => %d load count => %d'%(status_after['armed'], status_after['arm_count'], status_after['load_count'])) 90 | 91 | # capture data after 92 | x_2 = f.snapshots.snap_quant1_ss.read(man_valid=False, man_trig=False)['data'] 93 | 94 | plt.figure() 95 | plt.plot(x_0['real0']) 96 | plt.plot(x_0['imag0']) 97 | 98 | plt.figure() 99 | plt.plot(x_1['real0']) 100 | plt.plot(x_1['imag0']) 101 | 102 | plt.figure() 103 | plt.plot(x_2['real0']) 104 | plt.plot(x_2['imag0']) 105 | plt.show() 106 | -------------------------------------------------------------------------------- /debug/xeng_17_x_nd_vacc_tvg_test2.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | """ 4 | """ 5 | import argparse 6 | import os 7 | 8 | from casperfpga import utils as fpgautils 9 | from casperfpga import memory 10 | from corr2 import utils 11 | 12 | parser = argparse.ArgumentParser( 13 | description='Set up the x-engine VACCs.', 14 | formatter_class=argparse.ArgumentDefaultsHelpFormatter) 15 | parser.add_argument('--hosts', dest='hosts', type=str, action='store', 16 | default='', help='comma-delimited list of x-engine hosts') 17 | parser.add_argument('-p', '--polltime', dest='polltime', action='store', 18 | default=1, type=int, 19 | help='time at which to poll fengine data, in seconds') 20 | parser.add_argument('-r', '--reset_count', dest='rstcnt', action='store_true', 21 | default=False, 22 | help='reset all counters at script startup') 23 | parser.add_argument('--comms', dest='comms', action='store', default='katcp', 24 | type=str, help='katcp (default) or dcp?') 25 | parser.add_argument('--loglevel', dest='log_level', action='store', default='', 26 | help='log level to use, default None, options INFO, ' 27 | 'DEBUG, ERROR') 28 | args = parser.parse_args() 29 | 30 | polltime = args.polltime 31 | 32 | if args.log_level != '': 33 | import logging 34 | log_level = args.log_level.strip() 35 | try: 36 | logging.basicConfig(level=eval('logging.%s' % log_level)) 37 | except AttributeError: 38 | raise RuntimeError('No such log level: %s' % log_level) 39 | 40 | if 'CORR2INI' in os.environ.keys() and args.hosts == '': 41 | args.hosts = os.environ['CORR2INI'] 42 | hosts = utils.parse_hosts(args.hosts, section='xengine') 43 | if len(hosts) == 0: 44 | raise RuntimeError('No good carrying on without hosts.') 45 | 46 | # create the devices and connect to them 47 | fpgas = fpgautils.threaded_create_fpgas_from_hosts(hosts) 48 | fpgautils.threaded_fpga_function(fpgas, 15, 'get_system_information') 49 | 50 | vals = [10, 20, 30, 40] 51 | 52 | # and enable it and route the valid line 53 | fpgautils.threaded_fpga_operation( 54 | fpgas, 10, 55 | lambda fpga_: 56 | fpga_.registers.vacctvg_control.write(valid_sel=True, pulse_en=False), ) 57 | 58 | # and enable it and route the valid line 59 | fpgautils.threaded_fpga_operation( 60 | fpgas, 10, 61 | lambda fpga_: 62 | fpga_.registers.vacctvg_control.write(sync_sel=True),) 63 | 64 | # and enable it and route the valid line 65 | fpgautils.threaded_fpga_operation( 66 | fpgas, 10, 67 | lambda fpga_: 68 | fpga_.registers.vacctvg_control.write(reset='pulse'), ) 69 | 70 | # set up the valid pulse generator 71 | for ctr in range(4): 72 | _pref = 'sys%i_vacc_tvg0' % ctr 73 | 74 | regname = '%s_n_pulses' % _pref 75 | fpgautils.threaded_fpga_operation( 76 | fpgas, 10, 77 | lambda fpga_: fpga_.registers[regname].write_int(777777), ) 78 | 79 | regname = '%s_n_per_group' % _pref 80 | fpgautils.threaded_fpga_operation( 81 | fpgas, 10, 82 | lambda fpga_: fpga_.registers[regname].write_int(64), ) 83 | 84 | regname = '%s_group_period' % _pref 85 | fpgautils.threaded_fpga_operation( 86 | fpgas, 10, 87 | lambda fpga_: fpga_.registers[regname].write_int(1024), ) 88 | 89 | # _regname = '%s_ins_vect_loc' % _pref 90 | # fpgautils.threaded_fpga_operation( 91 | # fpgas, 10, 92 | # lambda fpga_: fpga_.registers[_regname].write_int(100), ) 93 | # 94 | # _regname = '%s_ins_vect_val' % _pref 95 | # fpgautils.threaded_fpga_operation( 96 | # fpgas, 10, 97 | # lambda fpga_: fpga_.registers[_regname].write_int(vals[ctr]), ) 98 | # 99 | # fpgautils.threaded_fpga_operation( 100 | # fpgas, 10, 101 | # lambda fpga_: fpga_.registers.vacctvg_control.write(vector_en=True), ) 102 | 103 | # and enable it and route the valid line 104 | fpgautils.threaded_fpga_operation( 105 | fpgas, 10, 106 | lambda fpga_: 107 | fpga_.registers.vacctvg_control.write(valid_sel=True, pulse_en=True), ) 108 | 109 | -------------------------------------------------------------------------------- /src/delay.py: -------------------------------------------------------------------------------- 1 | from threading import Event 2 | import logging 3 | 4 | LOGGER = logging.getLogger(__name__) 5 | 6 | 7 | class DelaysUnsetError(Exception): 8 | pass 9 | 10 | 11 | def process_list(delay_list, sample_rate_hz): 12 | """ 13 | Given a list of strings or delay tuples, return a list of delay tuples 14 | NOTE: THIS WILL CONVERT SECONDS TO SAMPLES FOR DELAY! 15 | :param delay_list: a list of strings (delay,rate:phase,rate) or 16 | delay tuples ((delay,rate),(phase,rate)) 17 | :param sample_rate_hz: the sample rate of the incoming data 18 | :return: a list of Delay objects 19 | """ 20 | def process_string(delaystr): 21 | bits = delaystr.strip().split(':') 22 | delay = bits[0] 23 | delay = delay.split(',') 24 | delay = (float(delay[0]), float(delay[1])) 25 | fringe = bits[1] 26 | fringe = fringe.split(',') 27 | fringe = (float(fringe[0]), float(fringe[1])) 28 | return delay, fringe 29 | rv = [] 30 | for ctr, delay in enumerate(delay_list): 31 | try: 32 | if isinstance(delay, str): 33 | delaytup = process_string(delay) 34 | LOGGER.debug('input %i update received: %s'%(ctr,delay)) 35 | else: 36 | delaytup = delay 37 | rv.append(prepare_delay_vals(delaytup, sample_rate_hz)) 38 | except: 39 | errmsg = 'delay.process_list(): given delay \'%s\' at position %i' \ 40 | ' is not a valid delay setting' % (delay, ctr) 41 | LOGGER.error(errmsg) 42 | raise ValueError(errmsg) 43 | return rv 44 | 45 | 46 | def prepare_delay_vals(coefficients, sample_rate): 47 | """ 48 | 49 | :param coefficients: the delay and phase coefficients, as a tuple 50 | :param sample_rate: system sample rate, in Hz 51 | :return: 52 | """ 53 | if len(coefficients) != 2: 54 | errmsg = 'Incorrectly supplied coefficient tuple: %s. Expecting ((delay,rate),(phase,rate)).' % coefficients 55 | LOGGER.error(errmsg) 56 | raise ValueError(errmsg) 57 | delay_coeff = coefficients[0] 58 | phase_coeff = coefficients[1] 59 | # convert delay in time into delay in clock cycles 60 | delay_s = float(delay_coeff[0]) * sample_rate 61 | # convert to fractions of a sample 62 | import numpy 63 | phase_offset_s = float(phase_coeff[0])/float(numpy.pi) 64 | # convert from radians per second to fractions of sample per sample 65 | delta_phase_offset_s = (float(phase_coeff[1]) / float(numpy.pi) / 66 | sample_rate) 67 | return Delay(delay_s, delay_coeff[1], phase_offset_s, delta_phase_offset_s) 68 | 69 | 70 | class Delay(object): 71 | def __init__(self, delay=0.0, delay_delta=0.0, 72 | phase_offset=0.0, phase_offset_delta=0.0, 73 | load_mcnt=-1, load_count=-1, arm_count=-1, last_load_success=True): 74 | """ 75 | :param delay is in samples 76 | :param delay_delta is in samples per sample 77 | :param phase_offset is in fractions of a sample 78 | :param phase_offset_delta is in samples per sample 79 | :param load_mcnt is in samples since epoch 80 | :param load_cnt is integer 81 | :param arm_cnt is integer 82 | :param last_load_success: boolean, did the last delay load succeed? 83 | """ 84 | self.delay = delay 85 | self.delay_delta = delay_delta 86 | self.phase_offset = phase_offset 87 | self.phase_offset_delta = phase_offset_delta 88 | self.load_mcnt = load_mcnt 89 | self.last_load_success = last_load_success 90 | self.load_count = load_count 91 | self.arm_count = arm_count 92 | self.error = Event() 93 | 94 | # @classmethod 95 | # def from_coefficients(cls, coefficients, sample_rate): 96 | # coeff_tuple = process_list([coefficients])[0] 97 | # return prepare_delay_vals(coeff_tuple, sample_rate) 98 | 99 | def __str__(self): 100 | return 'Delay@{}: {},{}:{},{}'.format(self.load_mcnt,self.delay, 101 | self.delay_delta,self.phase_offset, self.phase_offset_delta) 102 | 103 | # end 104 | -------------------------------------------------------------------------------- /debug/fengct_input.py: -------------------------------------------------------------------------------- 1 | import feng_utils 2 | import time 3 | import numpy as np 4 | import scipy.io as sio 5 | 6 | hosts = feng_utils.setup_fhosts() 7 | # feng_utils.ct_tvg(hosts, 1) 8 | 9 | while True: 10 | feng_utils.print_err_regs(hosts) 11 | break 12 | time.sleep(1) 13 | 14 | # 15 | # 16 | # d = f.snapshots.ct_dv_in_ss.read(circular_capture=True, 17 | # man_trig=True)['data'] 18 | # dvs = [] 19 | # for dv in d['dv32']: 20 | # dvs.extend(decode(dv, 32)) 21 | # rising_edge = -1 22 | # problem_location = -1 23 | # for ctr in range(1, len(dvs)): 24 | # dv_prev = dvs[ctr - 1] 25 | # dv = dvs[ctr] 26 | # # print dv, 27 | # if dv == 1 and dv_prev == 0: 28 | # rising_edge = ctr 29 | # if dv == 0 and dv_prev == 1: 30 | # diff = ctr - rising_edge 31 | # if diff != 512 and ctr > 1000: 32 | # problem_location = ctr 33 | # break 34 | # 35 | # if problem_location > -1: 36 | # print problem_location 37 | # start = max(0, problem_location - 1500) 38 | # end = min(problem_location + 1500, len(dvs)) 39 | # print start 40 | # print end 41 | # print dvs[start:end] 42 | # 43 | # for host in ['skarab02030A-01', 'skarab02030B-01', 44 | # 'skarab02030C-01', 'skarab02030E-01']: 45 | # f = casperfpga.CasperFpga(host) 46 | # f.get_system_information('/home/paulp/bofs/s_c856m4k_p_2017-8-8_0927.fpg') 47 | # print host, f.registers.qt_dv_err.read()['data'], f.registers.ct_dv_err.read()['data'], f.registers.pack_dv_err.read()['data'], f.registers.gbe0_txerrctr.read()['data'] 48 | # 49 | # f = casperfpga.CasperFpga('skarab02030A-01') 50 | # f.get_system_information('/home/paulp/bofs/s_c856m4k_p_2017-8-8_0927.fpg') 51 | # 52 | # import IPython 53 | # IPython.embed() 54 | # 55 | # raise RuntimeError 56 | 57 | # f = hosts[0] 58 | # f.registers.ct_debug.write(in_stopmux=2) 59 | # # d = f.snapshots.ct_dv_in_ss.read(man_trig=True)['data'] 60 | # d = f.snapshots.ct_dv256_in_ss.read(man_trig=True)['data'] 61 | # dvs = [] 62 | # for dv in d['dv32']: 63 | # dvs.extend(feng_utils.decode(dv, 32)) 64 | # zero_start = -1 65 | # one_start = -1 66 | # one_len = {} 67 | # zero_len = {} 68 | # for ctr in range(1, len(dvs)): 69 | # prtstr = '%5i: %i' % (ctr, dvs[ctr]) 70 | # if dvs[ctr] == 1 and dvs[ctr-1] == 0: 71 | # zlen = ctr - zero_start 72 | # if zlen not in zero_len: 73 | # zero_len[zlen] = 0 74 | # zero_len[zlen] += 1 75 | # one_start = ctr 76 | # prtstr += ' %i' % zlen 77 | # elif dvs[ctr] == 0 and dvs[ctr-1] == 1: 78 | # olen = ctr - one_start 79 | # if olen not in one_len: 80 | # one_len[olen] = 0 81 | # one_len[olen] += 1 82 | # zero_start = ctr 83 | # prtstr += ' %i' % olen 84 | # # print(prtstr) 85 | # 86 | # print zero_len 87 | # print one_len 88 | # 89 | # import IPython 90 | # IPython.embed() 91 | 92 | f = hosts[0] 93 | loopctr = 0 94 | try: 95 | while True: 96 | stime = time.time() 97 | print('Triggering snap%i at %.3f' % (loopctr, stime)) 98 | d = f.snapshots.ct_dv_in_ss.read(circular_capture=True, 99 | man_trig=True)['data'] 100 | dvs = [] 101 | for dv in d['dv32']: 102 | dvs.extend(feng_utils.decode(dv, 32)) 103 | # print len(dvs) 104 | # raise RuntimeError 105 | datadict = { 106 | 'simin_dv': { 107 | 'time': [], 'signals': { 108 | 'dimensions': 1, 109 | 'values': np.array(dvs, dtype=np.uint32) 110 | } 111 | } 112 | } 113 | datadict['simin_dv']['signals']['values'].shape = (len(dvs), 1) 114 | filename = '/tmp/ct_in%03i.mat' % loopctr 115 | sio.savemat(filename, datadict) 116 | print('\twaited %.3f seconds and saved: %s ' % ( 117 | (time.time() - stime), filename)) 118 | loopctr += 1 119 | if loopctr == 100: 120 | raise KeyboardInterrupt 121 | except KeyboardInterrupt: 122 | print('Saved %i files in /tmp/' % loopctr) 123 | 124 | # import IPython 125 | # IPython.embed() 126 | 127 | # end 128 | -------------------------------------------------------------------------------- /debug/xeng_30_qdr_errcheck.py: -------------------------------------------------------------------------------- 1 | import time 2 | import casperfpga 3 | from casperfpga import utils as fpgautils 4 | import numpy.random as nprand 5 | 6 | THREADED_FPGA_OP = fpgautils.threaded_fpga_operation 7 | THREADED_FPGA_FUNC = fpgautils.threaded_fpga_function 8 | 9 | hosts = ['roach02081a', 'roach020712', 'roach020818', 'roach02064a'] 10 | 11 | xfs = [] 12 | errors_undetected = {} 13 | undetected_writes = {} 14 | 15 | for host in hosts: 16 | f = casperfpga.KatcpFpga(host) 17 | f.get_system_information() 18 | xfs.append(f) 19 | 20 | f = xfs[0] 21 | 22 | snapname = 'vaccsnap_0_ss' 23 | snapname = 'snap_vacc_ss' 24 | 25 | snap = f.snapshots[snapname] 26 | 27 | f.registers.vacc_snap_ctrl.write(arm=0) 28 | snap.arm(circular_capture=True, man_valid=False) 29 | # f.snapshots.vaccsnap_1_ss.arm(circular_capture=True, man_valid=False) 30 | f.registers.vacc_snap_ctrl.write(arm=1) 31 | 32 | d = snap.read(arm=False)['data'] 33 | # d.update(f.snapshots.vaccsnap_1_ss.read(arm=False)['data']) 34 | 35 | print(len(d[d.keys()[0]]) 36 | 37 | # d['dreal_acc'] = [] 38 | # d['dimage_acc'] = [] 39 | # d['dreal_qdr'] = [] 40 | # d['dimage_qdr'] = [] 41 | # for ctr in range(len(d[d.keys()[0]])): 42 | # _acc_data = (d['acc_data_ms60'][ctr] << 8) | d['acc_data_ls8'][ctr] 43 | # _dr = _acc_data & (2**32-1) 44 | # _di = (_acc_data >> 32) & (2**32-1) 45 | # d['dreal_acc'].append(_dr) 46 | # d['dimage_acc'].append(_di) 47 | # _dr = d['qdr_data'][ctr] & (2**32-1) 48 | # _di = (d['qdr_data'][ctr] >> 32) & (2**32-1) 49 | # d['dreal_qdr'].append(_dr) 50 | # d['dimage_qdr'].append(_di) 51 | # d.pop('qdr_data') 52 | # d.pop('acc_data_ms60') 53 | # d.pop('acc_data_ls8') 54 | 55 | key_order = ['new_acc', 'fifo_rd_en', 'qdr_data_ls10', 'qdr_wr_en', 'qdr_addr', 56 | 'qdr_valid', 'blank', 'qdr_addr_del', 'burst_rdy', 'qdr_rd_en'] 57 | 58 | print('ctr\t', 59 | for key in d.keys(): 60 | print(key, '\t', 61 | print('' 62 | for ctr in range(len(d['new_acc'])): 63 | print(ctr, 64 | for key in d.keys(): 65 | print(d[key][ctr], '\t', 66 | print('' 67 | 68 | # import IPython 69 | # IPython.embed() 70 | 71 | 72 | # before_writing = THREADED_FPGA_OP( 73 | # xfs, timeout=5, 74 | # target_function=(lambda fpga_: 75 | # fpga_.registers.control.write(cnt_rst='pulse'),)) 76 | # 77 | # total_ctr = 0 78 | # 79 | # while True: 80 | # 81 | # word_to_write = int(nprand.random() * (2**32)) 82 | # word_to_write = int(nprand.random() * (2**16)) 83 | # 84 | # before_writing = [ 85 | # THREADED_FPGA_OP( 86 | # xfs, timeout=5, 87 | # target_function=(lambda fpga_: 88 | # fpga_.registers['vacc_errors%i' % qdrnum].read(),)) 89 | # for qdrnum in range(0, 4)] 90 | # 91 | # [THREADED_FPGA_OP( 92 | # xfs, timeout=5, 93 | # target_function=(lambda fpga_: 94 | # fpga_.write_int('qdr%i_memory' % qdrnum, word_to_write, 95 | # blindwrite=True),)) 96 | # for qdrnum in range(0, 4)] 97 | # 98 | # time.sleep(1) 99 | # 100 | # after_writing = [ 101 | # THREADED_FPGA_OP( 102 | # xfs, timeout=5, 103 | # target_function=(lambda fpga_: 104 | # fpga_.registers['vacc_errors%i' % qdrnum].read(),)) 105 | # for qdrnum in range(0, 4)] 106 | # 107 | # total_ctr += 1 108 | # 109 | # for f in xfs: 110 | # print(f.host, ':' 111 | # for qdrnum in range(0, 4): 112 | # before = before_writing[qdrnum][f.host]['data']['parity'] 113 | # after = after_writing[qdrnum][f.host]['data']['parity'] 114 | # print('\t%i: %i > %i' % (qdrnum, before, after) 115 | # if before == after: 116 | # errors_undetected[f.host][qdrnum] += 1 117 | # _errnum = '0x%08x' % word_to_write 118 | # if _errnum not in undetected_writes[f.host]: 119 | # undetected_writes[f.host].append(_errnum) 120 | # print('undetected errors = %s / %i' % (errors_undetected[f.host], 121 | # total_ctr) 122 | # print('vals = %s' % undetected_writes[f.host] 123 | -------------------------------------------------------------------------------- /debug/fake_spec_ctrl.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | 4 | import casperfpga 5 | import argparse 6 | 7 | parser = argparse.ArgumentParser( 8 | description='Set up and run a fake spectrometer - data is just a ramp of' 9 | '64-bit integers.', 10 | formatter_class=argparse.ArgumentDefaultsHelpFormatter) 11 | 12 | parser.add_argument('--host', dest='host', type=str, action='store', 13 | required=True, 14 | default='roach02064a', help='the host to use') 15 | 16 | parser.add_argument('-p', '--program', dest='program', action='store_true', 17 | default=False, help='program the FPGA') 18 | parser.add_argument('--fpg', dest='fpg', type=str, action='store', 19 | default='/tmp/fake_spec_2016_Apr_12_1332.fpg', 20 | help='path to fpga binary') 21 | 22 | parser.add_argument('--ip', dest='host_ip', type=str, action='store', 23 | default='10.100.0.110', help='host IP') 24 | parser.add_argument('--mac', dest='host_mac', type=str, action='store', 25 | default='02:02:00:00:02:10', help='host MAC') 26 | parser.add_argument('--port', dest='host_port', type=int, action='store', 27 | default=9999, help='host port') 28 | 29 | parser.add_argument('--tx_ip', dest='tx_ip', type=str, action='store', 30 | default='10.100.201.1', help='destination IP') 31 | parser.add_argument('--tx_port', dest='tx_port', type=int, action='store', 32 | default=9876, help='destination port') 33 | 34 | parser.add_argument('--pkt_rate', dest='pkt_rate', type=int, action='store', 35 | default=2**22, help='send one packet (not heap) every X ' 36 | 'fpga clock cycles') 37 | 38 | parser.add_argument('--txen', dest='tx_enable', action='store_true', 39 | default=False, help='enable transmission') 40 | parser.add_argument('--txstop', dest='tx_disable', action='store_true', 41 | default=False, help='stop transmission') 42 | parser.add_argument('--reset_pkt', dest='reset_tvg', action='store_true', 43 | default=False, help='reset packet transmission') 44 | 45 | parser.add_argument('--loglevel', dest='log_level', action='store', 46 | default='INFO', 47 | help='log level to use, default None, options INFO, ' 48 | 'DEBUG, ERROR') 49 | args = parser.parse_args() 50 | 51 | if args.log_level != '': 52 | import logging 53 | log_level = args.log_level.strip() 54 | try: 55 | logging.basicConfig(level=eval('logging.%s' % log_level)) 56 | except AttributeError: 57 | raise RuntimeError('No such log level: %s' % log_level) 58 | 59 | # make the fpga 60 | f = casperfpga.KatcpFpga(args.host) 61 | if args.program: 62 | logging.info('Programming FPGA') 63 | f.upload_to_ram_and_program(args.fpg) 64 | else: 65 | f.get_system_information() 66 | 67 | # set the packet-rate 68 | if args.program: 69 | logging.info('Setting packet rate to {}'.format(args.pkt_rate)) 70 | f.registers.pkt_rate.write(rate=args.pkt_rate) 71 | 72 | # set the tx ip and core 73 | if args.program: 74 | logging.info('Setting up destination registers, {}:{}'.format( 75 | args.tx_ip, args.tx_port 76 | )) 77 | _ip_int = casperfpga.tengbe.IpAddress.str2ip(args.tx_ip) 78 | f.registers.ip.write(ip=_ip_int) 79 | f.registers.port.write(port=args.tx_port) 80 | 81 | # set up the tengbe core 82 | if args.program: 83 | f.registers.ctrl.write(data_en=False, gbe_rst=True) 84 | f.tengbes.gbe0.setup(mac=args.host_mac, ipaddress=args.host_ip, 85 | port=args.host_port) 86 | f.tengbes.gbe0.dhcp_start() 87 | f.registers.ctrl.write(gbe_rst=False) 88 | logging.info('Set up tengbe core: %s' % f.tengbes.gbe0) 89 | 90 | # reset the data gen 91 | if args.program or args.reset_tvg: 92 | logging.info('Resetting data gen') 93 | f.registers.ctrl.write(rst='pulse') 94 | 95 | # enable the data to the core 96 | if args.tx_enable: 97 | logging.info('Enabling data transmission') 98 | f.registers.ctrl.write(data_en=True) 99 | if args.tx_disable: 100 | logging.info('Stopping data transmission') 101 | f.registers.ctrl.write(data_en=False) 102 | 103 | # done 104 | -------------------------------------------------------------------------------- /debug/xeng_00_x_new_aa_timesnap.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """ 3 | """ 4 | import argparse 5 | 6 | 7 | parser = argparse.ArgumentParser(description='Display reorder preprocess timesnap block - to figure ' 8 | 'out what timestamps are being used.', 9 | formatter_class=argparse.ArgumentDefaultsHelpFormatter) 10 | parser.add_argument(dest='host', type=str, action='store', 11 | help='x-engine host') 12 | parser.add_argument('-feng1', dest='feng1', type=str, action='store', default='0,0,17', 13 | help='feng_num,freq1,freq2') 14 | parser.add_argument('-feng2', dest='feng2', type=str, action='store', default='1,1,18', 15 | help='feng_num,freq1,freq2') 16 | parser.add_argument('-verbose', dest='verbose', action='store_true', default=False, 17 | help='Output verbose data') 18 | parser.add_argument('--comms', dest='comms', action='store', default='katcp', type=str, 19 | help='katcp (default) or dcp?') 20 | parser.add_argument('--loglevel', dest='log_level', action='store', default='', 21 | help='log level to use, default None, options INFO, DEBUG, ERROR') 22 | args = parser.parse_args() 23 | 24 | if args.log_level != '': 25 | import logging 26 | log_level = args.log_level.strip() 27 | try: 28 | logging.basicConfig(level=eval('logging.%s' % log_level)) 29 | except AttributeError: 30 | raise RuntimeError('No such log level: %s' % log_level) 31 | 32 | if args.comms == 'katcp': 33 | HOSTCLASS = CasperFpga 34 | else: 35 | HOSTCLASS = dcp_fpga.DcpFpga 36 | 37 | # create the device and connect to it 38 | xeng_fpga = HOSTCLASS(args.host) 39 | xeng_fpga.get_system_information() 40 | 41 | feng1 = [int(f) for f in args.feng1.split(',')] 42 | feng2 = [int(f) for f in args.feng2.split(',')] 43 | 44 | # set up the debug 45 | xeng_fpga.registers.snaptime_setup1.write(feng_id1=feng1[0], freq1=feng1[1], freq2=feng1[2], 46 | feng_id2=feng2[0], freq3=feng2[1], freq4=feng2[2]) 47 | 48 | xeng_fpga.registers.snaptime_setup2.write(feng_id1=feng1[0], freq1=feng1[1], freq2=feng1[2], 49 | feng_id2=feng2[0], freq3=feng2[1], freq4=feng2[2]) 50 | 51 | # arm the snapblock 52 | xeng_fpga.snapshots.snaptime_x0_f1_fr1_ss.arm() 53 | xeng_fpga.snapshots.snaptime_x0_f1_fr2_ss.arm() 54 | xeng_fpga.snapshots.snaptime_x1_f1_fr1_ss.arm() 55 | xeng_fpga.snapshots.snaptime_x1_f1_fr2_ss.arm() 56 | xeng_fpga.snapshots.snaptime_x2_f1_fr1_ss.arm() 57 | xeng_fpga.snapshots.snaptime_x2_f1_fr2_ss.arm() 58 | xeng_fpga.snapshots.snaptime_x3_f1_fr1_ss.arm() 59 | xeng_fpga.snapshots.snaptime_x3_f1_fr2_ss.arm() 60 | 61 | # trigger 62 | xeng_fpga.registers.control.write(snap_trigger='pulse') 63 | 64 | # read 65 | snapdata1 = xeng_fpga.snapshots.snaptime_x0_f1_fr1_ss.read(arm=False)['data']['time'] 66 | snapdata2 = xeng_fpga.snapshots.snaptime_x0_f1_fr2_ss.read(arm=False)['data']['time'] 67 | snapdata3 = xeng_fpga.snapshots.snaptime_x1_f1_fr1_ss.read(arm=False)['data']['time'] 68 | snapdata4 = xeng_fpga.snapshots.snaptime_x1_f1_fr2_ss.read(arm=False)['data']['time'] 69 | snapdata5 = xeng_fpga.snapshots.snaptime_x2_f1_fr1_ss.read(arm=False)['data']['time'] 70 | snapdata6 = xeng_fpga.snapshots.snaptime_x2_f1_fr2_ss.read(arm=False)['data']['time'] 71 | snapdata7 = xeng_fpga.snapshots.snaptime_x3_f1_fr1_ss.read(arm=False)['data']['time'] 72 | snapdata8 = xeng_fpga.snapshots.snaptime_x3_f1_fr2_ss.read(arm=False)['data']['time'] 73 | 74 | xeng_fpga.disconnect() 75 | 76 | starttime = [] 77 | endtime = [] 78 | for snapdata in [snapdata1, snapdata2, snapdata3, snapdata4, 79 | snapdata5, snapdata6, snapdata7, snapdata8]: 80 | oldtime = snapdata[0]-1 81 | oldctr = -128 82 | starttime.append(oldtime) 83 | for ctr, newtime in enumerate(snapdata): 84 | if newtime != oldtime: 85 | if args.verbose: 86 | print(oldtime, 87 | assert newtime == oldtime + 1, '%d, %d' % (newtime, oldtime) 88 | assert ctr == oldctr + 128, '%d, %d' % (ctr, oldctr) 89 | oldtime = newtime 90 | oldctr = ctr 91 | if args.verbose: 92 | print('' 93 | endtime.append(oldtime) 94 | print('All times increased monotonically. Check the starts and stops across f-engines and frequencies.' 95 | print(starttime 96 | print(endtime 97 | 98 | # end 99 | --------------------------------------------------------------------------------