forked from M-Labs/artiq
1
0
Fork 0

drtio: expose internal satellite CRI

This commit is contained in:
Sebastien Bourdeauducq 2018-08-30 12:41:09 +08:00
parent aa64e6c1c6
commit ce6e390d5f
5 changed files with 75 additions and 39 deletions

View File

@ -1,2 +1,2 @@
from artiq.gateware.drtio.core import DRTIOSatellite, DRTIOMaster from artiq.gateware.drtio.core import SyncRTIO, DRTIOSatellite, DRTIOMaster

View File

@ -5,6 +5,7 @@ from migen.genlib.resetsync import AsyncResetSynchronizer
from migen.genlib.cdc import PulseSynchronizer from migen.genlib.cdc import PulseSynchronizer
from misoc.interconnect.csr import * from misoc.interconnect.csr import *
from artiq.gateware.rtio import cri
from artiq.gateware.rtio.sed.core import * from artiq.gateware.rtio.sed.core import *
from artiq.gateware.rtio.input_collector import * from artiq.gateware.rtio.input_collector import *
from artiq.gateware.drtio import (link_layer, aux_controller, from artiq.gateware.drtio import (link_layer, aux_controller,
@ -13,6 +14,11 @@ from artiq.gateware.drtio import (link_layer, aux_controller,
from artiq.gateware.drtio.rx_synchronizer import GenericRXSynchronizer from artiq.gateware.drtio.rx_synchronizer import GenericRXSynchronizer
__all__ = ["ChannelInterface", "TransceiverInterface",
"SyncRTIO",
"DRTIOSatellite", "DRTIOMaster"]
class ChannelInterface: class ChannelInterface:
def __init__(self, encoder, decoders): def __init__(self, encoder, decoders):
self.rx_ready = Signal() self.rx_ready = Signal()
@ -30,12 +36,49 @@ class TransceiverInterface(AutoCSR):
self.channels = channel_interfaces self.channels = channel_interfaces
async_errors_layout = [
("sequence_error", 1),
("sequence_error_channel", 16),
("collision", 1),
("collision_channel", 16),
("busy", 1),
("busy_channel", 16)
]
class SyncRTIO(Module):
def __init__(self, channels, fine_ts_width=3, lane_count=8, fifo_depth=128):
self.cri = cri.Interface()
self.async_errors = Record(async_errors_layout)
self.coarse_ts = Signal(64 - fine_ts_width)
self.comb += self.cri.counter.eq(self.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.cri))
self.comb += self.outputs.coarse_timestamp.eq(self.coarse_ts)
self.sync.rtio += self.outputs.minimum_coarse_timestamp.eq(self.coarse_ts + 16)
self.submodules.inputs = ClockDomainsRenamer("rio")(
InputCollector(channels, fine_ts_width, "sync",
interface=self.cri))
self.comb += self.inputs.coarse_timestamp.eq(self.coarse_ts)
for attr, _ in async_errors_layout:
self.comb += getattr(self.async_errors, attr).eq(getattr(self.outputs, attr))
class DRTIOSatellite(Module): class DRTIOSatellite(Module):
def __init__(self, chanif, channels, rx_synchronizer=None, fine_ts_width=3, def __init__(self, chanif, rx_synchronizer=None, fine_ts_width=3):
lane_count=8, fifo_depth=128):
self.reset = CSRStorage(reset=1) self.reset = CSRStorage(reset=1)
self.reset_phy = CSRStorage(reset=1) self.reset_phy = CSRStorage(reset=1)
self.tsc_loaded = CSR() self.tsc_loaded = CSR()
# master interface in the rtio domain
self.cri = cri.Interface()
self.async_errors = Record(async_errors_layout)
self.clock_domains.cd_rio = ClockDomain() self.clock_domains.cd_rio = ClockDomain()
self.clock_domains.cd_rio_phy = ClockDomain() self.clock_domains.cd_rio_phy = ClockDomain()
@ -81,18 +124,16 @@ class DRTIOSatellite(Module):
) )
self.submodules.link_stats = link_layer.LinkLayerStats(link_layer_sync, "rtio") self.submodules.link_stats = link_layer.LinkLayerStats(link_layer_sync, "rtio")
self.submodules.rt_packet = ClockDomainsRenamer("rtio")( self.submodules.rt_packet = ClockDomainsRenamer("rtio")(
rt_packet_satellite.RTPacketSatellite(link_layer_sync)) rt_packet_satellite.RTPacketSatellite(link_layer_sync, interface=self.cri))
self.comb += self.rt_packet.reset.eq(self.cd_rio.rst) self.comb += self.rt_packet.reset.eq(self.cd_rio.rst)
coarse_ts = Signal(64 - fine_ts_width) self.coarse_ts = Signal(64 - fine_ts_width)
self.sync.rtio += \ self.sync.rtio += \
If(self.rt_packet.tsc_load, If(self.rt_packet.tsc_load,
coarse_ts.eq(self.rt_packet.tsc_load_value) self.coarse_ts.eq(self.rt_packet.tsc_load_value)
).Else( ).Else(
coarse_ts.eq(coarse_ts + 1) self.coarse_ts.eq(self.coarse_ts + 1)
) )
self.comb += self.rt_packet.cri.counter.eq(coarse_ts << fine_ts_width)
self.coarse_ts = coarse_ts
ps_tsc_load = PulseSynchronizer("rtio", "sys") ps_tsc_load = PulseSynchronizer("rtio", "sys")
self.submodules += ps_tsc_load self.submodules += ps_tsc_load
@ -102,21 +143,8 @@ class DRTIOSatellite(Module):
If(ps_tsc_load.o, self.tsc_loaded.w.eq(1)) If(ps_tsc_load.o, self.tsc_loaded.w.eq(1))
] ]
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))
self.comb += self.outputs.coarse_timestamp.eq(coarse_ts)
self.sync.rtio += 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)
self.submodules.rt_errors = rt_errors_satellite.RTErrorsSatellite( self.submodules.rt_errors = rt_errors_satellite.RTErrorsSatellite(
self.rt_packet, self.outputs) self.rt_packet, self.cri, self.async_errors)
self.submodules.aux_controller = aux_controller.AuxController( self.submodules.aux_controller = aux_controller.AuxController(
self.link_layer) self.link_layer)

View File

@ -7,7 +7,7 @@ from artiq.gateware.rtio.cdc import BlindTransfer
class RTErrorsSatellite(Module, AutoCSR): class RTErrorsSatellite(Module, AutoCSR):
def __init__(self, rt_packet, outputs): def __init__(self, rt_packet, cri, async_errors):
self.protocol_error = CSR(4) self.protocol_error = CSR(4)
self.underflow_channel = CSRStatus(16) self.underflow_channel = CSRStatus(16)
self.underflow_timestamp_event = CSRStatus(64) self.underflow_timestamp_event = CSRStatus(64)
@ -56,11 +56,11 @@ class RTErrorsSatellite(Module, AutoCSR):
underflow_error_cri = Signal(16+64+64) underflow_error_cri = Signal(16+64+64)
underflow_error_csr = Signal(16+64+64) underflow_error_csr = Signal(16+64+64)
self.comb += [ self.comb += [
underflow.eq(outputs.cri.o_status[1]), underflow.eq(cri.o_status[1]),
overflow.eq(outputs.cri.o_status[0]), overflow.eq(cri.o_status[0]),
underflow_error_cri.eq(Cat(outputs.cri.chan_sel[:16], underflow_error_cri.eq(Cat(cri.chan_sel[:16],
outputs.cri.timestamp, cri.timestamp,
outputs.cri.counter)), cri.counter)),
Cat(self.underflow_channel.status, Cat(self.underflow_channel.status,
self.underflow_timestamp_event.status, self.underflow_timestamp_event.status,
self.underflow_timestamp_counter.status).eq(underflow_error_csr) self.underflow_timestamp_counter.status).eq(underflow_error_csr)
@ -73,10 +73,10 @@ class RTErrorsSatellite(Module, AutoCSR):
) )
error_csr(self.rtio_error, error_csr(self.rtio_error,
(outputs.sequence_error, False, (async_errors.sequence_error, False,
outputs.sequence_error_channel, self.sequence_error_channel.status), async_errors.sequence_error_channel, self.sequence_error_channel.status),
(outputs.collision, False, (async_errors.collision, False,
outputs.collision_channel, self.collision_channel.status), async_errors.collision_channel, self.collision_channel.status),
(outputs.busy, False, (async_errors.busy, False,
outputs.busy_channel, self.busy_channel.status) async_errors.busy_channel, self.busy_channel.status)
) )

View File

@ -8,7 +8,7 @@ from artiq.gateware.drtio.rt_serializer import *
class RTPacketSatellite(Module): class RTPacketSatellite(Module):
def __init__(self, link_layer): def __init__(self, link_layer, interface=None):
self.reset = Signal() self.reset = Signal()
self.unknown_packet_type = Signal() self.unknown_packet_type = Signal()
@ -17,7 +17,9 @@ class RTPacketSatellite(Module):
self.tsc_load = Signal() self.tsc_load = Signal()
self.tsc_load_value = Signal(64) self.tsc_load_value = Signal(64)
self.cri = cri.Interface() if interface is None:
interface = cri.Interface()
self.cri = interface
# # # # # #

View File

@ -67,12 +67,18 @@ class DUT(Module):
rtio.Channel.from_phy(self.phy2), rtio.Channel.from_phy(self.phy2),
] ]
self.submodules.satellite = DRTIOSatellite( self.submodules.satellite = DRTIOSatellite(
self.transceivers.bob, rtio_channels, rx_synchronizer, self.transceivers.bob, rx_synchronizer, fine_ts_width=0)
lane_count=4, fifo_depth=8, fine_ts_width=0)
self.satellite.reset.storage.reset = 0 self.satellite.reset.storage.reset = 0
self.satellite.reset.storage_full.reset = 0 self.satellite.reset.storage_full.reset = 0
self.satellite.reset_phy.storage.reset = 0 self.satellite.reset_phy.storage.reset = 0
self.satellite.reset_phy.storage_full.reset = 0 self.satellite.reset_phy.storage_full.reset = 0
self.submodules.satellite_rtio = SyncRTIO(
rtio_channels, fine_ts_width=0, lane_count=4, fifo_depth=8)
self.comb += [
self.satellite_rtio.coarse_ts.eq(self.satellite.coarse_ts),
self.satellite.cri.connect(self.satellite_rtio.cri),
self.satellite.async_errors.eq(self.satellite_rtio.async_errors),
]
class OutputsTestbench: class OutputsTestbench: