mirror of
https://github.com/m-labs/artiq.git
synced 2024-12-26 11:48:27 +08:00
rtio/sed: take global fine TS width
This commit is contained in:
parent
65baca8c57
commit
81d6317053
@ -1,6 +1,5 @@
|
||||
from migen import *
|
||||
|
||||
from artiq.gateware.rtio import rtlink
|
||||
from artiq.gateware.rtio.sed import layouts
|
||||
from artiq.gateware.rtio.sed.lane_distributor import *
|
||||
from artiq.gateware.rtio.sed.fifos import *
|
||||
@ -12,7 +11,8 @@ __all__ = ["SED"]
|
||||
|
||||
|
||||
class SED(Module):
|
||||
def __init__(self, channels, mode, lane_count=8, fifo_depth=128, enable_spread=True,
|
||||
def __init__(self, channels, glbl_fine_ts_width, mode,
|
||||
lane_count=8, fifo_depth=128, enable_spread=True,
|
||||
quash_channels=[], interface=None):
|
||||
if mode == "sync":
|
||||
lane_dist_cdr = lambda x: x
|
||||
@ -27,13 +27,11 @@ class SED(Module):
|
||||
else:
|
||||
raise ValueError
|
||||
|
||||
fine_ts_width = max(rtlink.get_fine_ts_width(c.interface.o)
|
||||
for c in channels)
|
||||
seqn_width = layouts.seqn_width(lane_count, fifo_depth)
|
||||
|
||||
self.submodules.lane_dist = lane_dist_cdr(
|
||||
LaneDistributor(lane_count, seqn_width,
|
||||
layouts.fifo_payload(channels), fine_ts_width,
|
||||
layouts.fifo_payload(channels), glbl_fine_ts_width,
|
||||
enable_spread=enable_spread,
|
||||
quash_channels=quash_channels,
|
||||
interface=interface))
|
||||
@ -43,9 +41,9 @@ class SED(Module):
|
||||
self.submodules.gates = gates_cdr(
|
||||
Gates(lane_count, seqn_width,
|
||||
layouts.fifo_payload(channels),
|
||||
layouts.output_network_payload(channels)))
|
||||
layouts.output_network_payload(channels, glbl_fine_ts_width)))
|
||||
self.submodules.output_driver = output_driver_cdr(
|
||||
OutputDriver(channels, lane_count, seqn_width))
|
||||
OutputDriver(channels, glbl_fine_ts_width, lane_count, seqn_width))
|
||||
|
||||
for o, i in zip(self.lane_dist.output, self.fifos.input):
|
||||
self.comb += o.connect(i)
|
||||
|
@ -14,18 +14,18 @@ class Gates(Module):
|
||||
for _ in range(lane_count)]
|
||||
|
||||
if hasattr(self.output[0].payload, "fine_ts"):
|
||||
fine_ts_width = len(self.output[0].payload.fine_ts)
|
||||
glbl_fine_ts_width = len(self.output[0].payload.fine_ts)
|
||||
else:
|
||||
fine_ts_width = 0
|
||||
glbl_fine_ts_width = 0
|
||||
|
||||
self.coarse_timestamp = Signal(64-fine_ts_width)
|
||||
self.coarse_timestamp = Signal(64-glbl_fine_ts_width)
|
||||
|
||||
# # #
|
||||
|
||||
for input, output in zip(self.input, self.output):
|
||||
for field, _ in output.payload.layout:
|
||||
if field == "fine_ts":
|
||||
self.sync += output.payload.fine_ts.eq(input.payload.timestamp[:fine_ts_width])
|
||||
self.sync += output.payload.fine_ts.eq(input.payload.timestamp[:glbl_fine_ts_width])
|
||||
else:
|
||||
self.sync += getattr(output.payload, field).eq(getattr(input.payload, field))
|
||||
self.sync += output.seqn.eq(input.seqn)
|
||||
@ -34,5 +34,5 @@ class Gates(Module):
|
||||
output.nondata_replace_occured.eq(0)
|
||||
]
|
||||
|
||||
self.comb += input.re.eq(input.payload.timestamp[fine_ts_width:] == self.coarse_timestamp)
|
||||
self.comb += input.re.eq(input.payload.timestamp[glbl_fine_ts_width:] == self.coarse_timestamp)
|
||||
self.sync += output.valid.eq(input.re & input.readable)
|
||||
|
@ -13,7 +13,7 @@ __all__ = ["LaneDistributor"]
|
||||
# 3. check status
|
||||
|
||||
class LaneDistributor(Module):
|
||||
def __init__(self, lane_count, seqn_width, layout_payload, fine_ts_width,
|
||||
def __init__(self, lane_count, seqn_width, layout_payload, glbl_fine_ts_width,
|
||||
enable_spread=True, quash_channels=[], interface=None):
|
||||
if lane_count & (lane_count - 1):
|
||||
raise NotImplementedError("lane count must be a power of 2")
|
||||
@ -21,7 +21,7 @@ class LaneDistributor(Module):
|
||||
if interface is None:
|
||||
interface = cri.Interface()
|
||||
self.cri = interface
|
||||
self.minimum_coarse_timestamp = Signal(64-fine_ts_width)
|
||||
self.minimum_coarse_timestamp = Signal(64-glbl_fine_ts_width)
|
||||
self.output = [Record(layouts.fifo_ingress(seqn_width, layout_payload))
|
||||
for _ in range(lane_count)]
|
||||
|
||||
@ -35,8 +35,8 @@ class LaneDistributor(Module):
|
||||
|
||||
# internal state
|
||||
current_lane = Signal(max=lane_count)
|
||||
last_coarse_timestamp = Signal(64-fine_ts_width)
|
||||
last_lane_coarse_timestamps = Array(Signal(64-fine_ts_width)
|
||||
last_coarse_timestamp = Signal(64-glbl_fine_ts_width)
|
||||
last_lane_coarse_timestamps = Array(Signal(64-glbl_fine_ts_width)
|
||||
for _ in range(lane_count))
|
||||
seqn = Signal(seqn_width)
|
||||
|
||||
@ -53,8 +53,8 @@ class LaneDistributor(Module):
|
||||
self.comb += lio.payload.data.eq(self.cri.o_data)
|
||||
|
||||
# when timestamp and channel arrive in cycle #1, prepare computations
|
||||
coarse_timestamp = Signal(64-fine_ts_width)
|
||||
self.comb += coarse_timestamp.eq(self.cri.timestamp[fine_ts_width:])
|
||||
coarse_timestamp = Signal(64-glbl_fine_ts_width)
|
||||
self.comb += coarse_timestamp.eq(self.cri.timestamp[glbl_fine_ts_width:])
|
||||
timestamp_above_min = Signal()
|
||||
timestamp_above_laneA_min = Signal()
|
||||
timestamp_above_laneB_min = Signal()
|
||||
|
@ -45,17 +45,20 @@ def fifo_egress(seqn_width, layout_payload):
|
||||
]
|
||||
|
||||
|
||||
def output_network_payload(channels):
|
||||
fine_ts_width = max(rtlink.get_fine_ts_width(channel.interface.o)
|
||||
for channel in channels)
|
||||
# We use glbl_fine_ts_width in the output network so that collisions due
|
||||
# to insufficiently increasing timestamps are always reliably detected.
|
||||
# We can still have undetected collisions on the address by making it wrap
|
||||
# around, but those are more rare and easier to debug, and addresses are
|
||||
# not normally exposed directly to the ARTIQ user.
|
||||
def output_network_payload(channels, glbl_fine_ts_width):
|
||||
address_width = max(rtlink.get_address_width(channel.interface.o)
|
||||
for channel in channels)
|
||||
data_width = max(rtlink.get_data_width(channel.interface.o)
|
||||
for channel in channels)
|
||||
|
||||
layout = [("channel", bits_for(len(channels)-1))]
|
||||
if fine_ts_width:
|
||||
layout.append(("fine_ts", fine_ts_width))
|
||||
if glbl_fine_ts_width:
|
||||
layout.append(("fine_ts", glbl_fine_ts_width))
|
||||
if address_width:
|
||||
layout.append(("address", address_width))
|
||||
if data_width:
|
||||
|
@ -11,14 +11,14 @@ __all__ = ["OutputDriver"]
|
||||
|
||||
|
||||
class OutputDriver(Module):
|
||||
def __init__(self, channels, lane_count, seqn_width):
|
||||
def __init__(self, channels, glbl_fine_ts_width, lane_count, seqn_width):
|
||||
self.collision = Signal()
|
||||
self.collision_channel = Signal(max=len(channels))
|
||||
self.busy = Signal()
|
||||
self.busy_channel = Signal(max=len(channels))
|
||||
|
||||
# output network
|
||||
layout_on_payload = layouts.output_network_payload(channels)
|
||||
layout_on_payload = layouts.output_network_payload(channels, glbl_fine_ts_width)
|
||||
output_network = OutputNetwork(lane_count, seqn_width, layout_on_payload)
|
||||
self.submodules += output_network
|
||||
self.input = output_network.input
|
||||
|
@ -37,7 +37,7 @@ class DUT(Module):
|
||||
]
|
||||
|
||||
self.submodules.output_driver = output_driver.OutputDriver(
|
||||
rtio_channels, LANE_COUNT, 4*LANE_COUNT)
|
||||
rtio_channels, 0, LANE_COUNT, 4*LANE_COUNT)
|
||||
|
||||
|
||||
def simulate(input_events):
|
||||
|
@ -22,7 +22,7 @@ class DUT(Module):
|
||||
rtio.Channel.from_phy(self.phy1)
|
||||
]
|
||||
|
||||
self.submodules.sed = SED(rtio_channels, "sync")
|
||||
self.submodules.sed = SED(rtio_channels, 0, "sync")
|
||||
self.sync += [
|
||||
self.sed.coarse_timestamp.eq(self.sed.coarse_timestamp + 1),
|
||||
self.sed.minimum_coarse_timestamp.eq(self.sed.coarse_timestamp + 16)
|
||||
|
Loading…
Reference in New Issue
Block a user