m-labs / artiq

A leading-edge control system for quantum information experiments
https://m-labs.hk/artiq
GNU Lesser General Public License v3.0
434 stars 201 forks source link

sawg: clipping on phase jumps at large amplitudes #743

Closed jbqubit closed 7 years ago

jbqubit commented 7 years ago

Testing SAWG absolute/relative phase modes. I see undesired oscillation.

test 0

$ cat test_ap2.py
from artiq.experiment import *

class SAWGTest(EnvExperiment):
    def build(self):
        self.setattr_device("core")
        self.setattr_device("led")
        self.setattr_device("ttl_sma")

        self.setattr_device("sawg0")
        self.setattr_device("sawg1")

    @kernel
    def run(self):
        self.core.reset()
        self.ttl_sma.output()
        delay(1*ms)

        while True:
            self.ttl_sma.pulse(3 * us)
            self.ap1()
            delay(1*ms)

    @kernel
    def ap1(self):
        # test: t1
        f0 = 5*MHz
        t = 1*us
        a0 = 0.99

        # prepare
        self.sawg0.frequency0.set(0*MHz)
        self.sawg0.frequency1.set(f0)
        self.sawg0.frequency2.set(0*MHz)
        self.sawg0.amplitude1.set(a0)
        self.sawg0.config.set_clr(1, 1, 1)
        self.sawg0.phase1.set(0.)
        self.sawg1.frequency0.set(0*MHz)
        self.sawg1.frequency1.set(f0)
        self.sawg1.frequency2.set(0*MHz)
        self.sawg1.amplitude1.set(a0)
        self.sawg0.config.set_clr(1, 1, 1)
        self.sawg1.phase1.set(0.)

        delay(t)
        self.sawg1.phase1.set(0.5)
        delay(t)

        # switch RF off
        self.sawg0.amplitude1.set(0.)
        self.sawg1.amplitude1.set(0.)

Here's what I see with scope triggered on ttl_sma.

ds1z_quickprint6

Is this an implication of FIR filters?

jordens commented 7 years ago

Most likely a balun/cable/termination/filter/scope effect. Try smaller amplitude, longer/shorter cable, termination at scope, probe actual DAC output etc. c.f. #742

jbqubit commented 7 years ago

Switched to using 1 GS/s old school LeCroy 9354AM.

test 1

Still looking at SMA output of the prototype board. I observe strong nonlinear behavior for small changes in waveform parameters. Same program as above but with the following changes.

        f0 = 1*MHz
        t = 1*us
        a0 = 0.98

Compare scope traces for two phase jumps. This is too nonlinear to be balun/cable/termination/filter/scope.

self.sawg1.phase1.set(0.12)
self.sawg1.phase1.set(0.13)

file_000

file_001

test 2

Vary the phase in a loop.

        while True:
            for ph in range(0, 100):
                for i in range(0, 100):
                    self.ap(ph/100.0)
                    self.ttl_sma.pulse(3 * us)
                    delay(1 * ms)

clip: https://drive.google.com/file/d/0B5PIArGKtLa-TnZRa1J0S0UwSzQ/view?usp=sharing

test 3

The sharp nonlinearity persists for some phases while phase looping when amplitude is 0.8 but is gone altogether when amplitude is 0.78.

jordens commented 7 years ago

Ok. Looks like the HBF is clipping. Does it also do that if you jump the phase of the DUC (phase0)?

jbqubit commented 7 years ago

Here's my test code for sweeping phase0.

$ cat test_ap4.py
from artiq.experiment import *

class SAWGTest(EnvExperiment):
    def build(self):
        self.setattr_device("core")
        self.setattr_device("led")
        self.setattr_device("ttl_sma")

        self.setattr_device("sawg0")
        self.setattr_device("sawg1")

    @kernel
    def run(self):
        self.core.reset()
        self.ttl_sma.output()
        delay(3*ms)

        while True:
            for ph in range(0, 100):
                for i in range(0, 100):
                    self.ap(ph/100.0)
                    self.ttl_sma.pulse(3 * us)
                    delay(1 * ms)

    @kernel
    def ap(self, ph):
        # test: t1
        f0 = 1*MHz
        t = 1*us
        a0 = 0.99

        # prepare reference signal
        self.sawg0.frequency0.set(0*MHz)
        self.sawg0.frequency1.set(f0)
        self.sawg0.frequency2.set(0*MHz)
        self.sawg0.amplitude1.set(a0)
        self.sawg0.config.set_clr(1, 1, 1)
        self.sawg0.phase1.set(0.)

        # prepare signal
        self.sawg1.frequency0.set(f0)
        self.sawg1.frequency1.set(0*MHz)
        self.sawg1.frequency2.set(0*MHz)
        self.sawg1.amplitude1.set(a0)
        self.sawg1.config.set_clr(1, 1, 1)
        self.sawg1.phase1.set(0.)
        self.sawg1.phase0.set(0.)

        delay(t)
        self.sawg1.phase0.set(ph)
        delay(t)

        # switch RF off
        self.sawg0.amplitude1.set(0.)
        self.sawg1.amplitude1.set(0.)

I do not see the sharp non-linearity observed for phase1.

jbqubit commented 7 years ago

@jordens Do you have enough information to address this Issue?

jordens commented 7 years ago

Yes.

jordens commented 7 years ago

TL;DR: The FIR interpolator before the DUC overshoots. That is correct behavior. I moved things around a little and added some headroom. You shouldn't see this again unless you intentionally provoke it by maxing out both DDS per channel and then do phase/amplitude jumps on top of that. But it should be obvious that that is unwise for several other reasons.

jbqubit commented 7 years ago

Flashed using latest build bot build... flashing artiq-kc705-phaser... but can't ping. https://gist.github.com/jbqubit/95840c0bf6ea65e5a244faa9068f99da

Discussion taking place on IRC. https://irclog.whitequark.org/m-labs

jbqubit commented 7 years ago

Please reopen and I'll test.

jordens commented 7 years ago

File a new issue if you still see a problem. This one is closed.

jbqubit commented 7 years ago

Please re-open this Issue as I haven't tested it. Patch 9a8a7b9 didn't even build successfully until today.

screenshot from 2017-06-15 15 41 11

And simpler things with swag are not working... #751.

jbqubit commented 7 years ago

Confirmed that this is resolved. Here's the updated test code.

$ artiq_corelog
[           7us]  INFO(runtime): ARTIQ runtime starting...
[        3853us]  INFO(runtime): software version 3.0.dev+1207.g5b26e5de
[       10201us]  INFO(runtime): gateware version 3.0.dev+1207.g5b26e5de
$ cat test_ap3.py

from artiq.experiment import *

class SAWGTest(EnvExperiment):
    """
    sawg0 is a reference channel
    sawg1 has its phase swept in a loop
    """
    def build(self):
        self.setattr_device("core")
        self.setattr_device("led")
        self.setattr_device("ttl_sma")

        self.setattr_device("sawg0")
        self.setattr_device("sawg1")

    @kernel
    def run(self):
        self.core.reset()
        delay(300 * us)
        self.sawg0.reset()
        self.sawg1.reset()
        self.ttl_sma.output()
        delay(300 * us)

        for ph in range(0, 300):
            for i in range(0, 100):
                self.test(ph/100.0)
                self.ttl_sma.pulse(3 * us)
                delay(1 * ms)

    @kernel
    def test(self, ph):
        # test: t1
        f0 = 10*MHz
        t = 500*ns
        a0 = 1.

        # prepare
        self.sawg0.frequency1.set(f0)
        self.sawg0.amplitude1.set(a0)
        self.sawg1.frequency1.set(f0)
        self.sawg1.amplitude1.set(a0)

        delay(t)
        self.sawg1.phase1.set(ph)
        delay(t)

        # switch RF off
        self.sawg0.amplitude1.set(0.)
        self.sawg1.amplitude1.set(0.)