diff --git a/artiq/coredevice/rtio.py b/artiq/coredevice/rtio.py index 669ff1164..cda20bb24 100644 --- a/artiq/coredevice/rtio.py +++ b/artiq/coredevice/rtio.py @@ -180,6 +180,15 @@ class RTIOIn(_RTIOBase): delay(duration) self._set_value(0) + @kernel + def pileup_count(self): + """Returns the number of pileup events (a system clock cycle with too + many input transitions) since the last call to this function for this + channel (or since the last RTIO reset). + + """ + return syscall("rtio_pileup_count", self.channel) + @kernel def count(self): """Poll the RTIO input during all the previously programmed gate diff --git a/artiq/coredevice/runtime.py b/artiq/coredevice/runtime.py index 8d305def1..896b5abe8 100644 --- a/artiq/coredevice/runtime.py +++ b/artiq/coredevice/runtime.py @@ -18,6 +18,7 @@ _syscalls = { "rtio_replace": "Iii:n", "rtio_sync": "i:n", "rtio_get": "i:I", + "rtio_pileup_count": "i:i", "dds_program": "iiI:n", } diff --git a/soc/artiqlib/rtio/core.py b/soc/artiqlib/rtio/core.py index 54f03f76a..1d7086851 100644 --- a/soc/artiqlib/rtio/core.py +++ b/soc/artiqlib/rtio/core.py @@ -71,7 +71,8 @@ class _RTIOBankI(Module): self.readable = Signal() self.re = Signal() self.overflow = Signal() - self.pileup = Signal() + self.pileup_count = Signal(16) + self.pileup_reset = Signal() # # # @@ -79,7 +80,7 @@ class _RTIOBankI(Module): values = [] readables = [] overflows = [] - pileups = [] + pileup_counts = [] for n, chif in enumerate(rbus): if hasattr(chif, "oe"): sensitivity = Signal(2) @@ -115,22 +116,29 @@ class _RTIOBankI(Module): self.sync += If(fifo.we & ~fifo.writable, overflow.eq(1)) overflows.append(overflow) - pileup = Signal() - self.sync += If(chif.i_pileup, pileup.eq(1)) - pileups.append(pileup) + pileup_count = Signal(16) + self.sync += \ + If(self.pileup_reset & (self.sel == n), + pileup_count.eq(0) + ).Elif(chif.i_pileup, + If(pileup_count != 2**16 - 1, # saturate + pileup_count.eq(pileup_count + 1) + ) + ) + pileup_counts.append(pileup_count) else: timestamps.append(0) values.append(0) readables.append(0) overflows.append(0) - pileups.append(0) + pileup_counts.append(0) self.comb += [ self.timestamp.eq(Array(timestamps)[self.sel]), self.value.eq(Array(values)[self.sel]), self.readable.eq(Array(readables)[self.sel]), self.overflow.eq(Array(overflows)[self.sel]), - self.pileup.eq(Array(pileups)[self.sel]) + self.pileup_count.eq(Array(pileup_counts)[self.sel]) ] @@ -171,14 +179,16 @@ class RTIO(Module, AutoCSR): self._r_o_writable = CSRStatus() self._r_o_we = CSR() self._r_o_replace = CSR() - self._r_o_error = CSRStatus() + self._r_o_underflow = CSRStatus() self._r_o_level = CSRStatus(bits_for(ofifo_depth)) 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_error = CSRStatus(2) + self._r_i_overflow = CSRStatus() + self._r_i_pileup_count = CSRStatus(16) + self._r_i_pileup_reset = CSR() self._r_counter = CSRStatus(counter_width+fine_ts_width) self._r_counter_update = CSR() @@ -209,7 +219,7 @@ class RTIO(Module, AutoCSR): 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_error.status.eq(self.bank_o.underflow), + self._r_o_underflow.status.eq(self.bank_o.underflow), self._r_o_level.status.eq(self.bank_o.level) ] @@ -221,8 +231,9 @@ class RTIO(Module, AutoCSR): 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_error.status.eq( - Cat(self.bank_i.overflow, self.bank_i.pileup)) + self._r_i_overflow.status.eq(self.bank_i.overflow), + self._r_i_pileup_count.status.eq(self.bank_i.pileup_count), + self.bank_i.pileup_reset.eq(self._r_i_pileup_reset.re) ] # Counter access diff --git a/soc/runtime/rtio.c b/soc/runtime/rtio.c index 0033a6ccd..07148a961 100644 --- a/soc/runtime/rtio.c +++ b/soc/runtime/rtio.c @@ -27,7 +27,7 @@ void rtio_set(long long int timestamp, int channel, int value) rtio_o_value_write(value); while(!rtio_o_writable_read()); rtio_o_we_write(1); - if(rtio_o_error_read()) { + if(rtio_o_underflow_read()) { rtio_reset_logic_write(1); rtio_reset_logic_write(0); exception_raise(EID_RTIO_UNDERFLOW); @@ -40,7 +40,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_error_read()) { + if(rtio_o_underflow_read()) { rtio_reset_logic_write(1); rtio_reset_logic_write(0); exception_raise(EID_RTIO_UNDERFLOW); @@ -68,6 +68,16 @@ long long int rtio_get(int channel) return -1; } +int rtio_pileup_count(int channel) +{ + int r; + + rtio_chan_sel_write(channel); + r = rtio_i_pileup_count_read(); + rtio_i_pileup_reset_write(1); + return r; +} + #define RTIO_FUD_CHANNEL 4 void rtio_fud_sync(void) @@ -96,7 +106,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_error_read()) { + if(rtio_o_underflow_read()) { rtio_reset_logic_write(1); rtio_reset_logic_write(0); exception_raise(EID_RTIO_UNDERFLOW); diff --git a/soc/runtime/rtio.h b/soc/runtime/rtio.h index 92a54674a..3cd3b4f7c 100644 --- a/soc/runtime/rtio.h +++ b/soc/runtime/rtio.h @@ -7,6 +7,7 @@ void rtio_set(long long int timestamp, int channel, int value); void rtio_replace(long long int timestamp, int channel, int value); void rtio_sync(int channel); long long int rtio_get(int channel); +int rtio_pileup_count(int channel); void rtio_fud_sync(void); void rtio_fud(long long int fud_time); diff --git a/soc/runtime/services.c b/soc/runtime/services.c index 3e191a5a1..d6edba503 100644 --- a/soc/runtime/services.c +++ b/soc/runtime/services.c @@ -16,6 +16,7 @@ static const struct symbol syscalls[] = { {"rtio_replace", rtio_replace}, {"rtio_sync", rtio_sync}, {"rtio_get", rtio_get}, + {"rtio_pileup_count", rtio_pileup_count}, {"dds_program", dds_program}, {NULL, NULL} };