rtio: error recovery

This commit is contained in:
Sebastien Bourdeauducq 2014-10-10 20:12:22 +08:00
parent b749c8e64c
commit 1c24a5971b
4 changed files with 49 additions and 28 deletions

View File

@ -8,8 +8,8 @@ from artiqlib.rtio.rbus import get_fine_ts_width
class _RTIOBankO(Module):
def __init__(self, rbus, counter_width, fine_ts_width,
fifo_depth, counter_init):
def __init__(self, rbus, counter, fine_ts_width, fifo_depth):
counter_width = flen(counter)
self.sel = Signal(max=len(rbus))
self.timestamp = Signal(counter_width+fine_ts_width)
self.value = Signal(2)
@ -18,16 +18,13 @@ class _RTIOBankO(Module):
self.replace = Signal()
self.underflow = Signal()
self.level = Signal(bits_for(fifo_depth))
self.counter = Signal(counter_width, reset=counter_init)
# # #
self.sync += self.counter.eq(self.counter + 1)
# detect underflows
self.sync += \
If((self.we & self.writable) | self.replace,
If(self.timestamp[fine_ts_width:] < self.counter + 2,
If(self.timestamp[fine_ts_width:] < counter + 2,
self.underflow.eq(1))
)
@ -50,7 +47,7 @@ class _RTIOBankO(Module):
# FIFO read
self.comb += [
chif.o_stb.eq(fifo.readable &
(fifo.dout.timestamp[fine_ts_width:] == self.counter)),
(fifo.dout.timestamp[fine_ts_width:] == counter)),
chif.o_value.eq(fifo.dout.value),
fifo.re.eq(chif.o_stb)
]
@ -66,7 +63,8 @@ class _RTIOBankO(Module):
class _RTIOBankI(Module):
def __init__(self, rbus, counter_width, fine_ts_width, fifo_depth):
def __init__(self, rbus, counter, fine_ts_width, fifo_depth):
counter_width = flen(counter)
self.sel = Signal(max=len(rbus))
self.timestamp = Signal(counter_width+fine_ts_width)
self.value = Signal()
@ -75,10 +73,7 @@ class _RTIOBankI(Module):
self.overflow = Signal()
self.pileup = Signal()
###
counter = Signal(counter_width)
self.sync += counter.eq(counter + 1)
# # #
timestamps = []
values = []
@ -143,17 +138,30 @@ class RTIO(Module, AutoCSR):
def __init__(self, phy, clk_freq, counter_width=32, ofifo_depth=64, ififo_depth=64):
fine_ts_width = get_fine_ts_width(phy.rbus)
# Counters
reset_counter = Signal()
o_counter = Signal(counter_width, reset=phy.loopback_latency)
i_counter = Signal(counter_width)
self.sync += \
If(reset_counter,
o_counter.eq(o_counter.reset),
i_counter.eq(i_counter.reset)
).Else(
o_counter.eq(o_counter + 1),
i_counter.eq(i_counter + 1)
)
# Submodules
self.submodules.bank_o = InsertReset(_RTIOBankO(
phy.rbus,
counter_width, fine_ts_width, ofifo_depth,
phy.loopback_latency))
o_counter, fine_ts_width, ofifo_depth))
self.submodules.bank_i = InsertReset(_RTIOBankI(
phy.rbus,
counter_width, fine_ts_width, ofifo_depth))
i_counter, fine_ts_width, ofifo_depth))
# CSRs
self._r_reset = CSRStorage(reset=1)
self._r_reset_logic = CSRStorage(reset=1)
self._r_reset_counter = CSRStorage(reset=1)
self._r_chan_sel = CSRStorage(flen(self.bank_o.sel))
self._r_oe = CSR()
@ -194,7 +202,7 @@ class RTIO(Module, AutoCSR):
# Output/Gate
self.comb += [
self.bank_o.reset.eq(self._r_reset.storage),
self.bank_o.reset.eq(self._r_reset_logic.storage),
self.bank_o.sel.eq(self._r_chan_sel.storage),
self.bank_o.timestamp.eq(self._r_o_timestamp.storage),
self.bank_o.value.eq(self._r_o_value.storage),
@ -207,7 +215,7 @@ class RTIO(Module, AutoCSR):
# Input
self.comb += [
self.bank_i.reset.eq(self._r_reset.storage),
self.bank_i.reset.eq(self._r_reset_logic.storage),
self.bank_i.sel.eq(self._r_chan_sel.storage),
self._r_i_timestamp.status.eq(self.bank_i.timestamp),
self._r_i_value.status.eq(self.bank_i.value),
@ -217,11 +225,12 @@ class RTIO(Module, AutoCSR):
Cat(self.bank_i.overflow, self.bank_i.pileup))
]
# Counter
# Counter access
self.comb += reset_counter.eq(self._r_reset_counter.storage)
self.sync += \
If(self._r_counter_update.re,
self._r_counter.status.eq(Cat(Replicate(0, fine_ts_width),
self.bank_o.counter))
o_counter))
)
# Frequency

View File

@ -31,10 +31,10 @@ static void fud(long long int fud_time)
long long int fud_end_time;
static long long int previous_fud_end_time;
r = rtio_reset_read();
r = rtio_reset_counter_read();
if(r)
previous_fud_end_time = 0;
rtio_reset_write(0);
rtio_reset_counter_write(0);
rtio_chan_sel_write(RTIO_FUD_CHANNEL);
if(fud_time < 0) {
@ -52,12 +52,15 @@ static void fud(long long int fud_time)
rtio_o_timestamp_write(fud_end_time);
rtio_o_value_write(0);
rtio_o_we_write(1);
if(rtio_o_error_read())
if(rtio_o_error_read()) {
rtio_reset_logic_write(1);
rtio_reset_logic_write(0);
exception_raise(EID_RTIO_UNDERFLOW);
}
if(r) {
fud_sync();
rtio_reset_write(1);
rtio_reset_counter_write(1);
}
}

View File

@ -110,6 +110,7 @@ int main(void)
uart_init();
puts("ARTIQ runtime built "__DATE__" "__TIME__"\n");
rtio_init();
dds_init();
blink_led();
corecom_serve(load_object, run_kernel);

View File

@ -5,7 +5,9 @@
void rtio_init(void)
{
rtio_reset_write(1);
rtio_reset_counter_write(1);
rtio_reset_logic_write(1);
rtio_reset_logic_write(0);
}
void rtio_oe(int channel, int oe)
@ -16,14 +18,17 @@ void rtio_oe(int channel, int oe)
void rtio_set(long long int timestamp, int channel, int value)
{
rtio_reset_write(0);
rtio_reset_counter_write(0);
rtio_chan_sel_write(channel);
rtio_o_timestamp_write(timestamp);
rtio_o_value_write(value);
while(!rtio_o_writable_read());
rtio_o_we_write(1);
if(rtio_o_error_read())
if(rtio_o_error_read()) {
rtio_reset_logic_write(1);
rtio_reset_logic_write(0);
exception_raise(EID_RTIO_UNDERFLOW);
}
}
void rtio_replace(long long int timestamp, int channel, int value)
@ -32,8 +37,11 @@ void rtio_replace(long long int timestamp, int channel, int value)
rtio_o_timestamp_write(timestamp);
rtio_o_value_write(value);
rtio_o_replace_write(1);
if(rtio_o_error_read())
if(rtio_o_error_read()) {
rtio_reset_logic_write(1);
rtio_reset_logic_write(0);
exception_raise(EID_RTIO_UNDERFLOW);
}
}
void rtio_sync(int channel)