artiq
artiq copied to clipboard
Phaser: Document oscillator pipelining and measure differential parameter latency
Bug Report
One-Line Summary
The Kasli-Oscillator output is not deterministic when using update intervals that are an odd multiple of the 25 MS/s update rate.
Issue Details
When pulsing the Kasli-NCOs with update intervals of odd multiples of the 25 MS/s sample rate, the phaser output is non-deterministic between timeline jumps. This implies such pulses are not reproducible between experiments. Attempting to produce a 1 us pulse (the 25 times the sample interval) stochastically produces the two waveforms in the table below. Changing the pulse duration to 24 or 26 times the sample interval deterministically produces a single waveform.
~10% probability | ~90% probability |
---|---|
![]() |
![]() |
Steps to Reproduce
The following code produces both waveforms:
from artiq.experiment import *
class OscillatorDeterminism(EnvExperiment):
def build(self):
self.setattr_device("core")
self.setattr_device("phaser")
@kernel
def run(self):
ch0 = self.phaser.channel[0]
ch1 = self.phaser.channel[1]
self.core.wait_until_mu(now_mu())
self.core.break_realtime()
self.phaser.init(debug=False)
delay(1*ms)
ch1.set_att(0*dB)
delay(1*ms)
# reqired to avoid transient due to #1651
self.phaser.set_cfg(clk_sel=self.phaser.clk_sel, dac_txena=0)
delay(1*ms)
# settle zero amplitude
ch1.oscillator[0].set_amplitude_phase(amplitude=0., phase=0., clr=1)
delay(1*ms)
self.phaser.set_cfg(clk_sel=self.phaser.clk_sel, dac_txena=1)
delay(1*ms)
ch1.set_duc_frequency(0*MHz)
delay(1*ms)
ch1.set_duc_phase(.0)
delay(1*ms)
ch1.set_duc_cfg(clr=1)
delay(.1*ms)
self.phaser.duc_stb()
delay(1*ms)
for _ in range(100):
ch1.oscillator[0].set_frequency(7 * MHz)
delay(us/25 * 2)
ch1.oscillator[0].set_amplitude_phase(amplitude=0., phase=0., clr=1)
delay(us/25 * 2)
ch1.oscillator[0].set_amplitude_phase(amplitude=.8)
delay(us/25 * 25)
ch1.oscillator[0].set_amplitude_phase(amplitude=.0, clr=1)
self.core.wait_until_mu(now_mu())
print("make jitter")
self.core.break_realtime()
Expected Behavior
This behaviour should be documented. Currently, the documentation only points out that the Kasli-NCO is updates at 25 MS/s and that delays are deterministic. This suggests that behaviour would be deterministic when the Kasli-NCO settings are updated at 1/25 us intervals.
Actual (undesired) Behavior
- The behaviour is only deterministic when using update invervals that are an even multiple of the samle interval
Your System (omit irrelevant parts)
- ARTIQ version: latest master
- Phaser gateware: latest release (v0.5)
- Hardware involved: Kasli v1.1, Phaser v1.0 (baseband)
As it turns out this is not related to even multiples. Using 20/25 us or 30/25 us intervals is also non-deterministic.
Yes. The latency of parameter updates is deterministic, but not matched. In fact, it was explicitly agreed that latencies between parameter updates would not be matched, as clearly state in the docs. Obviously any update would have a sample interval granularity but you are updating two parameters (amplitude
and clr
). The data processing is pipelined and depending on the timing, parameter updates affect different samples. I haven't constructed the exact case you are seeing but, as pointed out already and clear from a fundamental understanding of sampling, you need to align your updates if you don't want to see that effect. If you want to align updates, you need to figure out the differential latency and ensure that the sampling interval falls deterministically.
The ratio of 1:9 is not immediately obvious to me, sure it's not 2:8? Also please do double check that this isn't some floating point issue in delay()
: replace the critical ones by integer delay_mu()
.
Again, I would recommend you stop trying to ram your analysis home and instead try to accurately describe the facts first. It'll save you time.
any update would have a sample interval granularity but you are updating two parameters (
amplitude
andclr
)
Thankyou for the insight. Do I understand you correctly that set_amplitude_phase
is not an atomic operation?
you need to align your updates
Indeed, one needs to align the updates with the NCO update cycle. That is why all updates are written at a multiple of the update interval. This issue only uses a single kasli-NCO, unless set_amplitude_phase
is not atomic, I would expect the output pulse to be identical.
sure it's not 2:8?
The statistics might well be 2:8. 1:9 was an estimate.
Also please do double check that this isn't some floating point issue in
delay()
: replace the critical ones by integerdelay_mu()
.
using delay_mu
with the appropriate integers still gives non-deterministic output.
Thankyou for the insight. Do I understand you correctly that set_amplitude_phase is not an atomic operation?
Depends a bit on your definition of atomic. The following is true: set_amplitude_phase()
can in principle affect the sample stream at three different instants. From a cursory reading, I think clr
and frequency
are the same latency, but amplitude
should be 6 cycles later, i.e. for n=5
either 1 or 2 samples depending on alignment. And phase
is one cycle after frequency
.
Indeed, one needs to align the updates with the NCO update cycle. That is why all updates are written at a multiple of the update interval.
Not frequency alignment but also (and specifically here) phase alignment.
It may be true that the sample-to-RTIO-counter alignment is in fact deterministic, but I haven't checked. Then ensuring that the relevant part of your timeline is aligned to the 5 RTIO-cycle beats would be sufficient and you would not need the frame alignment measurement.