actorlib/dma_asmi: support for writes
authorSebastien Bourdeauducq <sebastien@milkymist.org>
Sun, 28 Apr 2013 16:06:36 +0000 (18:06 +0200)
committerSebastien Bourdeauducq <sebastien@milkymist.org>
Sun, 28 Apr 2013 16:06:36 +0000 (18:06 +0200)
examples/dataflow/dma.py
migen/actorlib/dma_asmi.py

index 38d77300afc94aa7f3cc1a324d43024c3d710350..c46ee4a623cdaf914db956c8eec3acea88fd290a 100644 (file)
@@ -24,7 +24,7 @@ class MyModelASMI(MyModel, asmibus.TargetModel):
 
 def adrgen_gen():
        for i in range(10):
-               print("Address:  " + str(i))
+               print("Address:  " + hex(i))
                yield Token("address", {"a": i})
 
 class SimAdrGen(SimActor):
@@ -36,7 +36,7 @@ def dumper_gen():
        while True:
                t = Token("data", idle_wait=True)
                yield t
-               print("Received: " + str(t.value["d"]))
+               print("Received: " + hex(t.value["d"]))
 
 class SimDumper(SimActor):
        def __init__(self):
@@ -47,12 +47,12 @@ def trgen_gen():
        for i in range(10):
                a = i
                d = i+10
-               print("Address: " + str(a) + " Data: " + str(d))
+               print("Address: " + hex(a) + " Data: " + hex(d))
                yield Token("address_data", {"a": a, "d": d})
 
 class SimTrGen(SimActor):
-       def __init__(self):
-               self.address_data = Source([("a", 30), ("d", 32)])
+       def __init__(self, a_nbits):
+               self.address_data = Source([("a", a_nbits), ("d", 32)])
                SimActor.__init__(self, trgen_gen())
 
 class TBWishbone(Module):
@@ -78,7 +78,7 @@ class TBWishboneReader(TBWishbone):
 
 class TBWishboneWriter(TBWishbone):
        def __init__(self):
-               self.trgen = SimTrGen()
+               self.trgen = SimTrGen(30)
                self.writer = dma_wishbone.Writer()
                g = DataFlowGraph()
                g.add_connection(self.trgen, self.writer)
@@ -89,28 +89,42 @@ class TBWishboneWriter(TBWishbone):
                s.interrupt = self.trgen.token_exchanger.done and not s.rd(self.comp.busy)
 
 class TBAsmi(Module):
-       def __init__(self, hub):
-               self.submodules.peripheral = asmibus.Target(MyModelASMI(), hub)
-               self.submodules.tap = asmibus.Tap(hub)
-
-class TBAsmiReader(TBAsmi):
        def __init__(self, nslots):
                self.submodules.hub = asmibus.Hub(32, 32)
-               port = self.hub.get_port(nslots)
+               self.port = self.hub.get_port(nslots)
                self.hub.finalize()
+
+               self.submodules.peripheral = asmibus.Target(MyModelASMI(), self.hub)
+               self.submodules.tap = asmibus.Tap(self.hub)
+
+class TBAsmiReader(TBAsmi):
+       def __init__(self, nslots):
+               TBAsmi.__init__(self, nslots)
                
                self.adrgen = SimAdrGen(32)
-               self.reader = dma_asmi.Reader(port)
+               self.reader = dma_asmi.Reader(self.port)
                self.dumper = SimDumper()
                g = DataFlowGraph()
                g.add_connection(self.adrgen, self.reader)
                g.add_connection(self.reader, self.dumper)
                self.submodules.comp = CompositeActor(g)
-               TBAsmi.__init__(self, self.hub)
 
        def do_simulation(self, s):
                s.interrupt = self.adrgen.token_exchanger.done and not s.rd(self.comp.busy)
 
+class TBAsmiWriter(TBAsmi):
+       def __init__(self, nslots):
+               TBAsmi.__init__(self, nslots)
+               
+               self.trgen = SimTrGen(32)
+               self.writer = dma_asmi.Writer(self.port)
+               g = DataFlowGraph()
+               g.add_connection(self.trgen, self.writer)
+               self.submodules.comp = CompositeActor(g)
+               
+       def do_simulation(self, s):
+               s.interrupt = self.trgen.token_exchanger.done and not s.rd(self.comp.busy)
+
 def test_wb_reader():
        print("*** Testing Wishbone reader")
        Simulator(TBWishboneReader()).run()
@@ -123,7 +137,13 @@ def test_asmi_reader(nslots):
        print("*** Testing ASMI reader (nslots={})".format(nslots))
        Simulator(TBAsmiReader(nslots)).run()
 
+def test_asmi_writer(nslots):
+       print("*** Testing ASMI writer (nslots={})".format(nslots))
+       Simulator(TBAsmiWriter(nslots)).run()
+
 test_wb_reader()
 test_wb_writer()
 test_asmi_reader(1)
 test_asmi_reader(2)
+test_asmi_writer(1)
+test_asmi_writer(2)
index 9ff46dedb307e50a10c1f1d98a9cd8abeb3d7bbf..c348c4f794d31d3fb925ebb941f770caba1d4bd1 100644 (file)
@@ -76,8 +76,87 @@ class OOOReader(Module):
                        rob.tag_call.eq(port.tag_call)
                ]
 
+class SequentialWriter(Module):
+       def __init__(self, port):
+               assert(len(port.slots) == 1)
+               self.address_data = Sink([("a", port.hub.aw), ("d", port.hub.dw)])
+               self.busy = Signal()
+
+               ###
+
+               data_reg = Signal(port.hub.dw)
+               self.comb += [
+                       port.adr.eq(self.address_data.payload.a),
+                       port.we.eq(1),
+                       port.stb.eq(self.address_data.stb),
+                       self.address_data.ack.eq(port.ack)
+               ]
+               self.sync += [
+                       port.dat_w.eq(0),
+                       If(port.get_call_expression(),
+                               self.busy.eq(0),
+                               port.dat_w.eq(data_reg)
+                       ),
+                       If(self.address_data.stb & self.address_data.ack,
+                               self.busy.eq(1),
+                               data_reg.eq(self.address_data.payload.d)
+                       )
+               ]
+
+class _WriteSlot(Module):
+       def __init__(self, port, n):
+               self.load_data = Signal(port.hub.dw)
+               self.busy = Signal()
+
+               ###
+
+               drive_data = Signal()
+               data_reg = Signal(port.hub.dw)
+               self.comb += If(drive_data, port.dat_w.eq(data_reg))
+
+               self.sync += [
+                       If(port.stb & port.ack & (port.tag_issue == (port.base + n)),
+                               self.busy.eq(1),
+                               data_reg.eq(self.load_data)
+                       ),
+                       drive_data.eq(0),
+                       If(port.get_call_expression(n),
+                               self.busy.eq(0),
+                               drive_data.eq(1)
+                       )
+               ]
+
+class OOOWriter(Module):
+       def __init__(self, port):
+               assert(len(port.slots) > 1)
+               self.address_data = Sink([("a", port.hub.aw), ("d", port.hub.dw)])
+               self.busy = Signal()
+
+               ###
+
+               self.comb += [
+                       port.adr.eq(self.address_data.payload.a),
+                       port.we.eq(1),
+                       port.stb.eq(self.address_data.stb),
+                       self.address_data.ack.eq(port.ack)
+               ]
+
+               busy = 0
+               for i in range(len(port.slots)):
+                       write_slot = _WriteSlot(port, i)
+                       self.submodules += write_slot
+                       self.comb += write_slot.load_data.eq(self.address_data.payload.d)
+                       busy = busy | write_slot.busy
+               self.comb += self.busy.eq(busy)
+
 def Reader(port):
        if len(port.slots) == 1:
                return SequentialReader(port)
        else:
                return OOOReader(port)
+
+def Writer(port):
+       if len(port.slots) == 1:
+               return SequentialWriter(port)
+       else:
+               return OOOWriter(port)