flow/plumbing: add Multiplexer and Demultiplexer
authorFlorent Kermarrec <florent@enjoy-digital.fr>
Fri, 25 Oct 2013 20:45:45 +0000 (22:45 +0200)
committerSebastien Bourdeauducq <sebastien@milkymist.org>
Sat, 2 Nov 2013 22:09:47 +0000 (23:09 +0100)
migen/flow/plumbing.py

index 23301631c4a9be00e901b9bd51b7b24d35d60b93..a5af7e83c654652c68fc564ad43f6c733eaff481 100644 (file)
@@ -3,6 +3,14 @@ from migen.flow.actor import *
 from migen.genlib.record import *
 from migen.genlib.misc import optree
 
+def pipe(s1, s2):
+       r = [
+               s2.stb.eq(s1.stb),
+               s2.payload.eq(s1.payload),
+               s1.ack.eq(s2.ack)
+       ]
+       return r
+
 class Buffer(PipelinedActor):
        def __init__(self, layout):
                self.d = Sink(layout)
@@ -52,6 +60,42 @@ class Splitter(Module):
                for n, s in enumerate(sources):
                        self.comb += s.stb.eq(self.sink.stb & ~already_acked[n])
 
+class Multiplexer(Module):
+       def __init__(self, n, layout):
+               self.source = Source(layout)
+               sinks = []
+               for i in range(n):
+                       sink = Sink(layout)
+                       setattr(self, "sink"+str(i), sink)
+                       sinks.append(sink)
+               self.busy = Signal()
+               self.sel = Signal(max=n)
+               
+               ###
+
+               case = {}
+               for i, sink in enumerate(sinks):
+                       cases[i] = [pipe(sink, self.source)]
+               self.comb += Case(self.sel, cases)
+
+class Demultiplexer(Module):
+       def __init__(self, layout, n):
+               self.sink = Sink(layout)
+               sources = []
+               for i in range(n):
+                       source = Source(layout)
+                       setattr(self, "source"+str(i), source)
+                       sources.append(source)
+               self.busy = Signal()
+               self.sel = Signal(max=n)
+               
+               ###
+
+               cases = {}
+               for i, source in enumerate(sources):
+                       cases[i] = [pipe(self.sink, source)]
+               self.comb += Case(self.sel, cases)
+
 # Actors whose layout should be inferred from what their single sink is connected to.
 layout_sink = {Buffer, Splitter}
 # Actors whose layout should be inferred from what their single source is connected to.