Permalink
Browse files

Abstract actor graphs

  • Loading branch information...
1 parent b14be4c commit da522cd58d86713b93da1e5f49b0f280a5f35245 @sbourdeauducq sbourdeauducq committed Jun 15, 2012
Showing with 235 additions and 95 deletions.
  1. +26 −10 examples/dataflow/arithmetic.py
  2. +6 −1 migen/flow/actor.py
  3. +35 −22 migen/flow/ala.py
  4. +36 −45 migen/flow/composer.py
  5. +132 −17 migen/flow/network.py
@@ -1,23 +1,39 @@
import sys
+import matplotlib.pyplot as plt
+import networkx as nx
+
from migen.fhdl import verilog
from migen.flow.ala import *
from migen.flow.network import *
from migen.flow.composer import *
+draw = len(sys.argv) > 1 and sys.argv[1] == "draw"
+
+# Create graph
g = DataFlowGraph()
-a1 = make_composable(g, Add(BV(16)))
-a2 = make_composable(g, Add(BV(16)))
-a3 = make_composable(g, Add(BV(16)))
+a1 = ComposableSource(g, Add(BV(16)))
+a2 = ComposableSource(g, Add(BV(16)))
+a3 = ComposableSource(g, Add(BV(16)))
c3 = (a1 + a2)*a3
-c = CompositeActor(g)
-
-frag = c.get_fragment()
-print(verilog.convert(frag))
+a1.actor_node.name = "in1"
+a2.actor_node.name = "in2"
+a3.actor_node.name = "in3"
+c3.actor_node.name = "result"
-if len(sys.argv) > 1 and sys.argv[1] == "draw":
- import matplotlib.pyplot as plt
- import networkx as nx
+# Elaborate
+print("is_abstract before elaboration: " + str(g.is_abstract()))
+if draw:
nx.draw(g)
plt.show()
+g.elaborate()
+print("is_abstract after elaboration : " + str(g.is_abstract()))
+if draw:
+ nx.draw(g)
+ plt.show()
+
+# Convert
+#c = CompositeActor(g)
+#frag = c.get_fragment()
+#print(verilog.convert(frag))
View
@@ -46,6 +46,7 @@ def __init__(self, *endpoint_descriptions, endpoints=None):
self.endpoints[desc[0]] = ep
else:
self.endpoints = endpoints
+ self.name = None
self.busy = Signal()
def token(self, ep):
@@ -70,7 +71,11 @@ def get_fragment(self):
return self.get_control_fragment() + self.get_process_fragment()
def __repr__(self):
- return "<" + self.__class__.__name__ + " " + repr(self.sinks()) + " " + repr(self.sources()) + ">"
+ r = "<" + self.__class__.__name__
+ if self.name is not None:
+ r += ": " + self.name
+ r += ">"
+ return r
class BinaryActor(Actor):
def get_binary_control_fragment(self, stb_i, ack_o, stb_o, ack_i):
View
@@ -5,8 +5,11 @@
from migen.corelogic import divider
class _SimpleBinary(CombinatorialActor):
- def __init__(self, op, bv_op, bv_r):
- self.op = op
+ def __init__(self, bv_op, bv_r=None):
+ self.bv_op = bv_op
+ if bv_r is None:
+ bv_r = self.__class__.get_result_bv(bv_op)
+ self.bv_r = bv_r
super().__init__(
("operands", Sink, [("a", bv_op), ("b", bv_op)]),
("result", Source, [("r", bv_r)]))
@@ -18,44 +21,54 @@ def get_process_fragment(self):
])
class Add(_SimpleBinary):
- def __init__(self, bv):
- super().__init__("+", bv, BV(bv.width+1, bv.signed))
+ op = "+"
+ def get_result_bv(bv):
+ return BV(bv.width+1, bv.signed)
class Sub(_SimpleBinary):
- def __init__(self, bv):
- super().__init__("-", bv, BV(bv.width+1, bv.signed))
+ op = "-"
+ def get_result_bv(bv):
+ return BV(bv.width+1, bv.signed)
class Mul(_SimpleBinary):
- def __init__(self, bv):
- super().__init__("*", bv, BV(2*bv.width, bv.signed))
+ op = "*"
+ def get_result_bv(bv):
+ return BV(2*bv.width, bv.signed)
class And(_SimpleBinary):
- def __init__(self, bv):
- super().__init__("&", bv, bv)
+ op = "&"
+ def get_result_bv(bv):
+ return bv
class Xor(_SimpleBinary):
- def __init__(self, bv):
- super().__init__("^", bv, bv)
+ op = "^"
+ def get_result_bv(bv):
+ return bv
class Or(_SimpleBinary):
- def __init__(self, bv):
- super().__init__("|", bv, bv)
+ op = "|"
+ def get_result_bv(bv):
+ return bv
class LT(_SimpleBinary):
- def __init__(self, bv):
- super().__init__("<", bv, BV(1))
+ op = "<"
+ def get_result_bv(bv):
+ return BV(1)
class LE(_SimpleBinary):
- def __init__(self, bv):
- super().__init__("<=", bv, BV(1))
+ op = "<="
+ def get_result_bv(bv):
+ return BV(1)
class EQ(_SimpleBinary):
- def __init__(self, bv):
- super().__init__("==", bv, BV(1))
+ op = "=="
+ def get_result_bv(bv):
+ return BV(1)
class NE(_SimpleBinary):
- def __init__(self, bv):
- super().__init__("!=", bv, BV(1))
+ op = "!="
+ def get_result_bv(bv):
+ return BV(1)
class DivMod(SequentialActor):
def __init__(self, width):
View
@@ -3,71 +3,62 @@
from migen.flow.plumbing import *
from migen.flow.network import *
-def _get_bin_sigs(a, b):
+def _create(a, b, actor_class):
assert id(a.dfg) == id(b.dfg)
- return (a.actor.endpoints[a.endp].token_signal(),
- b.actor.endpoints[b.endp].token_signal())
-
-def _simple_binary(a, b, actor_class):
- (signal_self, signal_other) = _get_bin_sigs(a, b)
- width = max(signal_self.bv.width, signal_other.bv.width)
- signed = signal_self.bv.signed and signal_other.bv.signed
- actor = actor_class(BV(width, signed))
- combinator = Combinator(actor.token("operands").layout(), ["a"], ["b"])
- a.dfg.add_connection(combinator, actor)
- a.dfg.add_connection(a.actor, combinator, a.endp, "sink0")
- a.dfg.add_connection(b.actor, combinator, b.endp, "sink1")
- return make_composable(a.dfg, actor)
+ dfg = a.dfg
+
+ bva = a.actor_node.get_dict()["bv_r"]
+ bvb = b.actor_node.get_dict()["bv_r"]
+ bv_op = BV(max(bva.width, bvb.width), bva.signed and bvb.signed)
+ bv_r = actor_class.get_result_bv(bv_op)
+
+ new_actor = ActorNode(actor_class, {"bv_op": bv_op, "bv_r": bv_r})
+ dfg.add_connection(a.actor_node, new_actor, "result", "operands", sink_subr=["a"])
+ dfg.add_connection(b.actor_node, new_actor, "result", "operands", sink_subr=["b"])
+
+ return ComposableSource(dfg, new_actor)
-class ComposableSource():
- def __init__(self, dfg, actor, endp):
+class ComposableSource:
+ def __init__(self, dfg, actor_node):
self.dfg = dfg
- self.actor = actor
- self.endp = endp
+ if not isinstance(actor_node, ActorNode):
+ actor_node = ActorNode(actor_node)
+ self.actor_node = actor_node
def __add__(self, other):
- return _simple_binary(self, other, Add)
+ return _create(self, other, Add)
def __radd__(self, other):
- return _simple_binary(other, self, Add)
+ return _create(other, self, Add)
def __sub__(self, other):
- return _simple_binary(self, other, Sub)
+ return _create(self, other, Sub)
def __rsub__(self, other):
- return _simple_binary(other, self, Sub)
+ return _create(other, self, Sub)
def __mul__(self, other):
- return _simple_binary(self, other, Mul)
+ return _create(self, other, Mul)
def __rmul__(self, other):
- return _simple_binary(other, self, Mul)
+ return _create(other, self, Mul)
def __and__(self, other):
- return _simple_binary(self, other, And)
+ return _create(self, other, And)
def __rand__(self, other):
- return _simple_binary(other, self, And)
+ return _create(other, self, And)
def __xor__(self, other):
- return _simple_binary(self, other, Xor)
+ return _create(self, other, Xor)
def __rxor__(self, other):
- return _simple_binary(other, self, Xor)
+ return _create(other, self, Xor)
def __or__(self, other):
- return _simple_binary(self, other, Or)
+ return _create(self, other, Or)
def __ror__(self, other):
- return _simple_binary(other, self, Or)
+ return _create(other, self, Or)
def __lt__(self, other):
- return _simple_binary(self, other, LT)
+ return _create(self, other, LT)
def __le__(self, other):
- return _simple_binary(self, other, LE)
+ return _create(self, other, LE)
def __eq__(self, other):
- return _simple_binary(self, other, EQ)
+ return _create(self, other, EQ)
def __ne__(self, other):
- return _simple_binary(self, other, NE)
+ return _create(self, other, NE)
def __gt__(self, other):
- return _simple_binary(other, self, LT)
+ return _create(other, self, LT)
def __ge__(self, other):
- return _simple_binary(other, self, LE)
-
-def make_composable(dfg, actor):
- r = [ComposableSource(dfg, actor, k) for k in sorted(actor.sources())]
- if len(r) > 1:
- return tuple(r)
- elif len(r) > 0:
- return r[0]
- else:
- return None
+ return _create(other, self, LE)
Oops, something went wrong.

0 comments on commit da522cd

Please sign in to comment.