forked from M-Labs/artiq
drtio: expose internal satellite CRI
This commit is contained in:
parent
aa64e6c1c6
commit
ce6e390d5f
|
@ -1,2 +1,2 @@
|
||||||
from artiq.gateware.drtio.core import DRTIOSatellite, DRTIOMaster
|
from artiq.gateware.drtio.core import SyncRTIO, DRTIOSatellite, DRTIOMaster
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
)
|
)
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
# # #
|
# # #
|
||||||
|
|
||||||
|
|
|
@ -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:
|
||||||
|
|
Loading…
Reference in New Issue