forked from M-Labs/artiq
1
0
Fork 0

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): 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

View File

@ -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);
} }
} }

View File

@ -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);

View File

@ -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)