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-03-07 00:46:59 +08:00
|
|
|
from artiq.gateware.drtio import (link_layer, aux_controller,
|
|
|
|
rt_packet_satellite, rt_ios_satellite,
|
|
|
|
rt_packet_master, rt_controller_master)
|
2016-10-10 23:12:12 +08:00
|
|
|
|
|
|
|
|
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-01-16 03:44:43 +08:00
|
|
|
def __init__(self, transceiver, channels, rx_synchronizer=None, fine_ts_width=3, full_ts_width=63):
|
|
|
|
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(
|
2016-11-17 22:32:39 +08:00
|
|
|
transceiver.encoder, transceiver.decoders)
|
2016-11-19 10:46:56 +08:00
|
|
|
self.comb += self.link_layer.rx_ready.eq(transceiver.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")
|
2017-03-07 00:46:59 +08:00
|
|
|
self.submodules.rt_packet = ClockDomainsRenamer("rtio")(
|
|
|
|
rt_packet_satellite.RTPacketSatellite(link_layer_sync))
|
2016-10-15 18:36:27 +08:00
|
|
|
|
2017-03-07 00:46:59 +08:00
|
|
|
self.submodules.ios = rt_ios_satellite.IOS(
|
|
|
|
self.rt_packet, channels, fine_ts_width, full_ts_width)
|
2016-10-10 23:12:12 +08:00
|
|
|
|
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")),
|
2017-03-07 00:46:59 +08:00
|
|
|
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")),
|
2017-03-07 00:46:59 +08:00
|
|
|
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.aux_controller.get_csrs())
|
2016-11-14 17:20:47 +08:00
|
|
|
|
2016-10-10 23:12:12 +08:00
|
|
|
|
|
|
|
class DRTIOMaster(Module):
|
2016-11-17 22:32:39 +08:00
|
|
|
def __init__(self, transceiver, channel_count=1024, fine_ts_width=3):
|
2016-10-21 22:46:14 +08:00
|
|
|
self.submodules.link_layer = link_layer.LinkLayer(
|
2016-11-17 22:32:39 +08:00
|
|
|
transceiver.encoder, transceiver.decoders)
|
2016-11-19 10:46:56 +08:00
|
|
|
self.comb += self.link_layer.rx_ready.eq(transceiver.rx_ready)
|
|
|
|
|
2016-12-07 23:03:14 +08:00
|
|
|
self.submodules.link_stats = link_layer.LinkLayerStats(self.link_layer, "rtio_rx")
|
2017-03-07 00:46:59 +08:00
|
|
|
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):
|
2016-11-04 19:38:24 +08:00
|
|
|
return (self.link_layer.get_csrs() +
|
2016-12-07 23:03:14 +08:00
|
|
|
self.link_stats.get_csrs() +
|
2016-11-04 19:38:24 +08:00
|
|
|
self.rt_controller.get_csrs() +
|
2016-11-14 17:20:47 +08:00
|
|
|
self.rt_manager.get_csrs() +
|
|
|
|
self.aux_controller.get_csrs())
|