flow: plumbing
authorSebastien Bourdeauducq <sebastien@milkymist.org>
Fri, 6 Jan 2012 16:24:05 +0000 (17:24 +0100)
committerSebastien Bourdeauducq <sebastien@milkymist.org>
Fri, 6 Jan 2012 16:24:05 +0000 (17:24 +0100)
examples/dataflow.py
migen/flow/actor.py
migen/flow/ala.py
migen/flow/plumbing.py [new file with mode: 0644]

index 06c2ab123d930cf9291ba0c3672d0daf1ed11e3a..57035ce337100ba2e7f003474ca3b327ea59d0c8 100644 (file)
@@ -1,6 +1,22 @@
 from migen.fhdl import verilog 
 from migen.flow.ala import *
+from migen.flow.plumbing import *
 
-act = Divider(32)
-frag = act.get_control_fragment() + act.get_process_fragment()
-print(verilog.convert(frag))
+act = Adder(32)
+comb = Combinator(act.operands, ["a"], ["b"])
+outbuf = Buffer(act.result.template())
+frag = get_actor_fragments(act, comb, outbuf)
+
+stb_a = comb.sinks[0].stb
+ack_a = comb.sinks[0].ack
+stb_b = comb.sinks[1].stb
+ack_b = comb.sinks[1].ack
+stb_a.name = "stb_a_i"
+ack_a.name = "ack_a_o"
+stb_b.name = "stb_b_i"
+ack_b.name = "stb_b_o"
+a = comb.ins[0].a
+b = comb.ins[1].b
+a.name = "a"
+b.name = "b"
+print(verilog.convert(frag, ios={stb_a, ack_a, stb_b, ack_b, a, b}))
index f1b783a6748240e457cc4bb58ea69a3664f12151..98e9ba78901658354aaf58091b2488ed3df6b26c 100644 (file)
@@ -104,3 +104,6 @@ class Actor:
        
        def get_process_fragment(self):
                raise NotImplementedError("Actor classes must overload get_process_fragment")
+
+def get_actor_fragments(*actors):
+       return sum([a.get_control_fragment() + a.get_process_fragment() for a in actors], Fragment())
index b3456eb518c41cec449ec68d220ab0d0db5dfb4d..1fc53bb348038c4302aa803cded838205b03915f 100644 (file)
@@ -6,7 +6,7 @@ from migen.corelogic import divider
 class Adder(Actor):
        def __init__(self, width):
                self.operands = Record([('a', BV(width)), ('b', BV(width))])
-               self.result = Record(['sum', BV(width+1)])
+               self.result = Record([('sum', BV(width+1))])
                Actor.__init__(self,
                        SchedulingModel(SchedulingModel.COMBINATORIAL),
                        self.operands, self.result)
diff --git a/migen/flow/plumbing.py b/migen/flow/plumbing.py
new file mode 100644 (file)
index 0000000..a3780a1
--- /dev/null
@@ -0,0 +1,45 @@
+from migen.fhdl.structure import *
+from migen.flow.actor import *
+from migen.corelogic.record import *
+from migen.corelogic.misc import optree
+
+class Buffer(Actor):
+       def __init__(self, template):
+               self.d = Record(template)
+               self.q = Record(template)
+               Actor.__init__(self,
+                       SchedulingModel(SchedulingModel.PIPELINE, 1),
+                       self.d, self.q)
+       
+       def get_process_fragment(self):
+               sigs_d = self.d.flatten()
+               sigs_q = self.q.flatten()
+               sync = [Cat(*sigs_q).eq(Cat(*sigs_d))]
+               return Fragment(sync=sync)
+
+class Combinator(Actor):
+       def __init__(self, destination, *subrecords):
+               self.ins = [destination.subrecord(*subr) for subr in subrecords]
+               Actor.__init__(self,
+                       SchedulingModel(SchedulingModel.COMBINATORIAL),
+                       self.ins, destination)
+
+       def get_process_fragment(self):
+               return Fragment() # nothing to do
+       
+       def get_control_fragment(self):
+               comb = [self.sources[0].stb.eq(optree('&', [sink.stb for sink in self.sinks]))]
+               comb += [sink.ack.eq(self.sources[0].ack & self.sources[0].stb) for sink in self.sinks]
+               return Fragment(comb)
+
+class Splitter(Actor):
+       def __init__(self, source, *subrecords):
+               self.outs = [source.subrecord(*subr) for subr in subrecords]
+               Actor.__init__(self,
+                       SchedulingModel(SchedulingModel.COMBINATORIAL),
+                       source, self.outs)
+               
+       def get_process_fragment(self):
+               return Fragment() # nothing to do
+       
+       # TODO def get_control_fragment(self):