diff --git a/artiq/gateware/drtio/rt_controller.py b/artiq/gateware/drtio/rt_controller.py index d718393da..28d00d1d2 100644 --- a/artiq/gateware/drtio/rt_controller.py +++ b/artiq/gateware/drtio/rt_controller.py @@ -25,6 +25,10 @@ class _CSRs(AutoCSR): self.err_present = CSR() self.err_code = CSRStatus(8) + self.dbg_update_packet_cnt = CSR() + self.dbg_packet_cnt_tx = CSRStatus(32) + self.dbg_packet_cnt_rx = CSRStatus(32) + class RTController(Module): def __init__(self, rt_packets, channel_count, fine_ts_width): @@ -156,6 +160,7 @@ class RTController(Module): ) ) + # channel state access self.comb += [ self.csrs.o_dbg_fifo_space.status.eq(fifo_spaces.dat_r), self.csrs.o_dbg_last_timestamp.status.eq(last_timestamps.dat_r), @@ -167,12 +172,20 @@ class RTController(Module): ) ] + # errors self.comb += [ self.csrs.err_present.w.eq(rt_packets.error_not), rt_packets.error_not_ack.eq(self.csrs.err_present.re), self.csrs.err_code.status.eq(rt_packets.error_code) ] + # packet counters + self.sync += \ + If(self.csrs.dbg_update_packet_cnt.re, + self.csrs.dbg_packet_cnt_tx.status.eq(rt_packets.packet_cnt_tx), + self.csrs.dbg_packet_cnt_rx.status.eq(rt_packets.packet_cnt_rx) + ) + def get_kernel_csrs(self): return self.kcsrs.get_csrs() diff --git a/artiq/gateware/drtio/rt_packets.py b/artiq/gateware/drtio/rt_packets.py index 84243e903..183bc913f 100644 --- a/artiq/gateware/drtio/rt_packets.py +++ b/artiq/gateware/drtio/rt_packets.py @@ -5,6 +5,8 @@ from migen.genlib.fsm import * from migen.genlib.fifo import AsyncFIFO from migen.genlib.cdc import PulseSynchronizer +from artiq.gateware.rtio.cdc import GrayCodeTransfer + def layout_len(l): return sum(e[1] for e in l) @@ -404,6 +406,10 @@ class RTPacketMaster(Module): self.error_not_ack = Signal() self.error_code = Signal(8) + # packet counters + self.packet_cnt_tx = Signal(32) + self.packet_cnt_rx = Signal(32) + # # # # CDC @@ -545,3 +551,33 @@ class RTPacketMaster(Module): fifo_space.eq(rx_dp.packet_as["fifo_space_reply"].space), NextState("INPUT") ) + + # packet counters + tx_frame_r = Signal() + packet_cnt_tx = Signal(32) + self.sync.rtio += [ + tx_frame_r.eq(link_layer.tx_rt_frame), + If(link_layer.tx_rt_frame & ~tx_frame_r, + packet_cnt_tx.eq(packet_cnt_tx + 1)) + ] + cdc_packet_cnt_tx = GrayCodeTransfer(32) + self.submodules += cdc_packet_cnt_tx + self.comb += [ + cdc_packet_cnt_tx.i.eq(packet_cnt_tx), + self.packet_cnt_tx.eq(cdc_packet_cnt_tx.o) + ] + + rx_frame_r = Signal() + packet_cnt_rx = Signal(32) + self.sync.rtio_rx += [ + rx_frame_r.eq(link_layer.rx_rt_frame), + If(link_layer.rx_rt_frame & ~rx_frame_r, + packet_cnt_rx.eq(packet_cnt_rx + 1)) + ] + cdc_packet_cnt_rx = ClockDomainsRenamer({"rtio": "rtio_rx"})( + GrayCodeTransfer(32)) + self.submodules += cdc_packet_cnt_rx + self.comb += [ + cdc_packet_cnt_rx.i.eq(packet_cnt_rx), + self.packet_cnt_rx.eq(cdc_packet_cnt_rx.o) + ]