I'm using a Sinara crate with three Urukuls conencted to Kasli with two EEM channels (the "normal" way, i assume), and one fourth Urukul card only connected via a single EEM channel.

What's the correct way to use the DDS channels of all four cards (that is the twelve "fast channels" from the first three cards, and the four "slow channels" from the fourth card)?

The following code doesn't work:

    @kernel
    def run(self):
        self.krn_init_hardware()
        self.core.break_realtime()
        self.krn_dds()  # <- (1)
        self.krn_dds_slow()  # <- (2)

    @kernel
    def krn_init_hardware(self):
        self.core.reset()
        self.core.break_realtime()
        for cpld in self.dds_cpld_devs:
            cpld.init()
        self.core.break_realtime()
        for dds in self.dds_devs:
            dds.init()
        self.core.break_realtime()
        for slow_dds in self.dds_slow_devs:  # <- (3)
            slow_dds.init() # <- (3)

    @kernel
    def krn_dds(self):
        self.core.break_realtime()
        FREQUENCY_MHZ = 150
        PHASE = 0.0
        AMPLITUDE = 1.0
        delay(1 * ms)
        self.dds_devs[4].set(FREQUENCY_MHZ * MHz, phase=PHASE, amplitude=AMPLITUDE)
        delay(1 * ms)
        self.dds_devs[4].sw.on()
        delay(1 * s)
        self.dds_devs[4].sw.off()
        
    @kernel
    def krn_dds_slow(self):
        self.core.break_realtime()
        FREQUENCY_MHZ = 150
        PHASE = 0.0
        AMPLITUDE = 1.0
        delay(1 * ms)
        self.dds_slow_devs[0].set(FREQUENCY_MHZ * MHz, phase=PHASE, amplitude=AMPLITUDE)
        delay(1 * ms)
        self.dds_slow_devs[0].cfg_sw(True)
        delay(1 * s)
        self.dds_slow_devs[0].cfg_sw(False)

(dds_devs[] and dds_slow_devs[] are initialized elsewhere and contain the the respective devices.)
The code doesn't create the intended pulses, and returns the following error:

<synthesized>:1:2-1:61: error: host object does not have an attribute 'sw'
[<artiq.coredevice.ad9910.AD9910 object at 0x7fb2377e7fd0>, <artiq.coredevice.ad9910.AD9910 object at 0x7fb2377ec090>, <artiq.coredevice.ad9910.AD9910 object at 0x7fb2377ec150>, <artiq.coredevice.ad9910.AD9910 object at 0x7fb2377ec1d0>]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
/home/<...>/artiq/sinara_sequencer_slow_dds.py:61:1: note: expanded from here
def run(self):
^
/home/<...>/artiq/sinara_sequencer_slow_dds.py:103:9-103:28: note: attribute accessed here
self.dds_devs[4].sw.on()
^^^^^^^^^^^^^^^^^^^

If I take out the code on the locations (2) and (3), it executes correctly (no error, first pulse created).

If I leave (2) and (3) in, and remove (1), it seems to execute correctly as well (second pulse created), but the following warning is produced:

<synthesized>:1:2-1:61: warning: object <artiq.coredevice.ad9910.AD9910 object at 0x7fc32f192f90> of type <instance artiq.coredevice.ad9910.AD9910> declares attribute 'sw' as kernel invariant, but the instance referenced here does not have this attribute
[<artiq.coredevice.ad9910.AD9910 object at 0x7fc32f192f90>, <artiq.coredevice.ad9910.AD9910 object at 0x7fc32f192fd0>, <artiq.coredevice.ad9910.AD9910 object at 0x7fc32f197110>, <artiq.coredevice.ad9910.AD9910 object at 0x7fc32f197190>]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
/home/<...>artiq/sinara_sequencer_slow_dds.py:61:1: note: expanded from here
def run(self):
^

...
That are the addresses of the four "slow devices" (The DDS channels of the Urukul connected via only one EEM port).
The warning is repeated for all four devices.

To sum up:
I can use the "slow channel", but not the fast ones. And there is a warning I don't understand.
Or I can use the fast channels, but not the slow ones.

Clearly, I'm doing something wrong here, and I'd be grateful for any tips, what.

Best regards,
Max

PS: I'm using artiq 5 on the host PC and Kasli, and execute the
code using artiq_run in a nix environment on an Ubuntu system this time.

5 days later

I think you are hitting https://github.com/m-labs/artiq/issues/1207
I am unsure what the best or even realistic way around this is.
Maybe a pragmatic way would be to instantiate the sw as a TTLOut even for the single-EEM Urukuls but make it so that it has an invalid RTIO channel and thus doesn't emit any events.

Ok, I see.
I wasn't aware of this issue, when I chose the components of my Sinara crate.
Concerning your proposed workaround:
I tried now the following changes in my device_db:
I added a dummy sw for my Urukul3:

device_db["ttl_urukul3_sw_dummy"] = {
    "type": "local",
    "module": "artiq.coredevice.ttl",
    "class": "TTLOut",
    "arguments": {"channel": 0x00003f}
}

Then, I added the following line in all four channels of Urukul3:

 "sw_device": "ttl_urukul3_sw_dummy",

This seems to work nicely so far (more thorough tests still outstanding).
So, thanks a lot for the tip!

I need to make sure though probably, that channel 0x00003f is really not used for anything else.
It's not used in my device_db.

Is it possible, that this channel is still used for something else?
If so, how can I find out?

These cases should certainly be documented. Documentation is currently only at the level that people are willing to pay for.
All used RTIO channels appear in the device-db templates. AFAIR 0x00ffff would typically be unused (high byte is DRTIO destination prefix, lower two bytes are destination-level RTIO channel).

  • max replied to this.

    rjo These cases should certainly be documented. Documentation is currently only at the level that people are willing to pay for.
    All used RTIO channels appear in the device-db templates. AFAIR 0x00ffff would typically be unused (high byte is DRTIO destination prefix, lower two bytes are destination-level RTIO channel).

    Yes, I understand your issues of acquiring resources for extended documentation.

    If I can somehow help by e.g. making this issue and its workaround more widely known (e.g. posting it somewhere else, adding it to some "known issues" list, etc.), let me know, I'm happy to do so.