])
def pack_layout(l, n):
- return [("chunk{0}".format(i), l) for i in range(n)]
+ return [("chunk"+str(i), l) for i in range(n)]
class Unpack(Actor):
def __init__(self, n, layout_to):
]
cases = {}
for i in range(self.n):
- cases[i] = [Cat(*self.token("source").flatten()).eq(Cat(*self.token("sink").subrecord("chunk{0}".format(i)).flatten()))]
+ cases[i] = [self.token("source").raw_bits().eq(getattr(self.token("sink"), "chunk"+str(i)).raw_bits())]
comb.append(Case(mux, cases).makedefault())
return Fragment(comb, sync)
strobe_all = Signal()
cases = {}
for i in range(self.n):
- cases[i] = [Cat(*self.token("source").subrecord("chunk{0}".format(i)).flatten()).eq(*self.token("sink").flatten())]
+ cases[i] = [getattr(self.token("source"), "chunk"+str(i)).raw_bits().eq(self.token("sink").raw_bits())]
comb = [
self.busy.eq(strobe_all),
self.endpoints["sink"].ack.eq(~strobe_all | self.endpoints["source"].ack),
from migen.fhdl.structure import *
+from migen.fhdl.module import Module
from migen.flow.actor import *
from migen.genlib.record import *
from migen.genlib.misc import optree
sync = [If(self.pipe_ce, Cat(*sigs_q).eq(Cat(*sigs_d)))]
return Fragment(sync=sync)
-class Combinator(Actor):
+class Combinator(Module, Actor):
def __init__(self, layout, subrecords):
- source = Record(layout)
- subrecords = [source.subrecord(*subr) for subr in subrecords]
- eps = [("sink{0}".format(n), Sink, r)
+ eps = [("source", Source, layout)]
+ eps += [("sink"+str(n), Sink, layout_partial(layout, r))
for n, r in enumerate(subrecords)]
- ep_source = ("source", Source, source)
- eps.append(ep_source)
Actor.__init__(self, *eps)
- def get_fragment(self):
+ ###
+
source = self.endpoints["source"]
- sinks = [self.endpoints["sink{0}".format(n)]
+ sinks = [self.endpoints["sink"+str(n)]
for n in range(len(self.endpoints)-1)]
- comb = [source.stb.eq(optree("&", [sink.stb for sink in sinks]))]
- comb += [sink.ack.eq(source.ack & source.stb) for sink in sinks]
- return Fragment(comb)
+ self.comb += [source.stb.eq(optree("&", [sink.stb for sink in sinks]))]
+ self.comb += [sink.ack.eq(source.ack & source.stb) for sink in sinks]
+ self.comb += [source.token.eq(sink.token) for sink in sinks]
-class Splitter(Actor):
+class Splitter(Module, Actor):
def __init__(self, layout, subrecords):
- sink = Record(layout)
- subr = []
- for s in subrecords:
- if s is None:
- subr.append(sink)
- else:
- subr.append(sink.subrecord(*s))
- eps = [("source{0}".format(n), Source, r)
- for n, r in enumerate(subr)]
- ep_sink = ("sink", Sink, sink)
- eps.append(ep_sink)
+ eps = [("sink", Sink, layout)]
+ eps += [("source"+str(n), Source, layout_partial(layout, *r))
+ for n, r in enumerate(subrecords)]
Actor.__init__(self, *eps)
- def get_fragment(self):
+ ###
+
sources = [self.endpoints[e] for e in self.sources()]
sink = self.endpoints[self.sinks()[0]]
+
+ self.comb += [source.token.eq(sink.token) for source in sources]
already_acked = Signal(len(sources))
- sync = [
- If(sink.stb,
+ self.sync += If(sink.stb,
already_acked.eq(already_acked | Cat(*[s.ack for s in sources])),
If(sink.ack, already_acked.eq(0))
)
- ]
- comb = [
- sink.ack.eq(optree("&",
+ self.comb += sink.ack.eq(optree("&",
[s.ack | already_acked[n] for n, s in enumerate(sources)]))
- ]
for n, s in enumerate(sources):
- comb.append(s.stb.eq(sink.stb & ~already_acked[n]))
- return Fragment(comb, sync)
+ self.comb += s.stb.eq(sink.stb & ~already_acked[n])
# Actors whose layout should be inferred from what their single sink is connected to.
layout_sink = {Buffer, Splitter}