litex/examples/dataflow/fibonacci.py

64 lines
1.7 KiB
Python

from migen.flow.network import *
from migen.flow import plumbing
from migen.actorlib.ala import *
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)
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([("r", BV(nbits))])))
c = CompositeActor(g)
fragment = c.get_fragment()
sim = Simulator(fragment, Runner())
sim.run(100)
main()