Skip to content

Commit

Permalink
rtio: add RTIOBusy
Browse files Browse the repository at this point in the history
jordens committed Mar 8, 2016
1 parent 0d431cb commit 2cb5859
Showing 5 changed files with 46 additions and 4 deletions.
2 changes: 1 addition & 1 deletion artiq/coredevice/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from artiq.coredevice import exceptions, dds, spi
from artiq.coredevice.exceptions import (RTIOUnderflow, RTIOSequenceError,
RTIOCollision, RTIOOverflow,
RTIOCollision, RTIOOverflow, RTIOBusy,
DDSBatchError, CacheError)
from artiq.coredevice.dds import (PHASE_MODE_CONTINUOUS, PHASE_MODE_ABSOLUTE,
PHASE_MODE_TRACKING)
13 changes: 13 additions & 0 deletions artiq/coredevice/exceptions.py
Original file line number Diff line number Diff line change
@@ -98,6 +98,19 @@ class RTIOCollision(Exception):
"""
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):
"""Raised when at least one event could not be registered into the RTIO
input FIFO because it was full (CPU not reading fast enough).
27 changes: 24 additions & 3 deletions artiq/gateware/rtio/core.py
Original file line number Diff line number Diff line change
@@ -104,6 +104,7 @@ def __init__(self, interface, counter, fifo_depth, guard_io_cycles):
self.underflow = Signal() # valid 1 cycle after we, pulsed
self.sequence_error = Signal()
self.collision = Signal()
self.busy = Signal() # pulsed

# # #

@@ -223,6 +224,20 @@ def __init__(self, interface, counter, fifo_depth, guard_io_cycles):
dout.timestamp[fine_ts_width:] == counter.value_rtio),
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:
self.comb += interface.data.eq(dout.data)
if address_width:
@@ -336,10 +351,11 @@ def __init__(self, chan_sel_width,
self.o_address = CSRStorage(address_width)
self.o_timestamp = CSRStorage(full_ts_width)
self.o_we = CSR()
self.o_status = CSRStatus(4)
self.o_status = CSRStatus(5)
self.o_underflow_reset = CSR()
self.o_sequence_error_reset = CSR()
self.o_collision_reset = CSR()
self.o_busy_reset = CSR()

if data_width:
self.i_data = CSRStatus(data_width)
@@ -427,21 +443,26 @@ def __init__(self, channels, full_ts_width=63, guard_io_cycles=20):
underflow = Signal()
sequence_error = Signal()
collision = Signal()
busy = Signal()
self.sync.rsys += [
If(selected & self.kcsrs.o_underflow_reset.re,
underflow.eq(0)),
If(selected & self.kcsrs.o_sequence_error_reset.re,
sequence_error.eq(0)),
If(selected & self.kcsrs.o_collision_reset.re,
collision.eq(0)),
If(selected & self.kcsrs.o_busy_reset.re,
busy.eq(0)),
If(o_manager.underflow, underflow.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,
underflow,
sequence_error,
collision))
collision,
busy))

if channel.interface.i is not None:
i_manager = _InputManager(channel.interface.i, self.counter,
6 changes: 6 additions & 0 deletions artiq/runtime/rtio.c
Original file line number Diff line number Diff line change
@@ -39,6 +39,12 @@ static void rtio_process_exceptional_status(
"RTIO collision at {0} mu, channel {1}",
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 changes: 2 additions & 0 deletions artiq/runtime/rtio.h
Original file line number Diff line number Diff line change
@@ -2,11 +2,13 @@
#define __RTIO_H

#include <stdarg.h>
#include "generated/csr.h"

#define RTIO_O_STATUS_FULL 1
#define RTIO_O_STATUS_UNDERFLOW 2
#define RTIO_O_STATUS_SEQUENCE_ERROR 4
#define RTIO_O_STATUS_COLLISION 8
#define RTIO_O_STATUS_BUSY 16
#define RTIO_I_STATUS_EMPTY 1
#define RTIO_I_STATUS_OVERFLOW 2

0 comments on commit 2cb5859

Please sign in to comment.