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

View File

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