mirror of
https://github.com/enjoy-digital/litex.git
synced 2025-01-04 09:52:26 -05:00
actorlib/dma_asmi: support for writes
This commit is contained in:
parent
e97edd7253
commit
746e452838
2 changed files with 113 additions and 14 deletions
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in a new issue