From 018f6d1b5227114e906bb0bb403bf9363c496bde Mon Sep 17 00:00:00 2001 From: Sebastien Bourdeauducq Date: Tue, 11 Oct 2016 17:59:22 +0800 Subject: [PATCH] drtio: implement basic IOT --- artiq/gateware/drtio/core.py | 4 +- artiq/gateware/drtio/iot.py | 71 +++++++++++++++++++++++++++++++++++- 2 files changed, 71 insertions(+), 4 deletions(-) diff --git a/artiq/gateware/drtio/core.py b/artiq/gateware/drtio/core.py index d8bd1d165..1063822d4 100644 --- a/artiq/gateware/drtio/core.py +++ b/artiq/gateware/drtio/core.py @@ -4,13 +4,13 @@ from artiq.gateware.drtio import link_layer, rt_packets, iot class DRTIOSatellite(Module): - def __init__(self, transceiver, channels, full_ts_width=63, fine_ts_width=3): + def __init__(self, transceiver, channels, fine_ts_width=3, full_ts_width=63): self.submodules.link_layer = link_layer.LinkLayer( transceiver.encoder, transceiver.decoders) self.submodules.rt_packets = rt_packets.RTPacketSatellite( self.link_layer) self.submodules.iot = iot.IOT( - self.rt_packets, channels, full_ts_width, fine_ts_width) + self.rt_packets, channels, fine_ts_width, full_ts_width) class DRTIOMaster(Module): diff --git a/artiq/gateware/drtio/iot.py b/artiq/gateware/drtio/iot.py index 93e008796..5416893fa 100644 --- a/artiq/gateware/drtio/iot.py +++ b/artiq/gateware/drtio/iot.py @@ -1,9 +1,76 @@ from migen import * from migen.genlib.fifo import SyncFIFOBuffered +from migen.genlib.record import * from artiq.gateware.rtio import rtlink class IOT(Module): - def __init__(self, rt_packets, channels, full_ts_width, fine_ts_width): - pass + def __init__(self, rt_packets, channels, max_fine_ts_width, full_ts_width): + tsc = Signal(full_ts_width - max_fine_ts_width) + self.sync += \ + If(rt_packets.tsc_load, + tsc.eq(rt_packets.tsc_value) + ).Else( + tsc.eq(tsc + 1) + ) + + for n, channel in enumerate(channels): + data_width = rtlink.get_data_width(channel.interface) + address_width = rtlink.get_address_width(channel.interface) + fine_ts_width = rtlink.get_fine_ts_width(channel.interface) + assert fine_ts_width <= max_fine_ts_width + + # FIFO + ev_layout = [] + if data_width: + ev_layout.append(("data", data_width)) + if address_width: + ev_layout.append(("address", address_width)) + ev_layout.append(("timestamp", len(tsc) + fine_ts_width)) + + fifo = SyncFIFOBuffered(layout_len(ev_layout), channel.ofifo_depth) + self.submodules += fifo + fifo_in = Record(ev_layout) + fifo_out = Record(ev_layout) + self.comb += [ + fifo.din.eq(fifo_in.raw_bits()), + fifo_out.raw_bits().eq(fifo.dout) + ] + + # FIFO write + self.comb += fifo.we.eq(rt_packets.write_stb) + self.sync += \ + If(rt_packets.write_stb, + If(rt_packets.write_overflow_ack, + rt_packets.write_overflow.eq(0)), + If(~fifo.writable, rt_packets.write_overflow.eq(1)), + If(rt_packets.write_underflow_ack, + rt_packets.write_underflow.eq(0)), + If(rt_packets.timestamp[max_fine_ts_width:] < (tsc + 4), + rt_packets.write_underflow.eq(1) + ) + ) + if data_width: + self.comb += fifo_in.data.eq(rt_packets.write_data) + if address_width: + self.comb += fifo_in.address.eq(rt_packets.write_address) + self.comb += fifo_in.timestamp.eq( + rt_packets.timestamp[max_fine_ts_width-fine_ts_width:]) + + # FIFO read + self.sync += [ + fifo.re.eq(0), + interface.stb.eq(0), + If(fifo.readable & + (fifo_out.timestamp[fine_ts_width:] == tsc), + fifo.re.eq(1), + interface.stb.eq(1) + ) + ] + if data_width: + self.sync += interface.data.eq(fifo_out.data) + if address_width: + self.sync += interface.address.eq(fifo_out.address) + if fine_ts_width: + self.sync += interface.fine_ts.eq(fifo_out.timestamp[:fine_ts_width])