frontend: add AXI support for dma and bist

This commit is contained in:
Florent Kermarrec 2018-08-21 14:49:10 +02:00
parent 57157345cf
commit 522cbc97a1
3 changed files with 55 additions and 21 deletions

View file

@ -38,10 +38,11 @@ def r_description(data_width, id_width):
class LiteDRAMAXIPort(Record): class LiteDRAMAXIPort(Record):
def __init__(self, data_width, address_width, id_width): def __init__(self, data_width, address_width, id_width, clock_domain="sys"):
self.data_width = data_width self.data_width = data_width
self.address_width = address_width self.address_width = address_width
self.id_width = id_width self.id_width = id_width
self.clock_domain = clock_domain
self.aw = stream.Endpoint(aw_description(address_width, id_width)) self.aw = stream.Endpoint(aw_description(address_width, id_width))
self.w = stream.Endpoint(w_description(data_width)) self.w = stream.Endpoint(w_description(data_width))

View file

@ -1,4 +1,4 @@
"""Built In Self Test (BIST) modules for testing liteDRAM functionality.""" """Built In Self Test (BIST) modules for testing LiteDRAM functionality."""
from functools import reduce from functools import reduce
from operator import xor from operator import xor

View file

@ -4,6 +4,9 @@ from migen import *
from litex.soc.interconnect import stream from litex.soc.interconnect import stream
from litedram.common import LiteDRAMNativePort
from litedram.frontend.axi import LiteDRAMAXIPort
class LiteDRAMDMAReader(Module): class LiteDRAMDMAReader(Module):
"""Read data from DRAM memory. """Read data from DRAM memory.
@ -13,8 +16,8 @@ class LiteDRAMDMAReader(Module):
Parameters Parameters
---------- ----------
port : dram_port port : port
Port on the DRAM memory controller to read from. Port on the DRAM memory controller to read from (Native or AXI).
fifo_depth : int fifo_depth : int
How many request results the output FIFO can contain (and thus how many How many request results the output FIFO can contain (and thus how many
@ -38,16 +41,29 @@ class LiteDRAMDMAReader(Module):
# # # # # #
# native / axi selection
is_native = isinstance(port, LiteDRAMNativePort)
is_axi = isinstance(port, LiteDRAMAXIPort)
if is_native:
(cmd, rdata) = port.cmd, port.rdata
elif is_axi:
(cmd, rdata) = port.ar, port.r
else:
raise NotImplementedError
# request issuance # request issuance
request_enable = Signal() request_enable = Signal()
request_issued = Signal() request_issued = Signal()
if is_native:
self.comb += cmd.we.eq(0)
self.comb += cmd.adr.eq(sink.address) # FIXME: use addr for both
if is_axi:
self.comb += cmd.addr.eq(sink.address) # FIXME: use addr for both
self.comb += [ self.comb += [
port.cmd.we.eq(0), cmd.valid.eq(sink.valid & request_enable),
port.cmd.valid.eq(sink.valid & request_enable), sink.ready.eq(cmd.ready & request_enable),
port.cmd.adr.eq(sink.address), request_issued.eq(cmd.valid & cmd.ready)
sink.ready.eq(port.cmd.ready & request_enable),
request_issued.eq(port.cmd.valid & port.cmd.ready)
] ]
# FIFO reservation level counter # FIFO reservation level counter
@ -69,7 +85,7 @@ class LiteDRAMDMAReader(Module):
self.submodules += fifo self.submodules += fifo
self.comb += [ self.comb += [
port.rdata.connect(fifo.sink, omit=["bank"]), rdata.connect(fifo.sink, omit={"bank", "id"}),
fifo.source.connect(source), fifo.source.connect(source),
data_dequeued.eq(source.valid & source.ready) data_dequeued.eq(source.valid & source.ready)
] ]
@ -80,8 +96,8 @@ class LiteDRAMDMAWriter(Module):
Parameters Parameters
---------- ----------
port : dram_port port : port
Port on the DRAM memory controller to write to. Port on the DRAM memory controller to write to (Native or AXI).
fifo_depth : int fifo_depth : int
How many requests the input FIFO can contain (and thus how many write How many requests the input FIFO can contain (and thus how many write
@ -96,26 +112,43 @@ class LiteDRAMDMAWriter(Module):
Sink for DRAM addresses and DRAM data word to be written too. Sink for DRAM addresses and DRAM data word to be written too.
""" """
def __init__(self, port, fifo_depth=16, fifo_buffered=False): def __init__(self, port, fifo_depth=16, fifo_buffered=False):
assert isinstance(port, (LiteDRAMNativePort, LiteDRAMAXIPort))
self.sink = sink = stream.Endpoint([("address", port.address_width), self.sink = sink = stream.Endpoint([("address", port.address_width),
("data", port.data_width)]) ("data", port.data_width)])
# # # # # #
# native / axi selection
is_native = isinstance(port, LiteDRAMNativePort)
is_axi = isinstance(port, LiteDRAMAXIPort)
if is_native:
(cmd, wdata) = port.cmd, port.wdata
elif is_axi:
(cmd, wdata) = port.aw, port.w
else:
raise NotImplementedError
fifo = stream.SyncFIFO([("data", port.data_width)], fifo_depth, fifo_buffered) fifo = stream.SyncFIFO([("data", port.data_width)], fifo_depth, fifo_buffered)
self.submodules += fifo self.submodules += fifo
if is_native:
self.comb += cmd.we.eq(1)
self.comb += cmd.adr.eq(sink.address) # FIXME: use addr for both
if is_axi:
self.comb += cmd.addr.eq(sink.address) # FIXME: use addr for both
self.comb += [ self.comb += [
port.cmd.we.eq(1), cmd.valid.eq(fifo.sink.ready & sink.valid),
port.cmd.valid.eq(fifo.sink.ready & sink.valid), sink.ready.eq(fifo.sink.ready & cmd.ready),
port.cmd.adr.eq(sink.address), fifo.sink.valid.eq(sink.valid & cmd.ready),
sink.ready.eq(fifo.sink.ready & port.cmd.ready),
fifo.sink.valid.eq(sink.valid & port.cmd.ready),
fifo.sink.data.eq(sink.data) fifo.sink.data.eq(sink.data)
] ]
if is_native:
self.comb += wdata.we.eq(2**(port.data_width//8)-1)
if is_axi:
self.comb += wdata.strb.eq(2**(port.data_width//8)-1)
self.comb += [ self.comb += [
port.wdata.valid.eq(fifo.source.valid), wdata.valid.eq(fifo.source.valid),
fifo.source.ready.eq(port.wdata.ready), fifo.source.ready.eq(wdata.ready),
port.wdata.we.eq(2**(port.data_width//8)-1), wdata.data.eq(fifo.source.data)
port.wdata.data.eq(fifo.source.data)
] ]