forked from M-Labs/artiq
rtio: add RTIOBusy
This commit is contained in:
parent
0d431cb019
commit
2cb58592ff
|
@ -1,6 +1,6 @@
|
||||||
from artiq.coredevice import exceptions, dds, spi
|
from artiq.coredevice import exceptions, dds, spi
|
||||||
from artiq.coredevice.exceptions import (RTIOUnderflow, RTIOSequenceError,
|
from artiq.coredevice.exceptions import (RTIOUnderflow, RTIOSequenceError,
|
||||||
RTIOCollision, RTIOOverflow,
|
RTIOCollision, RTIOOverflow, RTIOBusy,
|
||||||
DDSBatchError, CacheError)
|
DDSBatchError, CacheError)
|
||||||
from artiq.coredevice.dds import (PHASE_MODE_CONTINUOUS, PHASE_MODE_ABSOLUTE,
|
from artiq.coredevice.dds import (PHASE_MODE_CONTINUOUS, PHASE_MODE_ABSOLUTE,
|
||||||
PHASE_MODE_TRACKING)
|
PHASE_MODE_TRACKING)
|
||||||
|
|
|
@ -98,6 +98,19 @@ class RTIOCollision(Exception):
|
||||||
"""
|
"""
|
||||||
artiq_builtin = True
|
artiq_builtin = True
|
||||||
|
|
||||||
|
class RTIOBusy(Exception):
|
||||||
|
"""Raised when an event could not be executed because the given channel
|
||||||
|
was already busy executing a previous event. The two events were not
|
||||||
|
sufficiently spaced on the timeline.
|
||||||
|
|
||||||
|
This exception is raised after the error condition appeared. More
|
||||||
|
specifically it is raised on submitting an event on the same channel after
|
||||||
|
the execution of the faulty event was attempted.
|
||||||
|
|
||||||
|
The offending event is discarded and the RTIO core keeps operating.
|
||||||
|
"""
|
||||||
|
artiq_builtin = True
|
||||||
|
|
||||||
class RTIOOverflow(Exception):
|
class RTIOOverflow(Exception):
|
||||||
"""Raised when at least one event could not be registered into the RTIO
|
"""Raised when at least one event could not be registered into the RTIO
|
||||||
input FIFO because it was full (CPU not reading fast enough).
|
input FIFO because it was full (CPU not reading fast enough).
|
||||||
|
|
|
@ -104,6 +104,7 @@ class _OutputManager(Module):
|
||||||
self.underflow = Signal() # valid 1 cycle after we, pulsed
|
self.underflow = Signal() # valid 1 cycle after we, pulsed
|
||||||
self.sequence_error = Signal()
|
self.sequence_error = Signal()
|
||||||
self.collision = Signal()
|
self.collision = Signal()
|
||||||
|
self.busy = Signal() # pulsed
|
||||||
|
|
||||||
# # #
|
# # #
|
||||||
|
|
||||||
|
@ -223,6 +224,20 @@ class _OutputManager(Module):
|
||||||
dout.timestamp[fine_ts_width:] == counter.value_rtio),
|
dout.timestamp[fine_ts_width:] == counter.value_rtio),
|
||||||
interface.stb.eq(dout_stb & dout_ack)
|
interface.stb.eq(dout_stb & dout_ack)
|
||||||
]
|
]
|
||||||
|
busy_sync = PulseSynchronizer("rio", "rsys")
|
||||||
|
busy_ack_sync = PulseSynchronizer("rsys", "rio")
|
||||||
|
self.submodules += busy_sync, busy_ack_sync
|
||||||
|
busy_blind = Signal()
|
||||||
|
self.comb += busy_sync.i.eq(interface.stb & interface.busy & ~busy_blind)
|
||||||
|
self.sync.rio += [
|
||||||
|
If(interface.stb & interface.busy, busy_blind.eq(1)),
|
||||||
|
If(busy_ack_sync.o, busy_blind.eq(0))
|
||||||
|
]
|
||||||
|
self.comb += [
|
||||||
|
busy_ack_sync.i.eq(busy_sync.o),
|
||||||
|
self.busy.eq(busy_sync.o)
|
||||||
|
]
|
||||||
|
|
||||||
if data_width:
|
if data_width:
|
||||||
self.comb += interface.data.eq(dout.data)
|
self.comb += interface.data.eq(dout.data)
|
||||||
if address_width:
|
if address_width:
|
||||||
|
@ -336,10 +351,11 @@ class _KernelCSRs(AutoCSR):
|
||||||
self.o_address = CSRStorage(address_width)
|
self.o_address = CSRStorage(address_width)
|
||||||
self.o_timestamp = CSRStorage(full_ts_width)
|
self.o_timestamp = CSRStorage(full_ts_width)
|
||||||
self.o_we = CSR()
|
self.o_we = CSR()
|
||||||
self.o_status = CSRStatus(4)
|
self.o_status = CSRStatus(5)
|
||||||
self.o_underflow_reset = CSR()
|
self.o_underflow_reset = CSR()
|
||||||
self.o_sequence_error_reset = CSR()
|
self.o_sequence_error_reset = CSR()
|
||||||
self.o_collision_reset = CSR()
|
self.o_collision_reset = CSR()
|
||||||
|
self.o_busy_reset = CSR()
|
||||||
|
|
||||||
if data_width:
|
if data_width:
|
||||||
self.i_data = CSRStatus(data_width)
|
self.i_data = CSRStatus(data_width)
|
||||||
|
@ -427,6 +443,7 @@ class RTIO(Module):
|
||||||
underflow = Signal()
|
underflow = Signal()
|
||||||
sequence_error = Signal()
|
sequence_error = Signal()
|
||||||
collision = Signal()
|
collision = Signal()
|
||||||
|
busy = Signal()
|
||||||
self.sync.rsys += [
|
self.sync.rsys += [
|
||||||
If(selected & self.kcsrs.o_underflow_reset.re,
|
If(selected & self.kcsrs.o_underflow_reset.re,
|
||||||
underflow.eq(0)),
|
underflow.eq(0)),
|
||||||
|
@ -434,14 +451,18 @@ class RTIO(Module):
|
||||||
sequence_error.eq(0)),
|
sequence_error.eq(0)),
|
||||||
If(selected & self.kcsrs.o_collision_reset.re,
|
If(selected & self.kcsrs.o_collision_reset.re,
|
||||||
collision.eq(0)),
|
collision.eq(0)),
|
||||||
|
If(selected & self.kcsrs.o_busy_reset.re,
|
||||||
|
busy.eq(0)),
|
||||||
If(o_manager.underflow, underflow.eq(1)),
|
If(o_manager.underflow, underflow.eq(1)),
|
||||||
If(o_manager.sequence_error, sequence_error.eq(1)),
|
If(o_manager.sequence_error, sequence_error.eq(1)),
|
||||||
If(o_manager.collision, collision.eq(1))
|
If(o_manager.collision, collision.eq(1)),
|
||||||
|
If(o_manager.busy, busy.eq(1))
|
||||||
]
|
]
|
||||||
o_statuses.append(Cat(~o_manager.writable,
|
o_statuses.append(Cat(~o_manager.writable,
|
||||||
underflow,
|
underflow,
|
||||||
sequence_error,
|
sequence_error,
|
||||||
collision))
|
collision,
|
||||||
|
busy))
|
||||||
|
|
||||||
if channel.interface.i is not None:
|
if channel.interface.i is not None:
|
||||||
i_manager = _InputManager(channel.interface.i, self.counter,
|
i_manager = _InputManager(channel.interface.i, self.counter,
|
||||||
|
|
|
@ -39,6 +39,12 @@ static void rtio_process_exceptional_status(
|
||||||
"RTIO collision at {0} mu, channel {1}",
|
"RTIO collision at {0} mu, channel {1}",
|
||||||
timestamp, channel, 0);
|
timestamp, channel, 0);
|
||||||
}
|
}
|
||||||
|
if(status & RTIO_O_STATUS_BUSY) {
|
||||||
|
rtio_o_busy_reset_write(1);
|
||||||
|
artiq_raise_from_c("RTIOBusy",
|
||||||
|
"RTIO busy at {0} mu, channel {1}",
|
||||||
|
timestamp, channel, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -2,11 +2,13 @@
|
||||||
#define __RTIO_H
|
#define __RTIO_H
|
||||||
|
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
#include "generated/csr.h"
|
||||||
|
|
||||||
#define RTIO_O_STATUS_FULL 1
|
#define RTIO_O_STATUS_FULL 1
|
||||||
#define RTIO_O_STATUS_UNDERFLOW 2
|
#define RTIO_O_STATUS_UNDERFLOW 2
|
||||||
#define RTIO_O_STATUS_SEQUENCE_ERROR 4
|
#define RTIO_O_STATUS_SEQUENCE_ERROR 4
|
||||||
#define RTIO_O_STATUS_COLLISION 8
|
#define RTIO_O_STATUS_COLLISION 8
|
||||||
|
#define RTIO_O_STATUS_BUSY 16
|
||||||
#define RTIO_I_STATUS_EMPTY 1
|
#define RTIO_I_STATUS_EMPTY 1
|
||||||
#define RTIO_I_STATUS_OVERFLOW 2
|
#define RTIO_I_STATUS_OVERFLOW 2
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue