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()