actorlib/dma_asmi: support for writes

This commit is contained in:
Sebastien Bourdeauducq 2013-04-28 18:06:36 +02:00
parent e97edd7253
commit 746e452838
2 changed files with 113 additions and 14 deletions

View 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)
def __init__(self, nslots):
self.submodules.hub = asmibus.Hub(32, 32)
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):
self.submodules.hub = asmibus.Hub(32, 32)
port = self.hub.get_port(nslots)
self.hub.finalize()
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 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)