examples/flow: Fibonacci demo
authorSebastien Bourdeauducq <sebastien@milkymist.org>
Sat, 16 Jun 2012 20:41:34 +0000 (22:41 +0200)
committerSebastien Bourdeauducq <sebastien@milkymist.org>
Sat, 16 Jun 2012 20:41:34 +0000 (22:41 +0200)
examples/dataflow/fibonacci.py [new file with mode: 0644]

diff --git a/examples/dataflow/fibonacci.py b/examples/dataflow/fibonacci.py
new file mode 100644 (file)
index 0000000..f580006
--- /dev/null
@@ -0,0 +1,75 @@
+import sys
+
+from migen.flow.ala import *
+from migen.flow.network import *
+from migen.flow import plumbing
+from migen.actorlib.sim import *
+from migen.sim.generic import Simulator
+from migen.sim.icarus import Runner
+
+# Pushes a "1" token and then becomes transparent.
+class Init(Actor):
+       def __init__(self, nbits):
+               super().__init__(
+                       ("in", Sink, [("d", BV(nbits))]),
+                       ("out", Source, [("d", BV(nbits))]))
+       
+       def get_fragment(self):
+               done = Signal()
+               comb = [
+                       self.busy.eq(~done),
+                       If(done,
+                               self.endpoints["in"].ack.eq(self.endpoints["out"].ack),
+                               self.endpoints["out"].stb.eq(self.endpoints["in"].stb),
+                               self.endpoints["out"].token.d.eq(self.endpoints["in"].token.d)
+                       ).Else(
+                               self.endpoints["in"].ack.eq(0),
+                               self.endpoints["out"].stb.eq(1),
+                               self.endpoints["out"].token.d.eq(1)
+                       )
+               ]
+               sync = [
+                       If(self.endpoints["out"].ack, done.eq(1))
+               ]
+               return Fragment(comb, sync)
+
+class Dumper(SimActor):
+       def __init__(self, nbits):
+               def dumper_gen():
+                       while True:
+                               t = Token("result")
+                               yield t
+                               print(t.value["r"])
+               super().__init__(dumper_gen(),
+                       ("result", Sink, [("r", BV(nbits))]))
+
+def main():
+       nbits = 32
+       
+       # See:
+       # http://www.csse.monash.edu.au/~damian/Idioms/Topics/12.1.DataFlow/html/text.html
+       g = DataFlowGraph()
+       
+       adder = ActorNode(Add(BV(nbits)))
+       bufadd = ActorNode(plumbing.Buffer) # TODO FIXME: deadlocks without this buffer
+       init1 = ActorNode(Init(nbits))
+       buf1 = ActorNode(plumbing.Buffer)
+       init2 = ActorNode(Init(nbits))
+       buf2 = ActorNode(plumbing.Buffer)
+       
+       g.add_connection(adder, bufadd)
+       g.add_connection(bufadd, init1)
+       g.add_connection(init1, buf1)
+       g.add_connection(buf1, adder, sink_subr="a")
+       g.add_connection(buf1, init2)
+       g.add_connection(init2, buf2)
+       g.add_connection(buf2, adder, sink_subr="b")
+       
+       g.add_connection(bufadd, ActorNode(Dumper(nbits)))
+       
+       c = CompositeActor(g)
+       fragment = c.get_fragment()
+       sim = Simulator(fragment, Runner())
+       sim.run(100)
+       
+main()