forked from M-Labs/artiq
rtio: error recovery
This commit is contained in:
parent
b749c8e64c
commit
1c24a5971b
|
@ -8,8 +8,8 @@ from artiqlib.rtio.rbus import get_fine_ts_width
|
||||||
|
|
||||||
|
|
||||||
class _RTIOBankO(Module):
|
class _RTIOBankO(Module):
|
||||||
def __init__(self, rbus, counter_width, fine_ts_width,
|
def __init__(self, rbus, counter, fine_ts_width, fifo_depth):
|
||||||
fifo_depth, counter_init):
|
counter_width = flen(counter)
|
||||||
self.sel = Signal(max=len(rbus))
|
self.sel = Signal(max=len(rbus))
|
||||||
self.timestamp = Signal(counter_width+fine_ts_width)
|
self.timestamp = Signal(counter_width+fine_ts_width)
|
||||||
self.value = Signal(2)
|
self.value = Signal(2)
|
||||||
|
@ -18,16 +18,13 @@ class _RTIOBankO(Module):
|
||||||
self.replace = Signal()
|
self.replace = Signal()
|
||||||
self.underflow = Signal()
|
self.underflow = Signal()
|
||||||
self.level = Signal(bits_for(fifo_depth))
|
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
|
# detect underflows
|
||||||
self.sync += \
|
self.sync += \
|
||||||
If((self.we & self.writable) | self.replace,
|
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))
|
self.underflow.eq(1))
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -50,7 +47,7 @@ class _RTIOBankO(Module):
|
||||||
# FIFO read
|
# FIFO read
|
||||||
self.comb += [
|
self.comb += [
|
||||||
chif.o_stb.eq(fifo.readable &
|
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),
|
chif.o_value.eq(fifo.dout.value),
|
||||||
fifo.re.eq(chif.o_stb)
|
fifo.re.eq(chif.o_stb)
|
||||||
]
|
]
|
||||||
|
@ -66,7 +63,8 @@ class _RTIOBankO(Module):
|
||||||
|
|
||||||
|
|
||||||
class _RTIOBankI(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.sel = Signal(max=len(rbus))
|
||||||
self.timestamp = Signal(counter_width+fine_ts_width)
|
self.timestamp = Signal(counter_width+fine_ts_width)
|
||||||
self.value = Signal()
|
self.value = Signal()
|
||||||
|
@ -75,10 +73,7 @@ class _RTIOBankI(Module):
|
||||||
self.overflow = Signal()
|
self.overflow = Signal()
|
||||||
self.pileup = Signal()
|
self.pileup = Signal()
|
||||||
|
|
||||||
###
|
# # #
|
||||||
|
|
||||||
counter = Signal(counter_width)
|
|
||||||
self.sync += counter.eq(counter + 1)
|
|
||||||
|
|
||||||
timestamps = []
|
timestamps = []
|
||||||
values = []
|
values = []
|
||||||
|
@ -143,17 +138,30 @@ class RTIO(Module, AutoCSR):
|
||||||
def __init__(self, phy, clk_freq, counter_width=32, ofifo_depth=64, ififo_depth=64):
|
def __init__(self, phy, clk_freq, counter_width=32, ofifo_depth=64, ififo_depth=64):
|
||||||
fine_ts_width = get_fine_ts_width(phy.rbus)
|
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
|
# Submodules
|
||||||
self.submodules.bank_o = InsertReset(_RTIOBankO(
|
self.submodules.bank_o = InsertReset(_RTIOBankO(
|
||||||
phy.rbus,
|
phy.rbus,
|
||||||
counter_width, fine_ts_width, ofifo_depth,
|
o_counter, fine_ts_width, ofifo_depth))
|
||||||
phy.loopback_latency))
|
|
||||||
self.submodules.bank_i = InsertReset(_RTIOBankI(
|
self.submodules.bank_i = InsertReset(_RTIOBankI(
|
||||||
phy.rbus,
|
phy.rbus,
|
||||||
counter_width, fine_ts_width, ofifo_depth))
|
i_counter, fine_ts_width, ofifo_depth))
|
||||||
|
|
||||||
# CSRs
|
# 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_chan_sel = CSRStorage(flen(self.bank_o.sel))
|
||||||
|
|
||||||
self._r_oe = CSR()
|
self._r_oe = CSR()
|
||||||
|
@ -194,7 +202,7 @@ class RTIO(Module, AutoCSR):
|
||||||
|
|
||||||
# Output/Gate
|
# Output/Gate
|
||||||
self.comb += [
|
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.sel.eq(self._r_chan_sel.storage),
|
||||||
self.bank_o.timestamp.eq(self._r_o_timestamp.storage),
|
self.bank_o.timestamp.eq(self._r_o_timestamp.storage),
|
||||||
self.bank_o.value.eq(self._r_o_value.storage),
|
self.bank_o.value.eq(self._r_o_value.storage),
|
||||||
|
@ -207,7 +215,7 @@ class RTIO(Module, AutoCSR):
|
||||||
|
|
||||||
# Input
|
# Input
|
||||||
self.comb += [
|
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.bank_i.sel.eq(self._r_chan_sel.storage),
|
||||||
self._r_i_timestamp.status.eq(self.bank_i.timestamp),
|
self._r_i_timestamp.status.eq(self.bank_i.timestamp),
|
||||||
self._r_i_value.status.eq(self.bank_i.value),
|
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))
|
Cat(self.bank_i.overflow, self.bank_i.pileup))
|
||||||
]
|
]
|
||||||
|
|
||||||
# Counter
|
# Counter access
|
||||||
|
self.comb += reset_counter.eq(self._r_reset_counter.storage)
|
||||||
self.sync += \
|
self.sync += \
|
||||||
If(self._r_counter_update.re,
|
If(self._r_counter_update.re,
|
||||||
self._r_counter.status.eq(Cat(Replicate(0, fine_ts_width),
|
self._r_counter.status.eq(Cat(Replicate(0, fine_ts_width),
|
||||||
self.bank_o.counter))
|
o_counter))
|
||||||
)
|
)
|
||||||
|
|
||||||
# Frequency
|
# Frequency
|
||||||
|
|
|
@ -31,10 +31,10 @@ static void fud(long long int fud_time)
|
||||||
long long int fud_end_time;
|
long long int fud_end_time;
|
||||||
static long long int previous_fud_end_time;
|
static long long int previous_fud_end_time;
|
||||||
|
|
||||||
r = rtio_reset_read();
|
r = rtio_reset_counter_read();
|
||||||
if(r)
|
if(r)
|
||||||
previous_fud_end_time = 0;
|
previous_fud_end_time = 0;
|
||||||
rtio_reset_write(0);
|
rtio_reset_counter_write(0);
|
||||||
|
|
||||||
rtio_chan_sel_write(RTIO_FUD_CHANNEL);
|
rtio_chan_sel_write(RTIO_FUD_CHANNEL);
|
||||||
if(fud_time < 0) {
|
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_timestamp_write(fud_end_time);
|
||||||
rtio_o_value_write(0);
|
rtio_o_value_write(0);
|
||||||
rtio_o_we_write(1);
|
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);
|
exception_raise(EID_RTIO_UNDERFLOW);
|
||||||
|
}
|
||||||
|
|
||||||
if(r) {
|
if(r) {
|
||||||
fud_sync();
|
fud_sync();
|
||||||
rtio_reset_write(1);
|
rtio_reset_counter_write(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -110,6 +110,7 @@ int main(void)
|
||||||
uart_init();
|
uart_init();
|
||||||
|
|
||||||
puts("ARTIQ runtime built "__DATE__" "__TIME__"\n");
|
puts("ARTIQ runtime built "__DATE__" "__TIME__"\n");
|
||||||
|
rtio_init();
|
||||||
dds_init();
|
dds_init();
|
||||||
blink_led();
|
blink_led();
|
||||||
corecom_serve(load_object, run_kernel);
|
corecom_serve(load_object, run_kernel);
|
||||||
|
|
|
@ -5,7 +5,9 @@
|
||||||
|
|
||||||
void rtio_init(void)
|
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)
|
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)
|
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_chan_sel_write(channel);
|
||||||
rtio_o_timestamp_write(timestamp);
|
rtio_o_timestamp_write(timestamp);
|
||||||
rtio_o_value_write(value);
|
rtio_o_value_write(value);
|
||||||
while(!rtio_o_writable_read());
|
while(!rtio_o_writable_read());
|
||||||
rtio_o_we_write(1);
|
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);
|
exception_raise(EID_RTIO_UNDERFLOW);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void rtio_replace(long long int timestamp, int channel, int value)
|
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_timestamp_write(timestamp);
|
||||||
rtio_o_value_write(value);
|
rtio_o_value_write(value);
|
||||||
rtio_o_replace_write(1);
|
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);
|
exception_raise(EID_RTIO_UNDERFLOW);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void rtio_sync(int channel)
|
void rtio_sync(int channel)
|
||||||
|
|
Loading…
Reference in New Issue