From a7227d7d2bbf8d58de1a12180f40ea82cf473900 Mon Sep 17 00:00:00 2001 From: Sebastien Bourdeauducq Date: Wed, 12 Dec 2012 22:20:48 +0100 Subject: [PATCH] Remove ActorNode --- examples/dataflow/dma.py | 25 ++++---- examples/dataflow/misc.py | 6 +- examples/dataflow/structuring.py | 12 ++-- examples/pytholite/basic.py | 2 +- examples/pytholite/uio.py | 2 +- examples/sim/dataflow.py | 6 +- migen/flow/actor.py | 3 +- migen/flow/network.py | 99 +++++++++++++++----------------- 8 files changed, 73 insertions(+), 82 deletions(-) diff --git a/examples/dataflow/dma.py b/examples/dataflow/dma.py index 5bcd063ed..8e221edcc 100644 --- a/examples/dataflow/dma.py +++ b/examples/dataflow/dma.py @@ -1,7 +1,6 @@ from random import Random from migen.flow.network import * -from migen.actorlib.ala import * from migen.actorlib import dma_wishbone, dma_asmi from migen.actorlib.sim import * from migen.bus import wishbone, asmibus @@ -43,7 +42,7 @@ def trgen_gen(): def wishbone_sim(efragment, master, end_simulation): peripheral = wishbone.Target(MyModelWB()) tap = wishbone.Tap(peripheral.bus) - interconnect = wishbone.InterconnectPointToPoint(master.actor.bus, peripheral.bus) + interconnect = wishbone.InterconnectPointToPoint(master.bus, peripheral.bus) def _end_simulation(s): s.interrupt = end_simulation(s) fragment = efragment \ @@ -70,27 +69,27 @@ def asmi_sim(efragment, hub, end_simulation): def test_wb_reader(): print("*** Testing Wishbone reader") - adrgen = ActorNode(SimActor(adrgen_gen(), ("address", Source, [("a", 30)]))) - reader = ActorNode(dma_wishbone.Reader()) - dumper = ActorNode(SimActor(dumper_gen(), ("data", Sink, [("d", 32)]))) + adrgen = SimActor(adrgen_gen(), ("address", Source, [("a", 30)])) + reader = dma_wishbone.Reader() + dumper = SimActor(dumper_gen(), ("data", Sink, [("d", 32)])) g = DataFlowGraph() g.add_connection(adrgen, reader) g.add_connection(reader, dumper) comp = CompositeActor(g) wishbone_sim(comp.get_fragment(), reader, - lambda s: adrgen.actor.token_exchanger.done and not s.rd(comp.busy)) + lambda s: adrgen.token_exchanger.done and not s.rd(comp.busy)) def test_wb_writer(): print("*** Testing Wishbone writer") - trgen = ActorNode(SimActor(trgen_gen(), ("address_data", Source, [("a", 30), ("d", 32)]))) - writer = ActorNode(dma_wishbone.Writer()) + trgen = SimActor(trgen_gen(), ("address_data", Source, [("a", 30), ("d", 32)])) + writer = dma_wishbone.Writer() g = DataFlowGraph() g.add_connection(trgen, writer) comp = CompositeActor(g) wishbone_sim(comp.get_fragment(), writer, - lambda s: trgen.actor.token_exchanger.done and not s.rd(comp.busy)) + lambda s: trgen.token_exchanger.done and not s.rd(comp.busy)) def test_asmi_reader(nslots): print("*** Testing ASMI reader (nslots={})".format(nslots)) @@ -99,16 +98,16 @@ def test_asmi_reader(nslots): port = hub.get_port(nslots) hub.finalize() - adrgen = ActorNode(SimActor(adrgen_gen(), ("address", Source, [("a", 32)]))) - reader = ActorNode(dma_asmi.Reader(port)) - dumper = ActorNode(SimActor(dumper_gen(), ("data", Sink, [("d", 32)]))) + adrgen = SimActor(adrgen_gen(), ("address", Source, [("a", 32)])) + reader = dma_asmi.Reader(port) + dumper = SimActor(dumper_gen(), ("data", Sink, [("d", 32)])) g = DataFlowGraph() g.add_connection(adrgen, reader) g.add_connection(reader, dumper) comp = CompositeActor(g) asmi_sim(hub.get_fragment() + comp.get_fragment(), hub, - lambda s: adrgen.actor.token_exchanger.done and not s.rd(comp.busy)) + lambda s: adrgen.token_exchanger.done and not s.rd(comp.busy)) test_wb_reader() test_wb_writer() diff --git a/examples/dataflow/misc.py b/examples/dataflow/misc.py index 71e0f2486..a4dc71d6f 100644 --- a/examples/dataflow/misc.py +++ b/examples/dataflow/misc.py @@ -17,9 +17,9 @@ def sink_gen(): print(t.value["value"]) def main(): - source = ActorNode(SimActor(source_gen(), ("source", Source, [("value", 32)]))) - loop = ActorNode(misc.IntSequence(32)) - sink = ActorNode(SimActor(sink_gen(), ("sink", Sink, [("value", 32)]))) + source = SimActor(source_gen(), ("source", Source, [("value", 32)])) + loop = misc.IntSequence(32) + sink = SimActor(sink_gen(), ("sink", Sink, [("value", 32)])) g = DataFlowGraph() g.add_connection(source, loop) g.add_connection(loop, sink) diff --git a/examples/dataflow/structuring.py b/examples/dataflow/structuring.py index fdbc75340..2a6dd24e1 100644 --- a/examples/dataflow/structuring.py +++ b/examples/dataflow/structuring.py @@ -27,14 +27,14 @@ def main(): packed_layout = structuring.pack_layout(base_layout, pack_factor) rawbits_layout = [("value", 32*pack_factor)] - source = ActorNode(SimActor(source_gen(), ("source", Source, base_layout))) - sink = ActorNode(SimActor(sink_gen(), ("sink", Sink, base_layout))) + source = SimActor(source_gen(), ("source", Source, base_layout)) + sink = SimActor(sink_gen(), ("sink", Sink, base_layout)) # A tortuous way of passing integer tokens. - packer = ActorNode(structuring.Pack(base_layout, pack_factor)) - to_raw = ActorNode(structuring.Cast(packed_layout, rawbits_layout)) - from_raw = ActorNode(structuring.Cast(rawbits_layout, packed_layout)) - unpacker = ActorNode(structuring.Unpack(pack_factor, base_layout)) + packer = structuring.Pack(base_layout, pack_factor) + to_raw = structuring.Cast(packed_layout, rawbits_layout) + from_raw = structuring.Cast(rawbits_layout, packed_layout) + unpacker = structuring.Unpack(pack_factor, base_layout) g = DataFlowGraph() g.add_connection(source, packer) diff --git a/examples/pytholite/basic.py b/examples/pytholite/basic.py index d2df3df39..921b0e5e2 100644 --- a/examples/pytholite/basic.py +++ b/examples/pytholite/basic.py @@ -14,7 +14,7 @@ def number_gen(): def run_sim(ng): g = DataFlowGraph() d = Dumper(layout) - g.add_connection(ActorNode(ng), ActorNode(d)) + g.add_connection(ng, d) c = CompositeActor(g) fragment = c.get_fragment() diff --git a/examples/pytholite/uio.py b/examples/pytholite/uio.py index ed8e92684..1a0690cdc 100644 --- a/examples/pytholite/uio.py +++ b/examples/pytholite/uio.py @@ -31,7 +31,7 @@ class SlaveModel(wishbone.TargetModel): def run_sim(ng): g = DataFlowGraph() d = Dumper(layout) - g.add_connection(ActorNode(ng), ActorNode(d)) + g.add_connection(ng, d) slave = wishbone.Target(SlaveModel()) intercon = wishbone.InterconnectPointToPoint(ng.buses["wb"], slave.bus) diff --git a/examples/sim/dataflow.py b/examples/sim/dataflow.py index 2137620ff..318206a25 100644 --- a/examples/sim/dataflow.py +++ b/examples/sim/dataflow.py @@ -17,13 +17,13 @@ def sink_gen(): print("Received: " + str(t.value["value"])) def main(): - source = ActorNode(SimActor(source_gen(), ("source", Source, [("value", 32)]))) - sink = ActorNode(SimActor(sink_gen(), ("sink", Sink, [("value", 32)]))) + source = SimActor(source_gen(), ("source", Source, [("value", 32)])) + sink = SimActor(sink_gen(), ("sink", Sink, [("value", 32)])) g = DataFlowGraph() g.add_connection(source, sink) comp = CompositeActor(g) def end_simulation(s): - s.interrupt = source.actor.token_exchanger.done + s.interrupt = source.token_exchanger.done fragment = comp.get_fragment() + Fragment(sim=[end_simulation]) sim = Simulator(fragment, Runner()) sim.run() diff --git a/migen/flow/actor.py b/migen/flow/actor.py index 5552624cf..fd9fd20b7 100644 --- a/migen/flow/actor.py +++ b/migen/flow/actor.py @@ -32,8 +32,9 @@ class Source(Endpoint): def __repr__(self): return "" -class Actor: +class Actor(HUID): def __init__(self, *endpoint_descriptions, endpoints=None): + super().__init__() if endpoints is None: self.endpoints = {} for desc in endpoint_descriptions: diff --git a/migen/flow/network.py b/migen/flow/network.py index acbbb6adb..c26af1f3a 100644 --- a/migen/flow/network.py +++ b/migen/flow/network.py @@ -6,57 +6,37 @@ from migen.flow.actor import * from migen.flow import plumbing from migen.flow.isd import DFGReporter -# Graph nodes can be either: -# (1) a reference to an existing actor -# (2) an abstract (class, dictionary) pair meaning that the actor class should be -# instantiated with the parameters from the dictionary. -# This form is needed to enable actor duplication or sharing during elaboration. +# Abstract actors mean that the actor class should be instantiated with the parameters +# from the dictionary. They are needed to enable actor duplication or sharing during +# elaboration, and automatic parametrization of plumbing actors. -class ActorNode(HUID): - def __init__(self, actor_class, parameters=dict()): +class AbstractActor(HUID): + def __init__(self, actor_class, parameters=dict(), name=None): super().__init__() - if isinstance(actor_class, type): - self.actor_class = actor_class - self.parameters = parameters - else: - self.actor = actor_class - self.name = None + self.actor_class = actor_class + self.parameters = parameters + self.name = name - def is_abstract(self): - return hasattr(self, "actor_class") - - def instantiate(self): - self.actor = self.actor_class(**self.parameters) - self.actor.name = self.name - del self.actor_class - del self.parameters - - def get_dict(self): - if self.is_abstract(): - return self.parameters - else: - return self.actor.__dict__ + def create_instance(self): + return self.actor_class(**self.parameters) def __repr__(self): - if self.is_abstract(): - r = " [sink1, ..., sinkn] # source element is a (node, endpoint) pair. @@ -116,7 +107,7 @@ class DataFlowGraph(MultiDiGraph): # NB: It is not allowed for a single sink to be fed by more than one source # (except with subrecords, i.e. when a combinator is used) def is_abstract(self): - return any(x.is_abstract() for x in self) \ + return any(isinstance(x, AbstractActor) for x in self) \ or any(d["source_subr"] is not None or d["sink_subr"] is not None for u, v, d in self.edges_iter(data=True)) \ or bool(self._list_divergences()) @@ -128,7 +119,7 @@ class DataFlowGraph(MultiDiGraph): # build combinator # "layout" is filled in during instantiation subrecords = [dst_subrecord for src_node, src_endpoint, dst_subrecord, src_subrecord in sources] - combinator = ActorNode(plumbing.Combinator, {"subrecords": subrecords}) + combinator = AbstractActor(plumbing.Combinator, {"subrecords": subrecords}) # disconnect source1 -> sink ... sourcen -> sink # connect source1 -> combinator_sink1 ... sourcen -> combinator_sinkn for n, (src_node, src_endpoint, dst_subrecord, src_subrecord) in enumerate(sources): @@ -142,7 +133,7 @@ class DataFlowGraph(MultiDiGraph): for (src_node, src_endpoint), sinks in self._source_to_sinks().items(): if len(sinks) > 1 or sinks[0][2] is not None: subrecords = [src_subrecord for dst_node, dst_endpoint, src_subrecord, dst_subrecord in sinks] - splitter = ActorNode(plumbing.Splitter, {"subrecords": subrecords}) + splitter = AbstractActor(plumbing.Splitter, {"subrecords": subrecords}) # disconnect source -> sink1 ... source -> sinkn # connect splitter_source1 -> sink1 ... splitter_sourcen -> sinkn for n, (dst_node, dst_endpoint, src_subrecord, dst_subrecord) in enumerate(sinks): @@ -155,7 +146,7 @@ class DataFlowGraph(MultiDiGraph): def _infer_plumbing_layout(self): while True: - ap = [a for a in self if a.is_abstract() and a.actor_class in plumbing.actors] + ap = [a for a in self if isinstance(a, AbstractActor) and a.actor_class in plumbing.actors] if not ap: break for a in ap: @@ -167,7 +158,7 @@ class DataFlowGraph(MultiDiGraph): continue other_ep = data["source"] if other_ep is None: - other_ep = other.actor.single_source() + other_ep = other.single_source() elif a.actor_class in plumbing.layout_source: edges = self.out_edges(a, data=True) assert(len(edges) == 1) @@ -176,26 +167,26 @@ class DataFlowGraph(MultiDiGraph): continue other_ep = data["sink"] if other_ep is None: - other_ep = other.actor.single_sink() + other_ep = other.single_sink() else: raise AssertionError - layout = other.actor.token(other_ep).layout() + layout = other.token(other_ep).layout() a.parameters["layout"] = layout - a.instantiate() + self.instantiate(a) def _instantiate_actors(self): # 1. instantiate all abstract non-plumbing actors - for actor in self: - if actor.is_abstract() and actor.actor_class not in plumbing.actors: - actor.instantiate() + for actor in list(self): + if isinstance(actor, AbstractActor) and actor.actor_class not in plumbing.actors: + self.instantiate(actor) # 2. infer plumbing layout and instantiate plumbing self._infer_plumbing_layout() # 3. resolve default eps for u, v, d in self.edges_iter(data=True): if d["source"] is None: - d["source"] = u.actor.single_source() + d["source"] = u.single_source() if d["sink"] is None: - d["sink"] = v.actor.single_sink() + d["sink"] = v.single_sink() # Elaboration turns an abstract DFG into a physical one. # Pass 1: eliminate subrecords and divergences @@ -227,13 +218,13 @@ class CompositeActor(Actor): return [] def get_fragment(self): - comb = [self.busy.eq(optree("|", [node.actor.busy for node in self.dfg]))] + comb = [self.busy.eq(optree("|", [node.busy for node in self.dfg]))] fragment = Fragment(comb) for node in self.dfg: - fragment += node.actor.get_fragment() + fragment += node.get_fragment() for u, v, d in self.dfg.edges_iter(data=True): - ep_src = u.actor.endpoints[d["source"]] - ep_dst = v.actor.endpoints[d["sink"]] + ep_src = u.endpoints[d["source"]] + ep_dst = v.endpoints[d["sink"]] fragment += get_conn_fragment(ep_src, ep_dst) if hasattr(self, "debugger"): fragment += self.debugger.get_fragment()