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")
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_)
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))
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_
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
def dma_retrieve(name: TStr) -> TTuple([TInt64, TInt32]): raise NotImplementedError("syscall not simulated")
def drtio_get_packet_counts(linkno: TInt32) -> TTuple([TInt32, TInt32]): raise NotImplementedError("syscall not simulated")
def drtio_get_channel_state(channel: TInt32) -> TTuple([TInt32, TInt64]): raise NotImplementedError("syscall not simulated")
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")