Hi, I am trying to provide the clock of the Kasli a 10 MHz clock sourced from GPS and verify that it is working correctly by outputting a frequency from a Urukul at 250 kHz. The Kasli is wired to share a clock internally I believe with the Urukul.

To provide the GPS signal we use a SRS-FS740 https://www.thinksrs.com/products/fs740.html which contains a frequency counter.

The 10MHz frequency from the FS740 goes into the clock of the Kasli. I run the command artiq_coremgmt config read rtio_clock and it outputs int_125. I then run (base) grpartiq@hrlit3085:~/ARTIQ/afws_directory/Experiments$ artiq_coremgmt config write -s rtio_clock ext0_synth0_10to125
(base) grpartiq@hrlit3085:~/ARTIQ/afws_directory/Experiments$ artiq_coremgmt config read rtio_clock
ext0_synth0_10to125

The code to generate the 250kHz signal is

` from artiq.experiment import *


 ALM_FREQ0 = ((9.192631770)/2-.3)*1e9

 class CPT_Reference_Experiment(EnvExperiment):

def build(self):

    self.setattr_device("core")
    self.mirny = self.get_device("mirny0_cpld")
    self.setattr_device("mirny0_ch0")
    self.almazny = self.get_device("mirny0_almazny0")
    self.setattr_device("urukul0_ch0")
    self.setattr_device("urukul0_ch1")
    self.setattr_device("urukul0_ch3")

@kernel
def run(self):

    # Begin a new data collection period
    self.core.reset
    self.core.break_realtime()

    # Initialize Mirny       
    self.mirny.init()                               
    self.mirny0_ch0.init()
    # self.almazny.init()
    self.urukul0_ch0.cpld.init()
    self.urukul0_ch0.init()
    
    self.urukul0_ch1.cpld.init()
    self.urukul0_ch1.init()
    
    self.urukul0_ch3.cpld.init()
    self.urukul0_ch3.init()
    delay(100*us)

    ### DEFINE URUKUL PARAMETERS ###
    # 1MHz -to- 400MHz frequency range
    URU_FREQ0 = 80*MHz
    URU_AMP0 = 1.0
    # Attenuation must be a Float
    attenuation = 0.0

### DEFINE URUKUL PARAMETERS ###
    # 1MHz -to- 400MHz frequency range
    URU_FREQ1 = 250*kHz
    URU_AMP1 = 1.0
    # Attenuation must be a Float
    attenuation1 = 0.0

    # 1MHz -to- 400MHz frequency range
    URU_FREQ2 = 300*MHz
    URU_AMP2 = 1.0
    # Attenuation must be a Float
    attenuation2 = 5.0


    self.urukul0_ch0.set_att(attenuation)
    self.urukul0_ch0.sw.on()
    
    self.urukul0_ch1.set_att(attenuation1)
    self.urukul0_ch1.sw.on()
    
    self.urukul0_ch3.set_att(attenuation2)
    self.urukul0_ch3.sw.on()


    self.urukul0_ch0.set(URU_FREQ0, amplitude = URU_AMP0)
    self.urukul0_ch1.set(URU_FREQ1, amplitude = URU_AMP1)
    self.urukul0_ch3.set(URU_FREQ2, amplitude = URU_AMP2)
    
    # 0xF is the decimal 15, binary 0b1111. This sets the four lowest bits as "1", which enables all four LEDs to ON.
    self.mirny.write_reg(2, 0xf)
    #  set_att function does not seem to work as of 2/26/2025 on artiq-8.0
        # Must use set_att_mu
        # Can be a value between 0-255 inclusive. 255 is 0dBm (minimum) attenuation. 0 is 31.5dBm (maximum) attenuatiuon.
    self.mirny0_ch0.set_output_power_mu(3)
    self.mirny0_ch0.set_att_mu(0)
    self.mirny0_ch0.set_frequency(ALM_FREQ0)
    # self.mirny0_almazny0.set_output_power_mu(3)
    # self.mirny0_almazny0.set_att_mu(255)
    self.almazny.set(ALM_FREQ0, True, True)
    delay(100*us)
    print("Done")

    print("output power is")
    print(self.mirny0_ch0.output_power_mu())
    # # Can't use f-strings??
    # print(f"The frequency on Channel 0 is {frequency}MHz.")` 

This indicates that the code has run and the clock has changed. I then output a 250kHz signal from the Urukul and to the FS740 where I count the frequency. The FS470 then indicates the Urukul is outputting 250000.041868. This means that the clock/PLL on the Kasli-Urukul is offset at the 40mHz level. The stability of this frequency changes at the .1mHz level indicating the PLL is also unstable. If I do the same thing with a Zurich UHF lockin instead of the Kasli-Urukul I get exactly 250kHz an instability at the 10s of uHz level or better. So the PLL in the Zurich appears 1000x better than in the Kasli.

What can be done to tweak/adjust or verify that the PLL is behaving properly?

I suppose you are using the default Si5324-based PLL, which is not designed for low noise, so these results are not surprising. You can:

  • switch to WRPLL (Si549-based, needs ARTIQ-8 or above)
  • optimize WRPLL's DSP loop filter by editing the Rust firmware
  • bypass the Kasli PLL and possibly the Urukul AD9910 PLL and generate suitable clocks externally, potentially distributing them with the 7210 Clocker module.

See my reply here as well: https://github.com/sinara-hw/Kasli/issues/111 (Urukul FTW precision)

Also be sure to restart the Kasli after changing clock sources; they are not switched at runtime.

The Si5324 isn't ultra-low noise, yes, but it's still a fairly low-noise clock in the grand scheme of things. The sensitivity of different applications to any given band of phase noise of course greatly varies, but just to give some indication, it's good enough for minute-long coherence times and 10^-7 -level single-qubit gates here (at baseband, but still).

    7 days later

    dpn

    Hi,

    Thanks for the heads up. I'll try to get an ADEV posted later this week. The 40mHz offset makes sense but I am more worried about the instability of the frequency. I also just ordered the 4412.

    I'm using the ARTIQ on a clock application for which the instability may matter quite a bit. I'll post an ADEV soon. I did off the bat notice that the SMA connector is sensitive to vibration/my hand touching it and noticably changes the ADEV on the frequency counter.