Open linuswck opened 1 year ago
The lack of RTIO output & proper input handling can be reproduced using a standalone variant.
from artiq.experiment import *
class Blinky(EnvExperiment):
def build(self):
self.setattr_device("core")
self.led0 = self.get_device("led0")
self.led1 = self.get_device("led1")
self.ttlin = self.get_device("ttl0")
self.setattr_device("core_dma")
self.setattr_argument("led0_state", NumberValue(ndecimals=0, step=1))
@kernel
def record(self):
with self.core_dma.record("blink"):
self.led1.pulse(1*s)
delay(1*s)
@kernel
def run(self):
self.core.reset()
self.led0.set_o(bool(self.led0_state))
if self.led0_state:
print(self.ttlin.sample_get())
self.core.break_realtime()
self.led1.off()
self.record()
blink_handle = self.core_dma.get_handle("blink")
self.core.break_realtime()
while True:
self.core_dma.playback_handle(blink_handle)
led0_state=0
. LED0 should be off while LED1 blinks.led0_state=1
.
I think it is most likely a CRI routing issue.
When DMA starts playback, the CRI listens to the DMA instead of the kernel, until the playback is completed. https://github.com/m-labs/artiq/blob/36b3678853e2a5667d1a458b11f5f176be39d933/artiq/firmware/ksupport/lib.rs#L408-L415
Given we are performing playback using an infinite loop, terminating the kernel via CTRL-C is very likely to not execute L415 in time, which leaves the CRI routing RTIO instructions from the DMA.
Adding L415 before executing the new kernel fixes the issue in my example (it does not use DDMA).
I found that using the scheduler to run the experiment in the following way can also recreate this buggy behavior.
Steps to Reproduce:
self.setattr_device("scheduler")
to def build()
while not(self.scheduler.check_termination()):
for the self.core_dma.playback_handle(example_waveform_handle)
statementartiq_client submit
to submit the same experiment twice and the two experiments should have RID 0 and RID 1 respectively.artiq_client delete 0
. The RID0 experiment should be terminated as usual but same buggy behavior existed on RID1 experiment. (Same as described in the PR description)
In that case, should core.reset()
also reset the cri_con
back to 0?
Bug Report
One-Line Summary
Delay and RTIO related drivers that are outside of a
self.core_dma.record()
malfunction after DMA playback is being terminated in the middle of execution on EFC.Issue Details
This bug is discovered when developing the example code for shuttler #2193, which can be modified to reproduce the bug. This bug exists on both DMA and DDMA. I do not know if it is an EFC exclusive bugs.
After
self.core_dma.playback_handle
is being terminated during execution, at least the following drivers malfunction when it is not placed inside aself.core_dma.record()
,But, self.core.reset() looks to be functional by observing the logs on both kasli and EFC and all the previously mentioned drivers still work inside a
self.core_dma.record()
.Steps to Reproduce
self.core_dma.playback_handle(example_waveform_handle)
statementself.led()
as a test for writing and reading rtio channelTo show that
self.core_dma.playback_handle()
is still functional, you can comment outself.init()
line.Expected Behavior
Actual (undesired) Behavior
You will not see LED blinks and relay got reset. All the delay does not exist and the program immediately stops at
assert self.afe_adc.read_id() >> 4 == 0x038d
as it reads a zero value. The printed offset value is incorrect and has a vlaue of 0.Your System