mirror of
https://github.com/enjoy-digital/litedram.git
synced 2025-01-04 09:52:25 -05:00
frontend: add AXI support for dma and bist
This commit is contained in:
parent
57157345cf
commit
522cbc97a1
3 changed files with 55 additions and 21 deletions
|
@ -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))
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
|
||||||
]
|
]
|
||||||
|
|
Loading…
Reference in a new issue