actorlib/control: simplify + fix
authorSebastien Bourdeauducq <sebastien@milkymist.org>
Sun, 17 Jun 2012 19:19:47 +0000 (21:19 +0200)
committerSebastien Bourdeauducq <sebastien@milkymist.org>
Sun, 17 Jun 2012 19:19:47 +0000 (21:19 +0200)
examples/dataflow/control.py [new file with mode: 0644]
migen/actorlib/control.py

diff --git a/examples/dataflow/control.py b/examples/dataflow/control.py
new file mode 100644 (file)
index 0000000..8819250
--- /dev/null
@@ -0,0 +1,31 @@
+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()
index 8520dd99f31a4c3a7344451f94b74e3c987b952d..0d562cc0b54ba9ec1c732a46e101c4d870976ab8 100644 (file)
@@ -1,6 +1,3 @@
-from operator import mul
-from functools import reduce
-
 from migen.fhdl.structure import *
 from migen.corelogic.record import *
 from migen.corelogic.fsm import *
@@ -8,80 +5,46 @@ from migen.flow.actor 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),
@@ -91,4 +54,4 @@ class For(Actor):
                                If(last, fsm.next_state(fsm.IDLE))
                        )
                )
-               return counters_fragment + fsm.get_fragment()
+               return counter_fragment + fsm.get_fragment()