soc/interconnect/stream: add separators, mode Actor modules just after Endpoint
authorFlorent Kermarrec <florent@enjoy-digital.fr>
Mon, 30 Sep 2019 21:18:39 +0000 (23:18 +0200)
committerFlorent Kermarrec <florent@enjoy-digital.fr>
Mon, 30 Sep 2019 21:33:25 +0000 (23:33 +0200)
litex/soc/interconnect/stream.py

index c99cff6d58ffbbb12a2f30dd23092f01fd191006..c1568e8442cc50417109f4811bfe1b6096af0d7e 100644 (file)
@@ -4,14 +4,18 @@
 # License: BSD
 
 import math
+from copy import copy
 
 from migen import *
+from migen.util.misc import xdir
 from migen.genlib.record import *
 from migen.genlib import fifo
 from migen.genlib.cdc import MultiReg, PulseSynchronizer
 
 from litex.soc.interconnect.csr import *
 
+# Endpoint -----------------------------------------------------------------------------------------
+
 (DIR_SINK, DIR_SOURCE) = range(2)
 
 def _make_m2s(layout):
@@ -64,6 +68,91 @@ class Endpoint(Record):
         except:
             return getattr(object.__getattribute__(self, "param"), name)
 
+# Actor --------------------------------------------------------------------------------------------
+
+def _rawbits_layout(l):
+    if isinstance(l, int):
+        return [("rawbits", l)]
+    else:
+        return l
+
+def pack_layout(l, n):
+    return [("chunk"+str(i), l) for i in range(n)]
+
+def get_endpoints(obj, filt=Endpoint):
+    if hasattr(obj, "get_endpoints") and callable(obj.get_endpoints):
+        return obj.get_endpoints(filt)
+    r = dict()
+    for k, v in xdir(obj, True):
+        if isinstance(v, filt):
+            r[k] = v
+    return r
+
+def get_single_ep(obj, filt):
+    eps = get_endpoints(obj, filt)
+    if len(eps) != 1:
+        raise ValueError("More than one endpoint")
+    return list(eps.items())[0]
+
+
+class BinaryActor(Module):
+    def __init__(self, *args, **kwargs):
+        self.build_binary_control(self.sink, self.source, *args, **kwargs)
+
+    def build_binary_control(self, sink, source):
+        raise NotImplementedError("Binary actor classes must overload build_binary_control_fragment")
+
+
+class CombinatorialActor(BinaryActor):
+    def build_binary_control(self, sink, source):
+        self.comb += [
+            source.valid.eq(sink.valid),
+            source.first.eq(sink.first),
+            source.last.eq(sink.last),
+            sink.ready.eq(source.ready),
+        ]
+
+
+class PipelinedActor(BinaryActor):
+    def __init__(self, latency):
+        self.latency = latency
+        self.pipe_ce = Signal()
+        self.busy = Signal()
+        BinaryActor.__init__(self, latency)
+
+    def build_binary_control(self, sink, source, latency):
+        busy = 0
+        valid = sink.valid
+        for i in range(latency):
+            valid_n = Signal()
+            self.sync += If(self.pipe_ce, valid_n.eq(valid))
+            valid = valid_n
+            busy = busy | valid
+
+        self.comb += [
+            self.pipe_ce.eq(source.ready | ~valid),
+            sink.ready.eq(self.pipe_ce),
+            source.valid.eq(valid),
+            self.busy.eq(busy)
+        ]
+        first = sink.valid & sink.first
+        last = sink.valid & sink.last
+        for i in range(latency):
+            first_n = Signal()
+            last_n = Signal()
+            self.sync += \
+                If(self.pipe_ce,
+                    first_n.eq(first),
+                    last_n.eq(last)
+                )
+            first = first_n
+            last = last_n
+        self.comb += [
+            source.first.eq(first),
+            source.last.eq(last)
+        ]
+
+# FIFO ---------------------------------------------------------------------------------------------
 
 class _FIFOWrapper(Module):
     def __init__(self, fifo_class, layout, depth):
@@ -120,6 +209,7 @@ class AsyncFIFO(_FIFOWrapper):
             fifo.AsyncFIFOBuffered if buffered else fifo.AsyncFIFO,
             layout, depth)
 
+# Mux/Demux ----------------------------------------------------------------------------------------
 
 class Multiplexer(Module):
     def __init__(self, layout, n):
@@ -156,6 +246,7 @@ class Demultiplexer(Module):
             cases[i] = self.sink.connect(source)
         self.comb += Case(self.sel, cases)
 
+# Converter ----------------------------------------------------------------------------------------
 
 class _UpConverter(Module):
     def __init__(self, nbits_from, nbits_to, ratio, reverse):
@@ -367,6 +458,7 @@ class StrideConverter(Module):
         else:
             raise ValueError
 
+# Gearbox ------------------------------------------------------------------------------------------
 
 def lcm(a, b):
     return (a*b)//math.gcd(a, b)
@@ -433,6 +525,7 @@ class Gearbox(Module):
         else:
             self.comb += source.data.eq(o_data[::-1])
 
+# Monitor ------------------------------------------------------------------------------------------
 
 class Monitor(Module, AutoCSR):
     def __init__(self, endpoint, count_width=32, clock_domain="sys",
@@ -501,94 +594,7 @@ class Monitor(Module, AutoCSR):
             underflow_counter = MonitorCounter(reset, latch, ~endpoint.valid & endpoint.ready, self.underflows.status)
             self.submodules += underflow_counter
 
-# TODO: clean up code below
-# XXX
-
-from copy import copy
-from migen.util.misc import xdir
-
-def _rawbits_layout(l):
-    if isinstance(l, int):
-        return [("rawbits", l)]
-    else:
-        return l
-
-def pack_layout(l, n):
-    return [("chunk"+str(i), l) for i in range(n)]
-
-def get_endpoints(obj, filt=Endpoint):
-    if hasattr(obj, "get_endpoints") and callable(obj.get_endpoints):
-        return obj.get_endpoints(filt)
-    r = dict()
-    for k, v in xdir(obj, True):
-        if isinstance(v, filt):
-            r[k] = v
-    return r
-
-def get_single_ep(obj, filt):
-    eps = get_endpoints(obj, filt)
-    if len(eps) != 1:
-        raise ValueError("More than one endpoint")
-    return list(eps.items())[0]
-
-
-class BinaryActor(Module):
-    def __init__(self, *args, **kwargs):
-        self.build_binary_control(self.sink, self.source, *args, **kwargs)
-
-    def build_binary_control(self, sink, source):
-        raise NotImplementedError("Binary actor classes must overload build_binary_control_fragment")
-
-
-class CombinatorialActor(BinaryActor):
-    def build_binary_control(self, sink, source):
-        self.comb += [
-            source.valid.eq(sink.valid),
-            source.first.eq(sink.first),
-            source.last.eq(sink.last),
-            sink.ready.eq(source.ready),
-        ]
-
-
-class PipelinedActor(BinaryActor):
-    def __init__(self, latency):
-        self.latency = latency
-        self.pipe_ce = Signal()
-        self.busy = Signal()
-        BinaryActor.__init__(self, latency)
-
-    def build_binary_control(self, sink, source, latency):
-        busy = 0
-        valid = sink.valid
-        for i in range(latency):
-            valid_n = Signal()
-            self.sync += If(self.pipe_ce, valid_n.eq(valid))
-            valid = valid_n
-            busy = busy | valid
-
-        self.comb += [
-            self.pipe_ce.eq(source.ready | ~valid),
-            sink.ready.eq(self.pipe_ce),
-            source.valid.eq(valid),
-            self.busy.eq(busy)
-        ]
-        first = sink.valid & sink.first
-        last = sink.valid & sink.last
-        for i in range(latency):
-            first_n = Signal()
-            last_n = Signal()
-            self.sync += \
-                If(self.pipe_ce,
-                    first_n.eq(first),
-                    last_n.eq(last)
-                )
-            first = first_n
-            last = last_n
-        self.comb += [
-            source.first.eq(first),
-            source.last.eq(last)
-        ]
-
+# Buffer -------------------------------------------------------------------------------------------
 
 class Buffer(PipelinedActor):
     def __init__(self, layout):
@@ -601,6 +607,7 @@ class Buffer(PipelinedActor):
                 self.source.param.eq(self.sink.param)
             )
 
+# Cast ---------------------------------------------------------------------------------------------
 
 class Cast(CombinatorialActor):
     def __init__(self, layout_from, layout_to, reverse_from=False, reverse_to=False):
@@ -620,6 +627,7 @@ class Cast(CombinatorialActor):
             raise TypeError
         self.comb += Cat(*sigs_to).eq(Cat(*sigs_from))
 
+# Unpack/Pack --------------------------------------------------------------------------------------
 
 class Unpack(Module):
     def __init__(self, n, layout_to, reverse=False):
@@ -715,6 +723,7 @@ class Pack(Module):
             )
         ]
 
+# Pipeline -----------------------------------------------------------------------------------------
 
 class Pipeline(Module):
     def __init__(self, *modules):
@@ -742,6 +751,7 @@ class Pipeline(Module):
         if hasattr(m, "source"):
             self.source = m.source
 
+# BufferizeEndpoints -------------------------------------------------------------------------------
 
 # Add buffers on Endpoints (can be used to improve timings)
 class BufferizeEndpoints(ModuleTransformer):
@@ -765,6 +775,3 @@ class BufferizeEndpoints(ModuleTransformer):
                 setattr(submodule, name, buf.source)
             else:
                 raise ValueError
-
-
-# XXX