Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

actorlib/dma_asmi: support for writes

  • Loading branch information...
commit 746e452838036abf22e15763e5f85d1fed1874c4 1 parent e97edd7
@sbourdeauducq sbourdeauducq authored
Showing with 113 additions and 14 deletions.
  1. +34 −14 examples/dataflow/dma.py
  2. +79 −0 migen/actorlib/dma_asmi.py
View
48 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 @@ def do_simulation(self, s):
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 @@ def do_simulation(self, s):
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)
View
79 migen/actorlib/dma_asmi.py
@@ -76,8 +76,87 @@ def __init__(self, port):
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)
Please sign in to comment.
Something went wrong with that request. Please try again.