Exemple #1
0
    def tune_sync_delay(self,
                        search_seed: TInt32 = 15) -> TTuple([TInt32, TInt32]):
        """Find a stable SYNC_IN delay.

        This method first locates a valid SYNC_IN delay at zero validation
        window size (setup/hold margin) by scanning around `search_seed`. It
        then looks for similar valid delays at successively larger validation
        window sizes until none can be found. It then decreases the validation
        window a bit to provide some slack and stability and returns the
        optimal values.

        This method and :meth:`tune_io_update_delay` can be run in any order.

        :param search_seed: Start value for valid SYNC_IN delay search.
            Defaults to 15 (half range).
        :return: Tuple of optimal delay and window size.
        """
        if not self.cpld.sync_div:
            raise ValueError("parent cpld does not drive SYNC")
        search_span = 31
        # FIXME https://github.com/sinara-hw/Urukul/issues/16
        # should both be 2-4 once kasli sync_in jitter is identified
        min_window = 0
        margin = 1  # 1*75ps setup and hold
        for window in range(16):
            next_seed = -1
            for in_delay in range(search_span - 2 * window):
                # alternate search direction around search_seed
                if in_delay & 1:
                    in_delay = -in_delay
                in_delay = search_seed + (in_delay >> 1)
                if in_delay < 0 or in_delay > 31:
                    continue
                self.set_sync(in_delay, window)
                self.clear_smp_err()
                # integrate SMP_ERR statistics for a few hundred cycles
                delay(100 * us)
                err = urukul_sta_smp_err(self.cpld.sta_read())
                delay(100 * us)  # slack
                if not (err >> (self.chip_select - 4)) & 1:
                    next_seed = in_delay
                    break
            if next_seed >= 0:  # valid delay found, scan next window
                search_seed = next_seed
                continue
            elif window > min_window:
                # no valid delay found here, roll back and add margin
                window = max(min_window, window - 1 - margin)
                self.set_sync(search_seed, window)
                self.clear_smp_err()
                delay(100 * us)  # slack
                return search_seed, window
            else:
                break
        raise ValueError("no valid window/delay")
Exemple #2
0
    def get(self) -> TTuple([TFloat, TFloat]):
        """Get the frequency and phase.

        .. seealso:: :meth:`get_mu`

        :return: A tuple ``(frequency, phase)``.
        """

        # Get values
        ftw, pow_ = self.get_mu()
        # Convert and return
        return self.ftw_to_frequency(ftw), self.pow_to_turns(pow_)
Exemple #3
0
    def get(self, profile: TInt32 = 0) -> TTuple([TFloat, TFloat, TFloat]):
        """Get the frequency, phase, and amplitude.

        .. seealso:: :meth:`get_mu`

        :param profile: Profile number to get (0-7, default: 0)
        :return: A tuple ``(frequency, phase, amplitude)``
        """

        # Get values
        ftw, pow_, asf = self.get_mu(profile)
        # Convert and return
        return (self.ftw_to_frequency(ftw), self.pow_to_turns(pow_),
                self.asf_to_amplitude(asf))
Exemple #4
0
    def get_mu(self) -> TTuple([TInt64, TInt32]):
        """Get the frequency tuning word and phase offset word.

        .. seealso:: :meth:`get`

        :return: A tuple ``(ftw, pow)``.
        """

        # Read data
        high = self.read(AD9912_POW1, 4)
        self.core.break_realtime()  # Regain slack to perform second read
        low = self.read(AD9912_FTW3, 4)
        # Extract and return fields
        ftw = (int64(high & 0xffff) << 32) | (int64(low) & int64(0xffffffff))
        pow_ = (high >> 16) & 0x3fff
        return ftw, pow_
Exemple #5
0
    def get_mu(self, profile: TInt32 = 0) -> TTuple([TInt32, TInt32, TInt32]):
        """Get the frequency tuning word, phase offset word,
        and amplitude scale factor.

        .. seealso:: :meth:`get`

        :param profile: Profile number to get (0-7, default: 0)
        :return: A tuple ``(ftw, pow, asf)``
        """

        # Read data
        data = int64(self.read64(_AD9910_REG_PROFILE0 + profile))
        # Extract and return fields
        ftw = int32(data)
        pow_ = int32((data >> 32) & 0xffff)
        asf = int32((data >> 48) & 0x3fff)
        return ftw, pow_, asf
Exemple #6
0
def dma_retrieve(name: TStr) -> TTuple([TInt64, TInt32]):
    raise NotImplementedError("syscall not simulated")
Exemple #7
0
def drtio_get_packet_counts(linkno: TInt32) -> TTuple([TInt32, TInt32]):
    raise NotImplementedError("syscall not simulated")
Exemple #8
0
def drtio_get_channel_state(channel: TInt32) -> TTuple([TInt32, TInt64]):
    raise NotImplementedError("syscall not simulated")
Exemple #9
0
def rtio_input_timestamped_data(timeout_mu: TInt64,
                                channel: TInt32) -> TTuple([TInt64, TInt32]):
    """Wait for an input event up to timeout_mu on the given channel, and
    return a tuple of timestamp and attached data, or (-1, 0) if the timeout is
    reached."""
    raise NotImplementedError("syscall not simulated")