rtio: optimize flag handling

This commit is contained in:
Sebastien Bourdeauducq 2014-12-01 14:29:50 +08:00
parent 572eecc57b
commit 50e0bf3280
2 changed files with 34 additions and 21 deletions

View File

@ -297,17 +297,15 @@ class RTIO(Module, AutoCSR):
self._r_o_timestamp = CSRStorage(counter_width + fine_ts_width) self._r_o_timestamp = CSRStorage(counter_width + fine_ts_width)
self._r_o_value = CSRStorage(2) self._r_o_value = CSRStorage(2)
self._r_o_writable = CSRStatus()
self._r_o_we = CSR() self._r_o_we = CSR()
self._r_o_replace = 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_o_underflow_reset = CSR()
self._r_i_timestamp = CSRStatus(counter_width + fine_ts_width) self._r_i_timestamp = CSRStatus(counter_width + fine_ts_width)
self._r_i_value = CSRStatus() self._r_i_value = CSRStatus()
self._r_i_readable = CSRStatus()
self._r_i_re = CSR() 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_overflow_reset = CSR()
self._r_i_pileup_count = CSRStatus(16) self._r_i_pileup_count = CSRStatus(16)
self._r_i_pileup_reset = CSR() 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.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),
self._r_o_writable.status.eq(self.bank_o.writable),
self.bank_o.we.eq(self._r_o_we.re), self.bank_o.we.eq(self._r_o_we.re),
self.bank_o.replace.eq(self._r_o_replace.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) 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.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),
self._r_i_readable.status.eq(self.bank_i.readable),
self.bank_i.re.eq(self._r_i_re.re), 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.bank_i.overflow_reset.eq(self._r_i_overflow_reset.re),
self._r_i_pileup_count.status.eq(self.bank_i.pileup_count), self._r_i_pileup_count.status.eq(self.bank_i.pileup_count),
self.bank_i.pileup_reset.eq(self._r_i_pileup_reset.re) self.bank_i.pileup_reset.eq(self._r_i_pileup_reset.re)

View File

@ -3,6 +3,11 @@
#include "exceptions.h" #include "exceptions.h"
#include "rtio.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; long long int previous_fud_end_time;
void rtio_init(void) 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) void rtio_set(long long int timestamp, int channel, int value)
{ {
int status;
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());
rtio_o_we_write(1); rtio_o_we_write(1);
if(rtio_o_underflow_read()) { status = rtio_o_status_read();
rtio_o_underflow_reset_write(1); if(status) {
exception_raise(EID_RTIO_UNDERFLOW); 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_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_underflow_read()) { if(rtio_o_status_read() & RTIO_O_STATUS_UNDERFLOW) {
rtio_o_underflow_reset_write(1); rtio_o_underflow_reset_write(1);
exception_raise(EID_RTIO_UNDERFLOW); 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 rtio_get(int channel, long long int time_limit)
{ {
long long int r; long long int r;
int status;
rtio_chan_sel_write(channel); rtio_chan_sel_write(channel);
while(rtio_i_readable_read() || (rtio_get_counter() < time_limit)) { while(status = rtio_i_status_read()) {
if(rtio_i_overflow_read()) { if(rtio_i_status_read() & RTIO_I_STATUS_OVERFLOW) {
rtio_i_overflow_reset_write(1); rtio_i_overflow_reset_write(1);
exception_raise(EID_RTIO_OVERFLOW); exception_raise(EID_RTIO_OVERFLOW);
} }
if(rtio_i_readable_read()) { if(rtio_get_counter() >= time_limit) {
r = rtio_i_timestamp_read(); /* check empty flag again to prevent race condition.
rtio_i_re_write(1); * now we are sure that the time limit has been exceeded.
return r; */
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) 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_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_underflow_read()) { if(rtio_o_status_read() & RTIO_O_STATUS_UNDERFLOW) {
rtio_o_underflow_reset_write(1); rtio_o_underflow_reset_write(1);
exception_raise(EID_RTIO_UNDERFLOW); exception_raise(EID_RTIO_UNDERFLOW);
} }