artiq/artiq/gateware/drtio/core.py

146 lines
5.9 KiB
Python
Raw Normal View History

2016-10-14 00:34:59 +08:00
from types import SimpleNamespace
2016-10-10 23:12:12 +08:00
from migen import *
2017-01-16 03:44:43 +08:00
from migen.genlib.cdc import ElasticBuffer
2016-10-10 23:12:12 +08:00
2017-09-24 12:23:47 +08:00
from artiq.gateware.rtio.sed.core import *
from artiq.gateware.rtio.input_collector import *
from artiq.gateware.drtio import (link_layer, aux_controller,
2017-09-24 12:49:21 +08:00
rt_packet_satellite, rt_errors_satellite,
2017-09-24 12:23:47 +08:00
rt_packet_master, rt_controller_master)
2016-10-10 23:12:12 +08:00
2017-07-18 13:27:33 +08:00
class ChannelInterface:
def __init__(self, encoder, decoders):
self.rx_ready = Signal()
self.encoder = encoder
self.decoders = decoders
class TransceiverInterface:
def __init__(self, channel_interfaces):
self.clock_domains.cd_rtio = ClockDomain()
for i in range(len(channel_interfaces)):
name = "rtio_rx" + str(i)
setattr(self.clock_domains, "cd_"+name, ClockDomain(name=name))
self.channels = channel_interfaces
2017-01-16 03:44:43 +08:00
class GenericRXSynchronizer(Module):
"""Simple RX synchronizer based on the portable Migen elastic buffer.
Introduces timing non-determinism in the satellite -> master path,
(and in the echo_request/echo_reply RTT) but useful for testing.
"""
def __init__(self):
self.signals = []
def resync(self, signal):
synchronized = Signal.like(signal, related=signal)
self.signals.append((signal, synchronized))
return synchronized
def do_finalize(self):
eb = ElasticBuffer(sum(len(s[0]) for s in self.signals), 4, "rtio_rx", "rtio")
self.submodules += eb
self.comb += [
eb.din.eq(Cat(*[s[0] for s in self.signals])),
Cat(*[s[1] for s in self.signals]).eq(eb.dout)
]
2016-10-10 23:12:12 +08:00
class DRTIOSatellite(Module):
2017-09-24 12:23:47 +08:00
def __init__(self, chanif, channels, rx_synchronizer=None, fine_ts_width=3,
lane_count=8, fifo_depth=128):
2017-01-16 03:44:43 +08:00
if rx_synchronizer is None:
rx_synchronizer = GenericRXSynchronizer()
self.submodules += rx_synchronizer
2016-10-10 23:12:12 +08:00
self.submodules.link_layer = link_layer.LinkLayer(
2017-07-18 13:27:33 +08:00
chanif.encoder, chanif.decoders)
self.comb += self.link_layer.rx_ready.eq(chanif.rx_ready)
2016-10-15 18:36:27 +08:00
2016-10-14 00:34:59 +08:00
link_layer_sync = SimpleNamespace(
2016-10-17 19:23:08 +08:00
tx_aux_frame=self.link_layer.tx_aux_frame,
2016-10-14 00:34:59 +08:00
tx_aux_data=self.link_layer.tx_aux_data,
tx_aux_ack=self.link_layer.tx_aux_ack,
tx_rt_frame=self.link_layer.tx_rt_frame,
tx_rt_data=self.link_layer.tx_rt_data,
2016-10-17 19:23:08 +08:00
rx_aux_stb=rx_synchronizer.resync(self.link_layer.rx_aux_stb),
rx_aux_frame=rx_synchronizer.resync(self.link_layer.rx_aux_frame),
2016-12-07 23:03:14 +08:00
rx_aux_frame_perm=rx_synchronizer.resync(self.link_layer.rx_aux_frame_perm),
2016-10-17 19:23:08 +08:00
rx_aux_data=rx_synchronizer.resync(self.link_layer.rx_aux_data),
rx_rt_frame=rx_synchronizer.resync(self.link_layer.rx_rt_frame),
2016-12-07 23:03:14 +08:00
rx_rt_frame_perm=rx_synchronizer.resync(self.link_layer.rx_rt_frame_perm),
2016-10-17 19:23:08 +08:00
rx_rt_data=rx_synchronizer.resync(self.link_layer.rx_rt_data)
2016-10-14 00:34:59 +08:00
)
2016-12-07 23:03:14 +08:00
self.submodules.link_stats = link_layer.LinkLayerStats(link_layer_sync, "rtio")
self.submodules.rt_packet = ClockDomainsRenamer("rtio")(
rt_packet_satellite.RTPacketSatellite(link_layer_sync))
2016-10-15 18:36:27 +08:00
2017-09-24 12:23:47 +08:00
coarse_ts = Signal(64 - fine_ts_width)
self.sync.rtio += \
If(self.rt_packet.tsc_load,
coarse_ts.eq(self.rt_packet.tsc_load_value)
).Else(
coarse_ts.eq(coarse_ts + 1)
)
self.comb += self.rt_packet.cri.counter.eq(coarse_ts << fine_ts_width)
self.submodules.outputs = ClockDomainsRenamer("rio")(
SED(channels, fine_ts_width, "sync",
lane_count=lane_count, fifo_depth=fifo_depth,
enable_spread=False, report_buffer_space=True,
interface=self.rt_packet.cri))
2017-09-24 12:23:47 +08:00
self.comb += self.outputs.coarse_timestamp.eq(coarse_ts)
self.sync += self.outputs.minimum_coarse_timestamp.eq(coarse_ts + 16)
self.submodules.inputs = ClockDomainsRenamer("rio")(
InputCollector(channels, fine_ts_width, "sync",
interface=self.rt_packet.cri))
self.comb += self.inputs.coarse_timestamp.eq(coarse_ts)
2016-10-10 23:12:12 +08:00
self.submodules.rt_errors = rt_errors_satellite.RTErrorsSatellite(
2017-09-24 12:23:47 +08:00
self.rt_packet, self.outputs)
2016-10-17 19:23:08 +08:00
self.clock_domains.cd_rio = ClockDomain()
self.clock_domains.cd_rio_phy = ClockDomain()
self.comb += [
self.cd_rio.clk.eq(ClockSignal("rtio")),
self.cd_rio.rst.eq(self.rt_packet.reset),
2016-10-17 19:23:08 +08:00
self.cd_rio_phy.clk.eq(ClockSignal("rtio")),
self.cd_rio_phy.rst.eq(self.rt_packet.reset_phy),
2016-10-17 19:23:08 +08:00
]
2016-11-14 17:20:47 +08:00
self.submodules.aux_controller = aux_controller.AuxController(
self.link_layer)
def get_csrs(self):
2016-12-07 23:03:14 +08:00
return (self.link_layer.get_csrs() + self.link_stats.get_csrs() +
self.rt_errors.get_csrs() + self.aux_controller.get_csrs())
2016-11-14 17:20:47 +08:00
2016-10-10 23:12:12 +08:00
class DRTIOMaster(Module):
2017-07-18 13:27:33 +08:00
def __init__(self, chanif, channel_count=1024, fine_ts_width=3):
2016-10-21 22:46:14 +08:00
self.submodules.link_layer = link_layer.LinkLayer(
2017-07-18 13:27:33 +08:00
chanif.encoder, chanif.decoders)
self.comb += self.link_layer.rx_ready.eq(chanif.rx_ready)
2016-12-07 23:03:14 +08:00
self.submodules.link_stats = link_layer.LinkLayerStats(self.link_layer, "rtio_rx")
self.submodules.rt_packet = rt_packet_master.RTPacketMaster(self.link_layer)
self.submodules.rt_controller = rt_controller_master.RTController(
self.rt_packet, channel_count, fine_ts_width)
self.submodules.rt_manager = rt_controller_master.RTManager(self.rt_packet)
2016-11-22 22:46:50 +08:00
self.cri = self.rt_controller.cri
2016-10-24 19:50:13 +08:00
2016-11-14 17:20:47 +08:00
self.submodules.aux_controller = aux_controller.AuxController(
self.link_layer)
2016-10-24 19:50:13 +08:00
def get_csrs(self):
return (self.link_layer.get_csrs() +
2016-12-07 23:03:14 +08:00
self.link_stats.get_csrs() +
self.rt_controller.get_csrs() +
2016-11-14 17:20:47 +08:00
self.rt_manager.get_csrs() +
self.aux_controller.get_csrs())