From: Sebastien Bourdeauducq Date: Sun, 28 Apr 2013 16:06:36 +0000 (+0200) Subject: actorlib/dma_asmi: support for writes X-Git-Tag: 24jan2021_ls180~2099^2~597 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=746e452838036abf22e15763e5f85d1fed1874c4;p=litex.git actorlib/dma_asmi: support for writes --- diff --git a/examples/dataflow/dma.py b/examples/dataflow/dma.py index 38d77300..c46ee4a6 100644 --- a/examples/dataflow/dma.py +++ b/examples/dataflow/dma.py @@ -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) diff --git a/migen/actorlib/dma_asmi.py b/migen/actorlib/dma_asmi.py index 9ff46ded..c348c4f7 100644 --- a/migen/actorlib/dma_asmi.py +++ b/migen/actorlib/dma_asmi.py @@ -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)