From 76fed11d59fcbed4376a7ad3aa8e58ea96d4366d Mon Sep 17 00:00:00 2001 From: Sebastien Bourdeauducq Date: Tue, 30 Sep 2014 19:32:11 +0800 Subject: [PATCH] rtio: raise RTIOSequenceError exceptions when events are not submitted in-order --- artiq/devices/rtio_core.py | 3 +++ artiq/devices/runtime_exceptions.py | 15 +++++++++++++++ doc/manual/drivers_reference.rst | 6 ++++++ soc/runtime/dds.c | 6 ++++++ soc/runtime/exceptions.h | 3 ++- test/full_stack.py | 21 +++++++++++++++++++++ 6 files changed, 53 insertions(+), 1 deletion(-) diff --git a/artiq/devices/rtio_core.py b/artiq/devices/rtio_core.py index 2eedbd279..88143a919 100644 --- a/artiq/devices/rtio_core.py +++ b/artiq/devices/rtio_core.py @@ -1,4 +1,5 @@ from artiq.language.core import * +from artiq.devices.runtime_exceptions import RTIOSequenceError class _RTIOBase(AutoContext): @@ -16,6 +17,8 @@ class _RTIOBase(AutoContext): @kernel def _set_value(self, value): + if now() < self.previous_timestamp: + raise RTIOSequenceError if self.previous_value != value: if self.previous_timestamp == now(): syscall("rtio_replace", now(), self.channel, value) diff --git a/artiq/devices/runtime_exceptions.py b/artiq/devices/runtime_exceptions.py index c9a90b697..fe3521470 100644 --- a/artiq/devices/runtime_exceptions.py +++ b/artiq/devices/runtime_exceptions.py @@ -6,13 +6,28 @@ from artiq.language.core import RuntimeException # Must be kept in sync with soc/runtime/exceptions.h class OutOfMemory(RuntimeException): + """Raised when the runtime fails to allocate memory. + + """ eid = 0 class RTIOUnderflow(RuntimeException): + """Raised when the CPU fails to submit a RTIO event early enough (with respect to the event's timestamp). + + """ 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() if inspect.isclass(e) and issubclass(e, RuntimeException) diff --git a/doc/manual/drivers_reference.rst b/doc/manual/drivers_reference.rst index 60378625f..7bc405325 100644 --- a/doc/manual/drivers_reference.rst +++ b/doc/manual/drivers_reference.rst @@ -12,3 +12,9 @@ Drivers reference .. automodule:: artiq.devices.dds_core :members: + +:mod:`artiq.devices.runtime_exceptions` module +---------------------------------------------- + +.. automodule:: artiq.devices.runtime_exceptions + :members: diff --git a/soc/runtime/dds.c b/soc/runtime/dds.c index ae9bcab57..d34c5d308 100644 --- a/soc/runtime/dds.c +++ b/soc/runtime/dds.c @@ -28,8 +28,11 @@ static void fud_sync(void) static void fud(long long int fud_time) { int r; + static int previous_fud_time; r = rtio_reset_read(); + if(r) + previous_fud_time = 0; rtio_reset_write(0); rtio_chan_sel_write(RTIO_FUD_CHANNEL); @@ -37,6 +40,9 @@ static void fud(long long int fud_time) rtio_counter_update_write(1); 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_value_write(1); rtio_o_we_write(1); diff --git a/soc/runtime/exceptions.h b/soc/runtime/exceptions.h index d701153b0..bc53ea487 100644 --- a/soc/runtime/exceptions.h +++ b/soc/runtime/exceptions.h @@ -3,7 +3,8 @@ enum { 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)); diff --git a/test/full_stack.py b/test/full_stack.py index 58c8cf40f..0356e93ef 100644 --- a/test/full_stack.py +++ b/test/full_stack.py @@ -163,6 +163,17 @@ class _RTIOUnderflow(AutoContext): 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): def test_loopback(self): npulses = 4 @@ -186,3 +197,13 @@ class RTIOCase(unittest.TestCase): ) with self.assertRaises(runtime_exceptions.RTIOUnderflow): 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()