--- /dev/null
+from migen.flow.network import *
+from migen.actorlib import control
+from migen.actorlib.sim import *
+from migen.sim.generic import Simulator
+from migen.sim.icarus import Runner
+
+def source_gen():
+ for i in range(10):
+ v = i + 5
+ print("==> " + str(v))
+ yield Token("source", {"value": v})
+
+def sink_gen():
+ while True:
+ t = Token("sink")
+ yield t
+ print(t.value["value"])
+
+def main():
+ source = ActorNode(SimActor(source_gen(), ("source", Source, [("value", BV(32))])))
+ loop = ActorNode(control.For(32))
+ sink = ActorNode(SimActor(sink_gen(), ("sink", Sink, [("value", BV(32))])))
+ g = DataFlowGraph()
+ g.add_connection(source, loop)
+ g.add_connection(loop, sink)
+ comp = CompositeActor(g)
+ fragment = comp.get_fragment()
+ sim = Simulator(fragment, Runner())
+ sim.run(500)
+
+main()
-from operator import mul
-from functools import reduce
-
from migen.fhdl.structure import *
from migen.corelogic.record import *
from migen.corelogic.fsm import *
# Generates integers from start to maximum-1
class For(Actor):
- def __init__(self, *nbits, start=False, step=False):
- self.dimensions = len(nbits)
- self.start = start
+ def __init__(self, nbits, step=1):
+ self.nbits = nbits
self.step = step
- params = ["end"]
- if start: params.append("start")
- if step: params.append("step")
- self.d_bv = [BV(dimension) for dimension in nbits]
- l_sink = [("d{0}".format(n), [(p, bv) for p in params])
- for n, bv in enumerate(self.d_bv)]
- l_source = [("d{0}".format(n), bv)
- for n, bv in enumerate(self.d_bv)]
+
super().__init__(
- ("sink", Sink, l_sink),
- ("source", Source, l_source))
+ ("maximum", Sink, [("value", BV(nbits))]),
+ ("source", Source, [("value", BV(nbits))]))
def get_fragment(self):
load = Signal()
ce = Signal()
last = Signal()
- counters_v = [Signal(bv, variable=True) for bv in self.d_bv]
- counters = [getattr(self.token("source"), "d{0}".format(n))
- for n in range(self.dimensions)]
+ maximum = Signal(BV(self.nbits))
+ counter = Signal(BV(self.nbits))
- params = [getattr(self.token("sink"), "d{0}".format(n))
- for n in range(self.dimensions)]
- if self.start:
- starts = [p.start for p in params]
- start_rs = [Signal(s.bv, variable=True) for s in starts]
- else:
- start_rs = [Constant(0, bv) for bv in self.d_bv]
- if self.step:
- steps = [p.step for p in params]
- step_rs = [Signal(s.bv, variable=True) for s in steps]
+ if self.step > 1:
+ comb = [last.eq(counter + self.step >= maximum)]
else:
- step_rs = [Constant(1, bv) for bv in self.d_bv]
- ends = [p.end for p in params]
- end_rs = [Signal(s.bv, variable=True) for s in ends]
-
- lasts = Signal(BV(self.dimensions))
-
- on_ce = [
- If(lasts[n],
- counter.eq(start)
- ).Else(
- counter.eq(counter + step)
- )
- for n, counter, start, step
- in zip(range(self.dimensions), counters_v, start_rs, step_rs)
- ]
- lasts_gen = [
- lasts[n].eq(counter + step >= end if self.step else counter + step == end)
- for n, counter, step, end
- in zip(range(self.dimensions), counters_v, step_rs, end_rs)
- ]
+ comb = [last.eq(counter + 1 == maximum)]
sync = [
If(load,
- Cat(*start_rs).eq(Cat(*starts)) if self.start else None,
- Cat(*step_rs).eq(Cat(*steps)) if self.step else None,
- Cat(*end_rs).eq(Cat(*ends)),
- Cat(*counters_v).eq(Cat(*start_rs))
- ),
- If(ce, *on_ce)
- ] + lasts_gen + [
- Cat(*counters).eq(Cat(*counters_v))
+ counter.eq(0),
+ maximum.eq(self.token("maximum").value)
+ ).Elif(ce,
+ If(last,
+ counter.eq(0)
+ ).Else(
+ counter.eq(counter + self.step)
+ )
+ )
]
- counters_fragment = Fragment(sync=sync)
+ comb.append(self.token("source").value.eq(counter))
+ counter_fragment = Fragment(comb, sync)
fsm = FSM("IDLE", "ACTIVE")
fsm.act(fsm.IDLE,
load.eq(1),
- self.endpoints["sink"].ack.eq(1),
- If(self.endpoints["sink"].stb, fsm.next_state(fsm.ACTIVE))
+ self.endpoints["maximum"].ack.eq(1),
+ If(self.endpoints["maximum"].stb, fsm.next_state(fsm.ACTIVE))
)
fsm.act(fsm.ACTIVE,
self.busy.eq(1),
If(last, fsm.next_state(fsm.IDLE))
)
)
- return counters_fragment + fsm.get_fragment()
+ return counter_fragment + fsm.get_fragment()