mirror of https://github.com/m-labs/artiq.git
rtio/sed: add FIFO wrapper
This commit is contained in:
parent
490c9815a2
commit
8e5ab90129
|
@ -0,0 +1,37 @@
|
||||||
|
from migen import *
|
||||||
|
from migen.genlib.fifo import *
|
||||||
|
|
||||||
|
from artiq.gateware.rtio.sed import layouts
|
||||||
|
|
||||||
|
|
||||||
|
__all__ = ["FIFO"]
|
||||||
|
|
||||||
|
|
||||||
|
class FIFO(Module):
|
||||||
|
def __init__(self, lane_count, mode, fifo_depth, layout_payload):
|
||||||
|
seqn_width = layouts.seqn_width(lane_count, fifo_width)
|
||||||
|
self.input = [layouts.fifo_ingress(seqn_width, layout_payload)
|
||||||
|
for _ in range(lane_count)]
|
||||||
|
self.output = [layouts.fifo_egress(seqn_width, layout_payload)
|
||||||
|
for _ in range(lane_count)]
|
||||||
|
|
||||||
|
if mode == "sync":
|
||||||
|
fifo_cls = fifo.SyncFIFOBuffered
|
||||||
|
elif mode == "async":
|
||||||
|
fifo_cls = fifo.AsyncFIFO
|
||||||
|
else:
|
||||||
|
raise ValueError
|
||||||
|
|
||||||
|
for input, output in zip(self.input, self.output):
|
||||||
|
fifo = fifo_cls(layout_len(layout_payload), fifo_depth)
|
||||||
|
self.submodules += fifo
|
||||||
|
|
||||||
|
self.comb += [
|
||||||
|
fifo.din.eq(input.payload.raw_bits()),
|
||||||
|
fifo.we.eq(input.we),
|
||||||
|
input.writable.eq(fifo.writable),
|
||||||
|
|
||||||
|
output.payload.raw_bits().eq(fifo.dout),
|
||||||
|
output.readable.eq(fifo.readable),
|
||||||
|
fifo.re.eq(output.re)
|
||||||
|
]
|
|
@ -14,14 +14,10 @@ __all__ = ["LaneDistributor"]
|
||||||
# 3. check status
|
# 3. check status
|
||||||
|
|
||||||
class LaneDistributor(Module):
|
class LaneDistributor(Module):
|
||||||
def __init__(self, lane_count, fifo_size, layout_payload, fine_ts_width, enable_spread=True):
|
def __init__(self, lane_count, seqn_width, layout_payload, fine_ts_width, enable_spread=True):
|
||||||
if lane_count & (lane_count - 1):
|
if lane_count & (lane_count - 1):
|
||||||
raise NotImplementedError("lane count must be a power of 2")
|
raise NotImplementedError("lane count must be a power of 2")
|
||||||
|
|
||||||
# There must be a unique sequence number for every possible event in every FIFO.
|
|
||||||
# Plus 2 bits to detect and handle wraparounds.
|
|
||||||
seqn_width = bits_for(lane_count*fifo_size-1) + 2
|
|
||||||
|
|
||||||
self.cri = cri.Interface()
|
self.cri = cri.Interface()
|
||||||
self.minimum_coarse_timestamp = Signal(64-fine_ts_width)
|
self.minimum_coarse_timestamp = Signal(64-fine_ts_width)
|
||||||
self.lane_io = [Record(layouts.fifo_ingress(seqn_width, layout_payload))
|
self.lane_io = [Record(layouts.fifo_ingress(seqn_width, layout_payload))
|
||||||
|
|
|
@ -21,6 +21,12 @@ def fifo_payload(channels):
|
||||||
return layout
|
return layout
|
||||||
|
|
||||||
|
|
||||||
|
def seqn_width(lane_count, fifo_width):
|
||||||
|
# There must be a unique sequence number for every possible event in every FIFO.
|
||||||
|
# Plus 2 bits to detect and handle wraparounds.
|
||||||
|
return bits_for(lane_count*fifo_size-1) + 2
|
||||||
|
|
||||||
|
|
||||||
def fifo_ingress(seqn_width, layout_payload):
|
def fifo_ingress(seqn_width, layout_payload):
|
||||||
return [
|
return [
|
||||||
("we", 1, DIR_M_TO_S),
|
("we", 1, DIR_M_TO_S),
|
||||||
|
|
|
@ -10,7 +10,7 @@ LANE_COUNT = 8
|
||||||
|
|
||||||
|
|
||||||
def simulate(input_events, wait=True):
|
def simulate(input_events, wait=True):
|
||||||
dut = lane_distributor.LaneDistributor(LANE_COUNT, 16, [("channel", 8), ("timestamp", 32)], 3)
|
dut = lane_distributor.LaneDistributor(LANE_COUNT, 8, [("channel", 8), ("timestamp", 32)], 3)
|
||||||
|
|
||||||
output = []
|
output = []
|
||||||
access_results = []
|
access_results = []
|
||||||
|
|
Loading…
Reference in New Issue