axi_dmac: Prevent destination AXI burst length truncation
The width of the AXI burst length field depends on the AXI standard
version. For AXI3 the width is 4 bits allowing a maximum burst length of 16
beats, for AXI4 it is 8 bits wide allowing a maximum burst length of 256
beats.
At the moment the width of the length signals are determined by type of the
source AXI interface, even if the source interface type is not AXI. This
means if the source interface is set to AXI3 and the destination interface
is set to AXI4 the internal width of the signal for all interfaces will be
4 bits. This leads to a truncation of the destination bus length field,
which is supposed to be 8 bits.
If burst are generated that are longer than 16 beats the upper bits of the
length signal will be truncated. The result of this will be that the
external AXI slave interface (e.g. the DDR memory) and the internal logic
in the DMA disagree about burst length. The DMA will eventually lock up
when its internal buffers are full.
To avoid this issue have different configuration parameters for the source
and destination interface that configure the AXI bus length field width.
This way one of the interfaces can be configured for AXI3 and the other for
AXI4 without interfering with each other.
Fixes: commit 495d2f3056
("axi_dmac: Propagate awlen/arlen width through the core")
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
main
parent
a3cd70ff1d
commit
e609c7fd3b
|
@ -617,7 +617,8 @@ dmac_request_arb #(
|
|||
.MAX_BYTES_PER_BURST(MAX_BYTES_PER_BURST),
|
||||
.FIFO_SIZE(FIFO_SIZE),
|
||||
.ID_WIDTH(ID_WIDTH),
|
||||
.AXI_LENGTH_WIDTH(8-(4*DMA_AXI_PROTOCOL_SRC))
|
||||
.AXI_LENGTH_WIDTH_SRC(8-(4*DMA_AXI_PROTOCOL_SRC)),
|
||||
.AXI_LENGTH_WIDTH_DEST(8-(4*DMA_AXI_PROTOCOL_DEST))
|
||||
) i_request_arb (
|
||||
.req_aclk(s_axi_aclk),
|
||||
.req_aresetn(s_axi_aresetn),
|
||||
|
|
|
@ -51,7 +51,8 @@ module dmac_request_arb #(
|
|||
parameter MAX_BYTES_PER_BURST = 128,
|
||||
parameter FIFO_SIZE = 4,
|
||||
parameter ID_WIDTH = $clog2(FIFO_SIZE*2),
|
||||
parameter AXI_LENGTH_WIDTH = 8)(
|
||||
parameter AXI_LENGTH_WIDTH_SRC = 8,
|
||||
parameter AXI_LENGTH_WIDTH_DEST = 8)(
|
||||
|
||||
input req_aclk,
|
||||
input req_aresetn,
|
||||
|
@ -77,7 +78,7 @@ module dmac_request_arb #(
|
|||
|
||||
// Write address
|
||||
output [DMA_AXI_ADDR_WIDTH-1:0] m_axi_awaddr,
|
||||
output [AXI_LENGTH_WIDTH-1:0] m_axi_awlen,
|
||||
output [AXI_LENGTH_WIDTH_DEST-1:0] m_axi_awlen,
|
||||
output [ 2:0] m_axi_awsize,
|
||||
output [ 1:0] m_axi_awburst,
|
||||
output [ 2:0] m_axi_awprot,
|
||||
|
@ -101,7 +102,7 @@ module dmac_request_arb #(
|
|||
input m_axi_arready,
|
||||
output m_axi_arvalid,
|
||||
output [DMA_AXI_ADDR_WIDTH-1:0] m_axi_araddr,
|
||||
output [AXI_LENGTH_WIDTH-1:0] m_axi_arlen,
|
||||
output [AXI_LENGTH_WIDTH_SRC-1:0] m_axi_arlen,
|
||||
output [ 2:0] m_axi_arsize,
|
||||
output [ 1:0] m_axi_arburst,
|
||||
output [ 2:0] m_axi_arprot,
|
||||
|
@ -402,7 +403,7 @@ dmac_dest_mm_axi #(
|
|||
.DMA_ADDR_WIDTH(DMA_AXI_ADDR_WIDTH),
|
||||
.BEATS_PER_BURST_WIDTH(BEATS_PER_BURST_WIDTH_DEST),
|
||||
.BYTES_PER_BEAT_WIDTH(BYTES_PER_BEAT_WIDTH_DEST),
|
||||
.AXI_LENGTH_WIDTH(AXI_LENGTH_WIDTH)
|
||||
.AXI_LENGTH_WIDTH(AXI_LENGTH_WIDTH_DEST)
|
||||
) i_dest_dma_mm (
|
||||
.m_axi_aclk(m_dest_axi_aclk),
|
||||
.m_axi_aresetn(dest_resetn),
|
||||
|
@ -615,7 +616,7 @@ dmac_src_mm_axi #(
|
|||
.DMA_ADDR_WIDTH(DMA_AXI_ADDR_WIDTH),
|
||||
.BEATS_PER_BURST_WIDTH(BEATS_PER_BURST_WIDTH_SRC),
|
||||
.BYTES_PER_BEAT_WIDTH(BYTES_PER_BEAT_WIDTH_SRC),
|
||||
.AXI_LENGTH_WIDTH(AXI_LENGTH_WIDTH)
|
||||
.AXI_LENGTH_WIDTH(AXI_LENGTH_WIDTH_SRC)
|
||||
) i_src_dma_mm (
|
||||
.m_axi_aclk(m_src_axi_aclk),
|
||||
.m_axi_aresetn(src_resetn),
|
||||
|
|
Loading…
Reference in New Issue