예제 #1
0
 def program(self, bitstream=None):
     progfile = bitstream or self.config['fpgfile']
     self.logger.info('Programming all SNAPs with %s' % progfile)
     utils.program_fpgas([feng.fpga for feng in self.fengs],
                         progfile,
                         timeout=300.0)
     self.r['corr:snap:last_programmed'] = time.ctime()
예제 #2
0
 def program(self, bitstream=None, unprogrammed_only=True):
     """
     Program SNAPs.
     Inputs:
         bitstream (str): Path to fpgfile to program. If None, the bitstream described in the current configuration will be used.
         unprogrammed_only (Boolean): If True, only program boards which aren't yet programmed. Current state is determined by a lazy
                                      check for the "adc16_controller" register. If it exists, the board is deemed programmed.
     """
     progfile = bitstream or self.config['fpgfile']
     self.logger.info('Programming all SNAPs with %s' % progfile)
     if unprogrammed_only:
         to_be_programmed = []
         for feng in self.fengs:
             if 'adc16_controller' not in feng.fpga.listdev():
                 to_be_programmed += [feng]
         if len(to_be_programmed) == 0:
             return
     else:
         to_be_programmed = self.fengs
     utils.program_fpgas([f.fpga for f in to_be_programmed],
                         progfile,
                         timeout=300.0)
     for f in to_be_programmed:
         self.r.hset('status:snap:%s' % f.host, 'last_programmed',
                     time.ctime())
예제 #3
0
    def program(self, bitstream=None, unprogrammed_only=True):
        """
        Program SNAPs.
        Inputs:
            bitstream (str): Path to fpgfile to program. If None, the bitstream described in the current configuration will be used.
            unprogrammed_only (Boolean): If True, only program boards which aren't yet programmed.
        """
        TEMP_BITSTREAM_STORE = "/tmp/"
        progfile = bitstream or self.config['fpgfile']
        self.logger.info('Programming all SNAPs with %s' % progfile)
        if progfile.startswith("redis:"):
            progfile = progfile.split(":")[-1]
            try:
                bitstream = self.r.hget("fpg:%s" % progfile, "fpg")
            except KeyError:
                self.logger.error(
                    "FPG file %s not available in redis. Cannot program" %
                    progfile)
                return
            progfile = os.path.join(TEMP_BITSTREAM_STORE, progfile)
            with open(progfile, "wb") as fh:
                fh.write(bitstream)

        if unprogrammed_only:
            to_be_programmed = []
            for feng in self.fengs:
                if not feng.is_programmed():
                    to_be_programmed += [feng]
            if len(to_be_programmed) == 0:
                self.logger.info(
                    "Skipping programming because all boards seem ready")
                return
        else:
            to_be_programmed = self.fengs
        self.logger.info("Actually programming %s" %
                         ([f.host for f in self.fengs]))
        utils.program_fpgas([f.fpga for f in to_be_programmed],
                            progfile,
                            timeout=300.0)
        time.sleep(20)
        for f in to_be_programmed:
            self.r.hset('status:snap:%s' % f.host, 'last_programmed',
                        time.ctime())
예제 #4
0
except AttributeError:
    raise RuntimeError('No such log level: %s' % log_level)
LOGGER = logging.getLogger(__name__)

THREADED_FPGA_OP = fpgautils.threaded_fpga_operation
THREADED_FPGA_FUNC = fpgautils.threaded_fpga_function

# read the config file
configd = fpgautils.parse_ini_file(args.config)
filter_cfg = configd['filter']

# program the filter boards
filter_fpgas = []
for _f in filter_cfg['hosts']:
    filter_fpgas.append(HOSTCLASS(_f))
fpgautils.program_fpgas(filter_fpgas, progfile=filter_cfg['bitstream'], timeout=15)
THREADED_FPGA_FUNC(filter_fpgas, timeout=10, target_function='get_system_information')

# set up the fpga comms
THREADED_FPGA_OP(filter_fpgas, timeout=10,
                 target_function=(lambda fpga_: fpga_.registers.control.write(gbe_txen=False),))
THREADED_FPGA_OP(filter_fpgas, timeout=10,
                 target_function=(lambda fpga_: fpga_.registers.control.write(gbe_rst=False),))
THREADED_FPGA_OP(filter_fpgas, timeout=10,
                 target_function=(lambda fpga_:
                                  fpga_.registers.control.write(status_clr='pulse',
                                                                gbe_cnt_rst='pulse',
                                                                cnt_rst='pulse'),))

# where does the filter data go?
THREADED_FPGA_OP(filter_fpgas, timeout=5,
예제 #5
0
    def initialise(self, program=True, qdr_cal=True):
        """
        Set up the correlator using the information in the config file.
        :return:
        """
        # set up the F, X, B and filter handlers
        self.fops = FEngineOperations(self)
        self.xops = XEngineOperations(self)
        # self.bops = BEngineOperations(self)
        self.filtops = FilterOperations(self)

        # set up the filter boards if we need to
        if 'filter' in self.configd:
            try:
                self.filtops.initialise(program=program)
            except Exception as e:
                raise e

        # connect to the other hosts that make up this correlator
        THREADED_FPGA_FUNC(self.fhosts + self.xhosts, timeout=5,
                           target_function='connect')

        igmp_version = self.configd['FxCorrelator'].get('igmp_version')
        if igmp_version is not None:
            self.logger.info('Setting FPGA hosts IGMP version to '
                             '%s' % igmp_version)
            THREADED_FPGA_FUNC(
                self.fhosts + self.xhosts, timeout=5, target_function=(
                    'set_igmp_version', (igmp_version, ), {}))

        # if we need to program the FPGAs, do so
        if program:
            self.logger.info('Programming FPGA hosts')
            fpgautils.program_fpgas([(host, host.boffile) for host in
                                     (self.fhosts + self.xhosts)],
                                    progfile=None, timeout=15)
        else:
            self.logger.info('Loading design information')
            THREADED_FPGA_FUNC(self.fhosts + self.xhosts, timeout=7,
                               target_function='get_system_information')

        # remove test hardware from designs
        utils.disable_test_gbes(self)
        utils.remove_test_objects(self)
        if program:
            # cal the qdr on all boards
            if qdr_cal:
                self.qdr_calibrate()
            else:
                self.logger.info('Skipping QDR cal - are you sure you'
                                 ' want to do this?')

            # init the engines
            self.fops.initialise()
            self.xops.initialise()

            # are there beamformers?
            if self.found_beamformer:
                bengops.beng_initialise(self)

            # for fpga_ in self.fhosts:
            #     fpga_.tap_arp_reload()
            # for fpga_ in self.xhosts:
            #     fpga_.tap_arp_reload()

            # subscribe all the engines to the multicast groups
            self.fops.subscribe_to_multicast()
            self.xops.subscribe_to_multicast()

            post_mess_delay = 10
            self.logger.info('post mess-with-the-switch delay of '
                             '%is' % post_mess_delay)
            time.sleep(post_mess_delay)

            # force a reset on the f-engines
            self.fops.sys_reset(sleeptime=1)

            # reset all counters on fhosts and xhosts
            self.fops.clear_status_all()
            self.xops.clear_status_all()

            # check to see if the f engines are receiving all their data
            if not self.fops.check_rx():
                raise RuntimeError('The f-engines RX have a problem.')

            # start f-engine TX
            self.logger.info('Starting f-engine datastream')
            self.fops.tx_enable()

            # check that the F-engines are transmitting data correctly
            if not self.fops.check_tx():
                raise RuntimeError('The f-engines TX have a problem.')

            # check that the X-engines are receiving data
            if not self.xops.check_rx():
                raise RuntimeError('The x-engines RX have a problem.')

            # arm the vaccs on the x-engines
            self.xops.vacc_sync()

        # reset all counters on fhosts and xhosts
        self.fops.clear_status_all()
        self.xops.clear_status_all()

        # set an initialised flag
        self._initialised = True
예제 #6
0
    def initialise(self, program=True, qdr_cal=True, require_epoch=False):
        """
        Set up the correlator using the information in the config file.
        :param program: program the FPGA boards if True
        :param qdr_cal: perform QDR cal if True
        :param require_epoch: the synch epoch MUST be set before init if True
        :return:
        """
        # check that the instrument's synch epoch has been set
        if require_epoch:
            if self.get_synch_time() == -1:
                raise RuntimeError('System synch epoch has not been set prior'
                                   ' to initialisation!')

        # set up the F, X, B and filter handlers
        self.fops = FEngineOperations(self)
        self.xops = XEngineOperations(self)
        self.bops = BEngineOperations(self)
        self.filtops = FilterOperations(self)
        self.speadops = SpeadOperations(self)

        # set up the filter boards if we need to
        if 'filter' in self.configd:
            try:
                self.filtops.initialise(program=program)
            except Exception as e:
                raise e

        # connect to the other hosts that make up this correlator
        THREADED_FPGA_FUNC(self.fhosts + self.xhosts, timeout=5,
                           target_function='connect')

        igmp_version = self.configd['FxCorrelator'].get('igmp_version')
        if igmp_version is not None:
            self.logger.info('Setting FPGA hosts IGMP version '
                             'to %s' % igmp_version)
            THREADED_FPGA_FUNC(
                self.fhosts + self.xhosts, timeout=5,
                target_function=('set_igmp_version', (igmp_version, ), {}))

        # if we need to program the FPGAs, do so
        if program:
            self.logger.info('Programming FPGA hosts')
            fpgautils.program_fpgas([(host, host.boffile) for host in
                                     (self.fhosts + self.xhosts)],
                                    progfile=None, timeout=15)
        else:
            self.logger.info('Loading design information')
            THREADED_FPGA_FUNC(self.fhosts + self.xhosts, timeout=10,
                               target_function='get_system_information')

        # remove test hardware from designs
        utils.disable_test_gbes(self)
        utils.remove_test_objects(self)

        # run configuration on the parts of the instrument
        self.configure()

        # run post-programming initialisation
        self._initialise(program, qdr_cal)

        # reset all counters on fhosts and xhosts
        self.fops.clear_status_all()
        self.xops.clear_status_all()

        # set an initialised flag
        self._initialised = True