From cdda1beea80d4c66d97b980c1184a5fb9c1aa613 Mon Sep 17 00:00:00 2001 From: Sebastien Bourdeauducq Date: Mon, 21 Jul 2014 13:17:21 -0600 Subject: [PATCH] soc/rtio: refactor, share counter and underflow detector --- soc/artiqlib/rtio/__init__.py | 90 +++++++++++++++++++---------------- 1 file changed, 50 insertions(+), 40 deletions(-) diff --git a/soc/artiqlib/rtio/__init__.py b/soc/artiqlib/rtio/__init__.py index 89e6b2166..5a73a6e20 100644 --- a/soc/artiqlib/rtio/__init__.py +++ b/soc/artiqlib/rtio/__init__.py @@ -3,41 +3,59 @@ from migen.bank.description import * from migen.genlib.fifo import SyncFIFOBuffered from migen.genlib.cdc import MultiReg -class RTIOChannelO(Module): - def __init__(self, signal, counter_width, fifo_depth): - self.submodules.fifo = SyncFIFOBuffered([ - ("timestamp", counter_width), ("value", 1)], - fifo_depth) - - self.event = self.fifo.din - self.writable = self.fifo.writable - self.we = self.fifo.we +class RTIOBankO(Module): + def __init__(self, channels, counter_width, fifo_depth): + self.sel = Signal(max=len(channels)) + self.timestamp = Signal(counter_width) + self.value = Signal() + self.writable = Signal() + self.we = Signal() self.underflow = Signal() - self.level = self.fifo.level + self.level = Signal(bits_for(fifo_depth)) ### counter = Signal(counter_width) - self.sync += counter.eq(counter + 1) - - self.sync += If(self.we & self.writable, - If(self.event.timestamp < counter + 2, - self.underflow.eq(1) + self.sync += [ + counter.eq(counter + 1), + If(self.we & self.writable, + If(self.timestamp < counter + 2, self.underflow.eq(1)) ) - ) - - time_hit = Signal() - self.comb += [ - time_hit.eq(self.fifo.readable & - (self.fifo.dout.timestamp == counter)), - self.fifo.re.eq(time_hit) ] - self.sync += If(time_hit, signal.eq(self.fifo.dout.value)) + + fifos = [] + for n, channel in enumerate(channels): + fifo = SyncFIFOBuffered([ + ("timestamp", counter_width), ("value", 1)], + fifo_depth) + self.submodules += fifo + fifos.append(fifo) + + # FIFO write + self.comb += [ + fifo.din.timestamp.eq(self.timestamp), + fifo.din.value.eq(self.value), + fifo.we.eq(self.we & (self.sel == n)) + ] + + # FIFO read + time_hit = Signal() + self.comb += [ + time_hit.eq(fifo.readable & + (fifo.dout.timestamp == counter)), + fifo.re.eq(time_hit) + ] + self.sync += If(time_hit, channel.eq(fifo.dout.value)) + + selfifo = Array(fifos)[self.sel] + self.comb += self.writable.eq(selfifo.writable), self.level.eq(selfifo.level) class RTIO(Module, AutoCSR): def __init__(self, channels, counter_width=32, ofifo_depth=8, ififo_depth=8): + self.submodules.bank_o = InsertReset(RTIOBankO(channels, counter_width, ofifo_depth)) + self._r_reset = CSRStorage(reset=1) - self._r_chan_sel = CSRStorage(bits_for(len(channels)-1)) + self._r_chan_sel = CSRStorage(flen(self.bank_o.sel)) self._r_o_timestamp = CSRStorage(counter_width) self._r_o_value = CSRStorage() self._r_o_writable = CSRStatus() @@ -45,21 +63,13 @@ class RTIO(Module, AutoCSR): self._r_o_underflow = CSRStatus() self._r_o_level = CSRStatus(bits_for(ofifo_depth)) - channel_os = [] - for n, channel in enumerate(channels): - channel_o = InsertReset(RTIOChannelO(channel, counter_width, ofifo_depth)) - self.submodules += channel_o - channel_os.append(channel_o) - self.comb += [ - channel_o.reset.eq(self._r_reset.storage), - channel_o.event.timestamp.eq(self._r_o_timestamp.storage), - channel_o.event.value.eq(self._r_o_value.storage), - channel_o.we.eq(self._r_o_we.re & (self._r_chan_sel.storage == n)) - ] - - channel_o = Array(channel_os)[self._r_chan_sel.storage] self.comb += [ - self._r_o_writable.status.eq(channel_o.writable), - self._r_o_underflow.status.eq(channel_o.underflow), - self._r_o_level.status.eq(channel_o.level) + self.bank_o.reset.eq(self._r_reset.storage), + 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._r_o_underflow.status.eq(self.bank_o.underflow), + self._r_o_level.status.eq(self.bank_o.level) ]