Skip to content

Commit

Permalink
actorlib/dma_asmi: support for writes
Browse files Browse the repository at this point in the history
  • Loading branch information
Sebastien Bourdeauducq committed Apr 28, 2013
1 parent e97edd7 commit 746e452
Show file tree
Hide file tree
Showing 2 changed files with 113 additions and 14 deletions.
48 changes: 34 additions & 14 deletions examples/dataflow/dma.py
Expand Up @@ -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):
Expand All @@ -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):
Expand All @@ -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):
Expand All @@ -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)
Expand All @@ -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()
Expand All @@ -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)
79 changes: 79 additions & 0 deletions migen/actorlib/dma_asmi.py
Expand Up @@ -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)

0 comments on commit 746e452

Please sign in to comment.