Ejemplo n.º 1
0
    def readout(self, no_data_timeout=None):
        '''Readout thread continuously reading SRAM.

        Readout thread, which uses read_data() and appends data to self._data_deque (collection.deque).
        '''
        logging.debug('Starting %s' % (self.readout_thread.name, ))
        curr_time = get_float_time()
        time_wait = 0.0
        while not self.force_stop.wait(time_wait if time_wait >= 0.0 else 0.0):
            try:
                time_read = time()
                if no_data_timeout and curr_time + no_data_timeout < get_float_time(
                ):
                    raise NoDataTimeout(
                        'Received no data for %0.1f second(s)' %
                        no_data_timeout)
                data = self.read_data()
            except Exception:
                no_data_timeout = None  # raise exception only once
                if self.errback:
                    self.errback(sys.exc_info())
                else:
                    raise
                if self.stop_readout.is_set():
                    break
            else:
                data_words = data.shape[0]
                if data_words > 0:
                    last_time, curr_time = self.update_timestamp()
                    status = 0
                    if self.callback:
                        self._data_deque.append(
                            (data, last_time, curr_time, status))
                    if self.fill_buffer:
                        self._data_buffer.append(
                            (data, last_time, curr_time, status))
                    self._words_per_read.append(data_words)
                elif self.stop_readout.is_set():
                    break
                else:
                    self._words_per_read.append(0)
            finally:
                time_wait = self.readout_interval - (time() - time_read)
            if self._calculate.is_set():
                self._calculate.clear()
                self._result.put(sum(self._words_per_read))
        if self.callback:
            self._data_deque.append(None)  # last item, will stop worker
        logging.debug('Stopped %s' % (self.readout_thread.name, ))
Ejemplo n.º 2
0
 def update_timestamp(self, fifo):
     curr_time = get_float_time()
     last_time = self.timestamp[fifo]
     if last_time is None:
         last_time = curr_time
     self.timestamp[fifo] = curr_time
     return last_time, curr_time
Ejemplo n.º 3
0
    def readout(self, fifo, no_data_timeout=None):
        '''Readout thread continuously reading FIFO.

        Readout thread, which uses read_raw_data_from_fifo() and appends data to self._fifo_data_deque (collection.deque).
        '''
        logging.info('Starting readout thread for %s', fifo)
        time_last_data = time()
        time_wait = 0.0
        empty_reads = 0
        while not self.force_stop[fifo].wait(
                time_wait if time_wait >= 0.0 else 0.0):
            time_read = time()
            try:
                if no_data_timeout and time_last_data + no_data_timeout < get_float_time(
                ):
                    raise NoDataTimeout(
                        'Received no data for %0.1f second(s) from %s' %
                        (no_data_timeout, fifo))
                raw_data = self.read_raw_data_from_fifo(fifo)
            except NoDataTimeout:
                no_data_timeout = None  # raise exception only once
                if self.errback:
                    self.errback(sys.exc_info())
                else:
                    raise
            except Exception:
                if self.errback:
                    self.errback(sys.exc_info())
                else:
                    raise
                if self.stop_readout.is_set(
                ):  # in case of a exception, break immediately
                    break
            else:
                n_data_words = raw_data.shape[0]
                if n_data_words > 0:
                    time_last_data = time()
                    empty_reads = 0
                    time_start_read, time_stop_read = self.update_timestamp(
                        fifo)
                    status = 0
                    self._fifo_data_deque[fifo].append(
                        (raw_data, time_start_read, time_stop_read, status))
                    with self._fifo_conditions[fifo]:
                        self._fifo_conditions[fifo].notify_all()
                elif self.stop_readout.is_set():
                    if empty_reads == self._n_empty_reads:
                        break
                    else:
                        empty_reads += 1
            finally:
                # ensure that the readout interval does not depend on the processing time of the data
                # and stays more or less constant over time
                time_wait = self.readout_interval - (time() - time_read)
        self._fifo_data_deque[fifo].append(
            None)  # last item, None will stop worker
        with self._fifo_conditions[fifo]:
            self._fifo_conditions[fifo].notify_all()
        logging.info('Stopping readout thread for %s', fifo)
Ejemplo n.º 4
0
    def readout(self, no_data_timeout=None):
        '''Readout thread continuously reading SRAM.

        Readout thread, which uses read_data() and appends data to self._data_deque (collection.deque).
        '''
        logging.debug('Starting %s', self.readout_thread.name)
        curr_time = get_float_time()
        time_wait = 0.0
        while not self.force_stop.wait(time_wait if time_wait >= 0.0 else 0.0):
            try:
                time_read = time()
                if no_data_timeout and curr_time + no_data_timeout < get_float_time():
                    raise NoDataTimeout('Received no data for %0.1f second(s)' % no_data_timeout)
                data = self.read_data()
            except Exception:
                no_data_timeout = None  # raise exception only once
                if self.errback:
                    self.errback(sys.exc_info())
                else:
                    raise
                if self.stop_readout.is_set():
                    break
            else:
                data_words = data.shape[0]
                if data_words > 0:
                    last_time, curr_time = self.update_timestamp()
                    status = 0
                    if self.callback:
                        self._data_deque.append((data, last_time, curr_time, status))
                    if self.fill_buffer:
                        self._data_buffer.append((data, last_time, curr_time, status))
                    self._words_per_read.append(data_words)
                elif self.stop_readout.is_set():
                    break
                else:
                    self._words_per_read.append(0)
            finally:
                time_wait = self.readout_interval - (time() - time_read)
            if self._calculate.is_set():
                self._calculate.clear()
                self._result.put(sum(self._words_per_read))
        if self.callback:
            self._data_deque.append(None)  # last item, will stop worker
        logging.debug('Stopped %s', self.readout_thread.name)
Ejemplo n.º 5
0
 def data_words_per_second(self):
     with self.data_words_per_second_lock:
         result = []
         curr_time = get_float_time()
         for words_per_read in self._words_per_read:
             result.append(
                 sum([
                     item[0] for item in words_per_read if item[1] >
                     (curr_time - self._moving_average_time_period)
                 ]) / float(self._moving_average_time_period))
         return result
Ejemplo n.º 6
0
 def update_timestamp(self):
     curr_time = get_float_time()
     last_time = self.timestamp
     self.timestamp = curr_time
     return last_time, curr_time
Ejemplo n.º 7
0
    def start(self,
              fifos,
              callback=None,
              errback=None,
              reset_rx=False,
              reset_fifo=False,
              fill_buffer=False,
              no_data_timeout=None,
              filter_func=None,
              converter_func=None,
              fifo_select=None,
              enabled_fe_channels=None):
        with self.is_running_lock:
            if self._is_running:
                raise RuntimeError(
                    'FIFO readout threads already started: use stop()')
            self._is_running = True

            if isinstance(fifos, basestring):
                fifos = [fifos]
            if len(fifos) == 0:
                raise ValueError('"fifos" parameter is empty.')
            if len(set(fifos)) != len(fifos):
                raise ValueError(
                    'The following strings are occurring multiple times in "fifos": %s'
                    % set([fifo for fifo in fifos if fifos.count(fifo) > 1]))
            if isinstance(fifo_select,
                          Iterable) and set(fifo_select) - set(fifos):
                raise ValueError(
                    "The following FIFOs have filters/converters set but are not read out: %s"
                    % (set(fifo_select) - set(fifos)))
            if isinstance(filter_func, Iterable) or isinstance(
                    converter_func,
                    Iterable) or (isinstance(fifo_select, Iterable)
                                  and not isinstance(fifo_select, basestring)):
                if not isinstance(filter_func, Iterable):
                    raise ValueError('"filter_func" is not iterable.')
                if not isinstance(converter_func, Iterable):
                    raise ValueError('"converter_func" is not iterable.')
                if not isinstance(fifo_select, Iterable):
                    raise ValueError('"fifo_select" is not iterable.')
                if len(filter_func) != len(converter_func):
                    raise ValueError(
                        'Length of "filter_func" and "converter_func" not equal.'
                    )
                if len(filter_func) != len(fifo_select):
                    raise ValueError(
                        'Length of "filter_func" and "fifo_select" not equal.')
                if len(converter_func) != len(fifo_select):
                    raise ValueError(
                        'Length of "converter_func" and "fifo_select" not equal.'
                    )
            else:
                if isinstance(fifo_select, basestring):
                    # convert to iterable
                    filter_func = [filter_func]
                    converter_func = [converter_func]
                    fifo_select = [fifo_select]
                else:
                    # if fifo_select is None:
                    # adding filters and converters for each FIFO
                    filter_func = [filter_func] * len(fifos)
                    converter_func = [converter_func] * len(fifos)
                    fifo_select = fifos
            if not (set(fifos) & set(fifo_select)) == set(fifo_select):
                raise ValueError(
                    '"fifo_select" contains non-existing FIFOs: %s' %
                    (set(fifo_select) & set(fifos)))

            if enabled_fe_channels is None:
                self.enabled_fe_channels = [
                    rx.name for rx in self.dut.get_modules('fei4_rx')
                ]
            else:
                self.enabled_fe_channels = enabled_fe_channels
            self.fifos = fifos
            self.callback = callback
            self.errback = errback
            self.fill_buffer = fill_buffer
            self.filter_func = filter_func
            self.converter_func = converter_func
            self.fifo_select = fifo_select

            self._fifo_data_deque = {fifo: deque() for fifo in self.fifos}
            self._fifo_conditions = {fifo: Condition() for fifo in self.fifos}
            self._data_deque = [deque() for _ in self.filter_func]
            self._data_conditions = [Condition() for _ in self.filter_func]
            self._data_buffer = [deque() for _ in self.filter_func]
            self.force_stop = {fifo: Event() for fifo in self.fifos}
            self.timestamp = {fifo: None for fifo in self.fifos}
            len_deque = int(self._moving_average_time_period /
                            self.readout_interval)
            curr_time = get_float_time()
            self._words_per_read = [
                deque(iterable=[(0, curr_time, curr_time)] * len_deque,
                      maxlen=len_deque) for _ in self.filter_func
            ]
            if reset_rx:
                self.reset_rx(fe_channels=self.enabled_fe_channels)
            for fifo in self.fifos:
                if reset_fifo:
                    self.reset_fifo([fifo])
                self.update_timestamp(fifo)
                fifo_size = self.get_fifo_size(fifo)
                if fifo_size != 0:
                    logging.warning('%s contains data: FIFO_SIZE = %i', fifo,
                                    fifo_size)
            self.stop_readout.clear()
            for event in self.force_stop.values():
                event.clear()
            logging.info('Starting FIFO readout...')
            if self.errback:
                self.watchdog_thread = Thread(target=self.watchdog,
                                              name='WatchdogThread')
                self.watchdog_thread.daemon = True
                self.watchdog_thread.start()
            self.readout_threads = []
            self.worker_threads = []
            self.writer_threads = []
            for fifo in self.fifos:
                readout_thread = Thread(target=self.readout,
                                        name='ReadoutThread %s' % fifo,
                                        kwargs={
                                            'fifo': fifo,
                                            'no_data_timeout': no_data_timeout
                                        })
                worker_thread = Thread(target=self.worker,
                                       name='WorkerThread %s' % fifo,
                                       kwargs={'fifo': fifo})
                readout_thread.daemon = True
                worker_thread.daemon = True
                self.readout_threads.append(readout_thread)
                self.worker_threads.append(worker_thread)
            for index, _ in enumerate(self.filter_func):
                writer_thread = Thread(target=self.writer,
                                       name='WriterThread %d' % index,
                                       kwargs={
                                           'index': index,
                                           'no_data_timeout': no_data_timeout
                                       })
                writer_thread.daemon = True
                self.writer_threads.append(writer_thread)
            for writer_thread in self.writer_threads:
                writer_thread.start()
            for worker_thread in self.worker_threads:
                worker_thread.start()
            for readout_thread in self.readout_threads:
                self.update_timestamp(fifo)
                readout_thread.start()
            # enabling RX channels
            for fifo in self.fifos:
                self.update_timestamp(fifo)
            for fei4_rx_name in self.enabled_fe_channels:
                self.dut[fei4_rx_name].ENABLE_RX = 1