diff --git a/soc/artiqlib/rtio/core.py b/soc/artiqlib/rtio/core.py index 4fa7eb261..f59b2434a 100644 --- a/soc/artiqlib/rtio/core.py +++ b/soc/artiqlib/rtio/core.py @@ -297,17 +297,15 @@ class RTIO(Module, AutoCSR): self._r_o_timestamp = CSRStorage(counter_width + fine_ts_width) self._r_o_value = CSRStorage(2) - self._r_o_writable = CSRStatus() self._r_o_we = CSR() self._r_o_replace = CSR() - self._r_o_underflow = CSRStatus() + self._r_o_status = CSRStatus(2) self._r_o_underflow_reset = CSR() self._r_i_timestamp = CSRStatus(counter_width + fine_ts_width) self._r_i_value = CSRStatus() - self._r_i_readable = CSRStatus() self._r_i_re = CSR() - self._r_i_overflow = CSRStatus() + self._r_i_status = CSRStatus(2) self._r_i_overflow_reset = CSR() self._r_i_pileup_count = CSRStatus(16) self._r_i_pileup_reset = CSR() @@ -351,10 +349,9 @@ class RTIO(Module, AutoCSR): 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), - self._r_o_writable.status.eq(self.bank_o.writable), self.bank_o.we.eq(self._r_o_we.re), self.bank_o.replace.eq(self._r_o_replace.re), - self._r_o_underflow.status.eq(self.bank_o.underflow), + self._r_o_status.status.eq(Cat(~self.bank_o.writable, self.bank_o.underflow)), self.bank_o.underflow_reset.eq(self._r_o_underflow_reset.re) ] @@ -363,9 +360,8 @@ class RTIO(Module, AutoCSR): 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), - self._r_i_readable.status.eq(self.bank_i.readable), self.bank_i.re.eq(self._r_i_re.re), - self._r_i_overflow.status.eq(self.bank_i.overflow), + self._r_i_status.status.eq(Cat(~self.bank_i.readable, self.bank_i.overflow)), self.bank_i.overflow_reset.eq(self._r_i_overflow_reset.re), self._r_i_pileup_count.status.eq(self.bank_i.pileup_count), self.bank_i.pileup_reset.eq(self._r_i_pileup_reset.re) diff --git a/soc/runtime/rtio.c b/soc/runtime/rtio.c index 6924be41f..1b6634fc7 100644 --- a/soc/runtime/rtio.c +++ b/soc/runtime/rtio.c @@ -3,6 +3,11 @@ #include "exceptions.h" #include "rtio.h" +#define RTIO_O_STATUS_FULL 1 +#define RTIO_O_STATUS_UNDERFLOW 2 +#define RTIO_I_STATUS_EMPTY 1 +#define RTIO_I_STATUS_OVERFLOW 2 + long long int previous_fud_end_time; void rtio_init(void) @@ -20,14 +25,20 @@ void rtio_oe(int channel, int oe) void rtio_set(long long int timestamp, int channel, int value) { + int status; + 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_underflow_read()) { - rtio_o_underflow_reset_write(1); - exception_raise(EID_RTIO_UNDERFLOW); + status = rtio_o_status_read(); + if(status) { + if(status & RTIO_O_STATUS_FULL) + while(rtio_o_status_read() & RTIO_O_STATUS_FULL); + if(status & RTIO_O_STATUS_UNDERFLOW) { + rtio_o_underflow_reset_write(1); + exception_raise(EID_RTIO_UNDERFLOW); + } } } @@ -37,7 +48,7 @@ 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_underflow_read()) { + if(rtio_o_status_read() & RTIO_O_STATUS_UNDERFLOW) { rtio_o_underflow_reset_write(1); exception_raise(EID_RTIO_UNDERFLOW); } @@ -52,20 +63,26 @@ long long int rtio_get_counter(void) long long int rtio_get(int channel, long long int time_limit) { long long int r; + int status; rtio_chan_sel_write(channel); - while(rtio_i_readable_read() || (rtio_get_counter() < time_limit)) { - if(rtio_i_overflow_read()) { + while(status = rtio_i_status_read()) { + if(rtio_i_status_read() & RTIO_I_STATUS_OVERFLOW) { rtio_i_overflow_reset_write(1); exception_raise(EID_RTIO_OVERFLOW); } - if(rtio_i_readable_read()) { - r = rtio_i_timestamp_read(); - rtio_i_re_write(1); - return r; + if(rtio_get_counter() >= time_limit) { + /* check empty flag again to prevent race condition. + * now we are sure that the time limit has been exceeded. + */ + if(rtio_i_status_read() & RTIO_I_STATUS_EMPTY) + return -1; } + /* input FIFO is empty - keep waiting */ } - return -1; + r = rtio_i_timestamp_read(); + rtio_i_re_write(1); + return r; } int rtio_pileup_count(int channel) @@ -101,7 +118,7 @@ void rtio_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_underflow_read()) { + if(rtio_o_status_read() & RTIO_O_STATUS_UNDERFLOW) { rtio_o_underflow_reset_write(1); exception_raise(EID_RTIO_UNDERFLOW); }