phy/utils: add HoldValid stream primitive

This commit is contained in:
Jędrzej Boczar 2021-06-18 16:02:57 +02:00
parent 34fbe01a78
commit 405cf8a8a5
1 changed files with 36 additions and 4 deletions

View File

@ -13,6 +13,7 @@ from collections import defaultdict
from migen import * from migen import *
from litex.soc.interconnect import stream
from litex.soc.interconnect.csr import CSRStorage, AutoCSR from litex.soc.interconnect.csr import CSRStorage, AutoCSR
from litedram.common import TappedDelayLine, Settings from litedram.common import TappedDelayLine, Settings
@ -158,16 +159,16 @@ class SimulationPads(Module):
if pad.io: if pad.io:
o, i, oe = (f"{pad.name}_{suffix}" for suffix in ["o", "i", "oe"]) o, i, oe = (f"{pad.name}_{suffix}" for suffix in ["o", "i", "oe"])
setattr(self, pad.name, Signal(pad.width)) setattr(self, pad.name, Signal(pad.width))
setattr(self, o, Signal(pad.width)) setattr(self, o, Signal(pad.width, name=o))
setattr(self, i, Signal(pad.width)) setattr(self, i, Signal(pad.width, name=i))
setattr(self, oe, Signal()) setattr(self, oe, Signal(name=oe))
self.comb += If(getattr(self, oe), self.comb += If(getattr(self, oe),
getattr(self, pad.name).eq(getattr(self, o)) getattr(self, pad.name).eq(getattr(self, o))
).Else( ).Else(
getattr(self, pad.name).eq(getattr(self, i)) getattr(self, pad.name).eq(getattr(self, i))
) )
else: else:
setattr(self, pad.name, Signal(pad.width)) setattr(self, pad.name, Signal(pad.width, name=pad.name))
class CommandsPipeline(Module): class CommandsPipeline(Module):
@ -411,3 +412,34 @@ class SimLogger(Module, AutoCSR):
fmt = f"[%16d ps] {fmt}" fmt = f"[%16d ps] {fmt}"
args = (self.time_ps, *args) args = (self.time_ps, *args)
self.sync += If((level >= self.level) & cond, Display(fmt, *args)) self.sync += If((level >= self.level) & cond, Display(fmt, *args))
class HoldValid(Module):
"""Hold input data until ready
Acts more or less like PipeValid with 0 latency. Data on source becomes valid in the same
cycle on which it is valid on sink. In the next cycle the data is latched to a buffer and
the data from buffer is presented on source. After source.ready, it resets back to sink data.
"""
def __init__(self, layout):
self.sink = stream.Endpoint(layout)
self.buf = stream.Endpoint(layout)
self.source = stream.Endpoint(layout)
self.sync += [
If(self.buf.ready,
self.buf.valid.eq(0),
).Elif(self.sink.valid,
self.buf.valid.eq(1),
self.buf.payload.eq(self.sink.payload),
self.buf.param.eq(self.sink.param),
),
]
self.comb += [
If(self.buf.valid,
self.buf.connect(self.source),
).Else(
self.sink.connect(self.source),
),
]