wishbone_dma: convert to new endpoint API and fix some bugs
authorSebastien Bourdeauducq <sebastien@milkymist.org>
Sun, 15 Jan 2012 15:41:15 +0000 (16:41 +0100)
committerSebastien Bourdeauducq <sebastien@milkymist.org>
Sun, 15 Jan 2012 15:41:15 +0000 (16:41 +0100)
examples/dataflow_dma.py [new file with mode: 0644]
migen/actorlib/dma_wishbone.py

diff --git a/examples/dataflow_dma.py b/examples/dataflow_dma.py
new file mode 100644 (file)
index 0000000..2671769
--- /dev/null
@@ -0,0 +1,20 @@
+import sys
+import networkx as nx
+
+from migen.fhdl import verilog
+from migen.flow.ala import *
+from migen.flow.network import *
+from migen.actorlib import dma_wishbone
+
+L = [
+       ("x", BV(10), 8),
+       ("y", BV(10), 8),
+       ("level2", [
+               ("a", BV(5), 32),
+               ("b", BV(5), 16)
+       ])
+]
+
+reader = dma_wishbone.Reader(L)
+frag = reader.get_fragment()
+print(verilog.convert(frag, ios=set(reader.bus.signals())))
index c3ad3af1cd4e2da9733f872d10aadbb03abea76f..3bf3ff8c9914141432dd1be274c884bffd8300a9 100644 (file)
@@ -6,36 +6,45 @@ from migen.flow.actor import *
 
 class Reader(Actor):
        def __init__(self, layout):
-               self.address = Record([("a", BV(30))])
-               self.data = Record(layout)
                self.bus = wishbone.Master()
                Actor.__init__(self,
                        SchedulingModel(SchedulingModel.DYNAMIC),
-                       self.address, self.data)
+                       ("address", Sink, [("a", BV(30))]),
+                       ("data", Source, layout))
        
        def get_fragment(self):
-               components, length = self.data.flatten(align=True, return_offset=True)
+               components, length = self.token("data").flatten(align=True, return_offset=True)
                nwords = (length + 31)//32
                
                # Address generator
                ag_stb = Signal()
-               ag_sync = [If(ag_stb, self.bus.adr_o.eq(self.address.a))]
+               ag_sync = [If(ag_stb, self.bus.adr_o.eq(self.token("address").a))]
                if nwords > 1:
                        ag_inc = Signal()
-                       sync.append(If(ag_inc, self.bus.adr_o.eq(self.bus.adr_o + 1)))
+                       ag_sync.append(If(ag_inc, self.bus.adr_o.eq(self.bus.adr_o + 1)))
                address_generator = Fragment(sync=ag_sync)
                
                # Output buffer
                ob_reg = Signal(BV(length))
                ob_stbs = Signal(BV(nwords))
-               ob_sync = [If(ob_stbs[w], ob_reg[32*w:32*(w+1)].eq(self.bus.dat_i))
-                       for w in range(nwords)]
+               ob_sync = []
+               top = length
+               for w in range(nwords):
+                       if top >= 32:
+                               width = 32
+                               sl = self.bus.dat_i
+                       else:
+                               width = top
+                               sl = self.bus.dat_i[32-top:]
+                       ob_sync.append(If(ob_stbs[w],
+                               ob_reg[top-width:top].eq(sl)))
+                       top -= width
                ob_comb = []
                offset = 0
                for s in components:
                        w = s.bv.width
                        if isinstance(s, Signal):
-                               comb.append(s.eq(ob_reg[length-offset-w:length-offset]))
+                               ob_comb.append(s.eq(ob_reg[length-offset-w:length-offset]))
                        offset += w
                output_buffer = Fragment(ob_comb, ob_sync)
                
@@ -55,12 +64,12 @@ class Reader(Actor):
                        if w == nwords - 1:
                                next_state = fsm.STROBE
                        else:
-                               state = getattr(fsm, fetch_states[w+1])
+                               next_state = getattr(fsm, fetch_states[w+1])
                        fsm.act(state,
                                self.bus.cyc_o.eq(1),
                                self.bus.stb_o.eq(1),
+                               ob_stbs[w].eq(1),
                                If(self.bus.ack_i,
-                                       ob_stbs[nwords-w-1].eq(1),
                                        fsm.next_state(next_state)
                                )
                        )