forked from M-Labs/artiq
rtio: raise RTIOSequenceError exceptions when events are not submitted in-order
This commit is contained in:
parent
73d0a84b44
commit
76fed11d59
|
@ -1,4 +1,5 @@
|
||||||
from artiq.language.core import *
|
from artiq.language.core import *
|
||||||
|
from artiq.devices.runtime_exceptions import RTIOSequenceError
|
||||||
|
|
||||||
|
|
||||||
class _RTIOBase(AutoContext):
|
class _RTIOBase(AutoContext):
|
||||||
|
@ -16,6 +17,8 @@ class _RTIOBase(AutoContext):
|
||||||
|
|
||||||
@kernel
|
@kernel
|
||||||
def _set_value(self, value):
|
def _set_value(self, value):
|
||||||
|
if now() < self.previous_timestamp:
|
||||||
|
raise RTIOSequenceError
|
||||||
if self.previous_value != value:
|
if self.previous_value != value:
|
||||||
if self.previous_timestamp == now():
|
if self.previous_timestamp == now():
|
||||||
syscall("rtio_replace", now(), self.channel, value)
|
syscall("rtio_replace", now(), self.channel, value)
|
||||||
|
|
|
@ -6,13 +6,28 @@ from artiq.language.core import RuntimeException
|
||||||
# Must be kept in sync with soc/runtime/exceptions.h
|
# Must be kept in sync with soc/runtime/exceptions.h
|
||||||
|
|
||||||
class OutOfMemory(RuntimeException):
|
class OutOfMemory(RuntimeException):
|
||||||
|
"""Raised when the runtime fails to allocate memory.
|
||||||
|
|
||||||
|
"""
|
||||||
eid = 0
|
eid = 0
|
||||||
|
|
||||||
|
|
||||||
class RTIOUnderflow(RuntimeException):
|
class RTIOUnderflow(RuntimeException):
|
||||||
|
"""Raised when the CPU fails to submit a RTIO event early enough (with respect to the event's timestamp).
|
||||||
|
|
||||||
|
"""
|
||||||
eid = 1
|
eid = 1
|
||||||
|
|
||||||
|
|
||||||
|
# Raised by RTIO driver for regular RTIO.
|
||||||
|
# Raised by runtime for DDS FUD.
|
||||||
|
class RTIOSequenceError(RuntimeException):
|
||||||
|
"""Raised when an event was not submitted with an increasing timestamp.
|
||||||
|
|
||||||
|
"""
|
||||||
|
eid = 2
|
||||||
|
|
||||||
|
|
||||||
exception_map = {e.eid: e for e in globals().values()
|
exception_map = {e.eid: e for e in globals().values()
|
||||||
if inspect.isclass(e)
|
if inspect.isclass(e)
|
||||||
and issubclass(e, RuntimeException)
|
and issubclass(e, RuntimeException)
|
||||||
|
|
|
@ -12,3 +12,9 @@ Drivers reference
|
||||||
|
|
||||||
.. automodule:: artiq.devices.dds_core
|
.. automodule:: artiq.devices.dds_core
|
||||||
:members:
|
:members:
|
||||||
|
|
||||||
|
:mod:`artiq.devices.runtime_exceptions` module
|
||||||
|
----------------------------------------------
|
||||||
|
|
||||||
|
.. automodule:: artiq.devices.runtime_exceptions
|
||||||
|
:members:
|
||||||
|
|
|
@ -28,8 +28,11 @@ static void fud_sync(void)
|
||||||
static void fud(long long int fud_time)
|
static void fud(long long int fud_time)
|
||||||
{
|
{
|
||||||
int r;
|
int r;
|
||||||
|
static int previous_fud_time;
|
||||||
|
|
||||||
r = rtio_reset_read();
|
r = rtio_reset_read();
|
||||||
|
if(r)
|
||||||
|
previous_fud_time = 0;
|
||||||
rtio_reset_write(0);
|
rtio_reset_write(0);
|
||||||
|
|
||||||
rtio_chan_sel_write(RTIO_FUD_CHANNEL);
|
rtio_chan_sel_write(RTIO_FUD_CHANNEL);
|
||||||
|
@ -37,6 +40,9 @@ static void fud(long long int fud_time)
|
||||||
rtio_counter_update_write(1);
|
rtio_counter_update_write(1);
|
||||||
fud_time = rtio_counter_read() + 3000;
|
fud_time = rtio_counter_read() + 3000;
|
||||||
}
|
}
|
||||||
|
if(fud_time < previous_fud_time)
|
||||||
|
exception_raise(EID_RTIO_SEQUENCE_ERROR);
|
||||||
|
|
||||||
rtio_o_timestamp_write(fud_time);
|
rtio_o_timestamp_write(fud_time);
|
||||||
rtio_o_value_write(1);
|
rtio_o_value_write(1);
|
||||||
rtio_o_we_write(1);
|
rtio_o_we_write(1);
|
||||||
|
|
|
@ -3,7 +3,8 @@
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
EID_OUT_OF_MEMORY = 0,
|
EID_OUT_OF_MEMORY = 0,
|
||||||
EID_RTIO_UNDERFLOW = 1
|
EID_RTIO_UNDERFLOW = 1,
|
||||||
|
EID_RTIO_SEQUENCE_ERROR = 2
|
||||||
};
|
};
|
||||||
|
|
||||||
int exception_setjmp(void *jb) __attribute__((returns_twice));
|
int exception_setjmp(void *jb) __attribute__((returns_twice));
|
||||||
|
|
|
@ -163,6 +163,17 @@ class _RTIOUnderflow(AutoContext):
|
||||||
self.o.pulse(25*ns)
|
self.o.pulse(25*ns)
|
||||||
|
|
||||||
|
|
||||||
|
class _RTIOSequenceError(AutoContext):
|
||||||
|
parameters = "o"
|
||||||
|
|
||||||
|
@kernel
|
||||||
|
def run(self):
|
||||||
|
t = now()
|
||||||
|
self.o.pulse(25*us)
|
||||||
|
at(t)
|
||||||
|
self.o.pulse(25*us)
|
||||||
|
|
||||||
|
|
||||||
class RTIOCase(unittest.TestCase):
|
class RTIOCase(unittest.TestCase):
|
||||||
def test_loopback(self):
|
def test_loopback(self):
|
||||||
npulses = 4
|
npulses = 4
|
||||||
|
@ -186,3 +197,13 @@ class RTIOCase(unittest.TestCase):
|
||||||
)
|
)
|
||||||
with self.assertRaises(runtime_exceptions.RTIOUnderflow):
|
with self.assertRaises(runtime_exceptions.RTIOUnderflow):
|
||||||
uut.run()
|
uut.run()
|
||||||
|
|
||||||
|
def test_sequence_error(self):
|
||||||
|
with corecom_serial.CoreCom() as com:
|
||||||
|
coredev = core.Core(com)
|
||||||
|
uut = _RTIOSequenceError(
|
||||||
|
core=coredev,
|
||||||
|
o=rtio_core.RTIOOut(core=coredev, channel=1)
|
||||||
|
)
|
||||||
|
with self.assertRaises(runtime_exceptions.RTIOSequenceError):
|
||||||
|
uut.run()
|
||||||
|
|
Loading…
Reference in New Issue