AXI DMAC#
The AXI DMA Controller IP core is a high-speed, high-throughput, general purpose DMA controller intended to be used to transfer data between system memory and other peripherals like high-speed converters.
Features#
Supports multiple interface types
AXI3/4 memory mapped
AXI4 Streaming
ADI FIFO interface
Zero-latency transfer switch-over architecture
Allows continuous high-speed streaming
Cyclic transfers
2D transfers
Scatter-Gather transfers
Utilization#
Device Family |
LUTs |
FFs |
---|---|---|
Intel Arria 10 |
TBD |
TBD |
Xilinx Artix 7 |
TBD |
TBD |
Xilinx Kintex 7 |
TBD |
TBD |
Xilinx Virtex 7 |
TBD |
TBD |
Files#
Name |
Description |
---|---|
Verilog source for the peripheral. |
Block Diagram#
Configuration Parameters#
Name |
Description |
Default Value |
Choices/Range |
---|---|---|---|
ID |
Instance identification number. |
0 |
|
DMA_DATA_WIDTH_SRC |
Data path width of the source interface in bits. |
64 |
16, 32, 64, 128, 256, 512, 1024, 2048 |
DMA_DATA_WIDTH_DEST |
Data path width of the destination interface in bits. |
64 |
|
DMA_DATA_WIDTH_SG |
Data path width of the scatter-gather interface in bits. |
64 |
64 |
DMA_LENGTH_WIDTH |
Width of transfer length control register in bits. Limits length of the transfers to 2** |
24 |
From 8 to 32. |
DMA_2D_TRANSFER |
Enable support for 2D transfers. |
False |
|
DMA_SG_TRANSFER |
Enable support for scatter-gather transfers. |
False |
|
ASYNC_CLK_REQ_SRC |
Whether the request and source clock domains are asynchronous. |
True |
|
ASYNC_CLK_SRC_DEST |
Whether the source and destination clock domains are asynchronous. |
True |
|
ASYNC_CLK_DEST_REQ |
Whether the destination and request clock domains are asynchronous. |
True |
|
ASYNC_CLK_REQ_SG |
Whether the request and scatter-gather clock domains are asynchronous. |
True |
|
ASYNC_CLK_SRC_SG |
Whether the source and scatter-gather clock domains are asynchronous. |
True |
|
ASYNC_CLK_DEST_SG |
Whether the destination and scatter-gather clock domains are asynchronous. |
True |
|
AXI_SLICE_DEST |
Whether to insert an extra register slice on the source data path. |
False |
|
AXI_SLICE_SRC |
Whether to insert an extra register slice on the destination data path. |
False |
|
AXIS_TUSER_SYNC |
Transfer Start Synchronization on TUSER |
True |
|
SYNC_TRANSFER_START |
Enable the transfer start synchronization feature. |
False |
|
CYCLIC |
Enable support for Cyclic transfers. |
False |
|
DMA_AXI_PROTOCOL_DEST |
AXI protocol version of the destination interface (0 = AXI4, 1 = AXI3). |
0 |
AXI3 (1), AXI4 (0) |
DMA_AXI_PROTOCOL_SRC |
AXI protocol version of the source interface (0 = AXI4, 1 = AXI3). |
0 |
|
DMA_AXI_PROTOCOL_SG |
AXI protocol version of the scatter-gather interface (0 = AXI4, 1 = AXI3). |
0 |
|
DMA_TYPE_DEST |
Interface type for the destination interface (0 = AXI-MM, 1 = AXI-Streaming, 2 = ADI-FIFO). |
0 |
Memory-Mapped AXI (0), Streaming AXI (1), FIFO Interface (2) |
DMA_TYPE_SRC |
Interface type for the source interface (0 = AXI-MM, 1 = AXI-Streaming, 2 = ADI-FIFO). |
2 |
|
DMA_AXI_ADDR_WIDTH |
Maximum address width for AXI interfaces. |
32 |
From 16 to 64. |
MAX_BYTES_PER_BURST |
Maximum size of bursts in bytes. Must be power of 2 in a range of 2 beats to 4096 bytes The size of the burst is limited by the largest burst that both source and destination supports. This depends on the selected protocol. For AXI3 the maximum beats per burst is 16, while for AXI4 is 256. For non AXI interfaces the maximum beats per burst is in theory unlimited but it is set to 1024 to provide a reasonable upper threshold. This limitation is done internally in the core. |
128 |
|
FIFO_SIZE |
Size of the store-and-forward memory in bursts. Size of a burst is defined by the |
8 |
2, 4, 8, 16, 32 |
AXI_ID_WIDTH_SRC |
Axi Id Width Src. |
1 |
|
AXI_ID_WIDTH_DEST |
Axi Id Width Dest. |
1 |
|
AXI_ID_WIDTH_SG |
Axi Id Width Sg. |
1 |
|
DMA_AXIS_ID_W |
Dma Axis Id W. |
8 |
|
DMA_AXIS_DEST_W |
Dma Axis Dest W. |
4 |
|
DISABLE_DEBUG_REGISTERS |
Disable debug registers. |
False |
|
ENABLE_DIAGNOSTICS_IF |
Add insight into internal operation of the core, for debug purposes only. |
False |
|
ALLOW_ASYM_MEM |
Allow Asym Mem. |
0 |
|
CACHE_COHERENT |
Cache Coherent. |
False |
|
AXI_AXCACHE |
ARCACHE/AWCACHE. |
'b0011 |
|
AXI_AXPROT |
ARPROT/AWPROT. |
'b000 |
Interface#
Physical Port |
Logical Port |
Direction |
Dependency |
---|---|---|---|
s_axi_awaddr |
AWADDR |
in [10:0] |
|
s_axi_awprot |
AWPROT |
in [2:0] |
|
s_axi_awvalid |
AWVALID |
in |
|
s_axi_awready |
AWREADY |
out |
|
s_axi_wdata |
WDATA |
in [31:0] |
|
s_axi_wstrb |
WSTRB |
in [3:0] |
|
s_axi_wvalid |
WVALID |
in |
|
s_axi_wready |
WREADY |
out |
|
s_axi_bresp |
BRESP |
out [1:0] |
|
s_axi_bvalid |
BVALID |
out |
|
s_axi_bready |
BREADY |
in |
|
s_axi_araddr |
ARADDR |
in [10:0] |
|
s_axi_arprot |
ARPROT |
in [2:0] |
|
s_axi_arvalid |
ARVALID |
in |
|
s_axi_arready |
ARREADY |
out |
|
s_axi_rdata |
RDATA |
out [31:0] |
|
s_axi_rresp |
RRESP |
out [1:0] |
|
s_axi_rvalid |
RVALID |
out |
|
s_axi_rready |
RREADY |
in |
Physical Port |
Logical Port |
Direction |
Dependency |
---|---|---|---|
s_axi_aclk |
CLK |
in |
Physical Port |
Logical Port |
Direction |
Dependency |
---|---|---|---|
s_axi_aresetn |
RST |
in |
Physical Port |
Logical Port |
Direction |
Dependency |
---|---|---|---|
m_dest_axi_awid |
AWID |
out [0:0] |
Disabled |
m_dest_axi_awaddr |
AWADDR |
out [31:0] |
DMA_TYPE_DEST = 0 |
m_dest_axi_awlen |
AWLEN |
out [7:0] |
DMA_TYPE_DEST = 0 |
m_dest_axi_awsize |
AWSIZE |
out [2:0] |
DMA_TYPE_DEST = 0 |
m_dest_axi_awburst |
AWBURST |
out [1:0] |
DMA_TYPE_DEST = 0 |
m_dest_axi_awlock |
AWLOCK |
out [0:0] |
Disabled |
m_dest_axi_awcache |
AWCACHE |
out [3:0] |
DMA_TYPE_DEST = 0 |
m_dest_axi_awprot |
AWPROT |
out [2:0] |
DMA_TYPE_DEST = 0 |
m_dest_axi_awvalid |
AWVALID |
out |
DMA_TYPE_DEST = 0 |
m_dest_axi_awready |
AWREADY |
in |
DMA_TYPE_DEST = 0 |
m_dest_axi_wid |
WID |
out [0:0] |
Disabled |
m_dest_axi_wdata |
WDATA |
out [63:0] |
DMA_TYPE_DEST = 0 |
m_dest_axi_wstrb |
WSTRB |
out [7:0] |
DMA_TYPE_DEST = 0 |
m_dest_axi_wlast |
WLAST |
out |
DMA_TYPE_DEST = 0 |
m_dest_axi_wvalid |
WVALID |
out |
DMA_TYPE_DEST = 0 |
m_dest_axi_wready |
WREADY |
in |
DMA_TYPE_DEST = 0 |
m_dest_axi_bid |
BID |
in [0:0] |
Disabled |
m_dest_axi_bresp |
BRESP |
in [1:0] |
DMA_TYPE_DEST = 0 |
m_dest_axi_bvalid |
BVALID |
in |
DMA_TYPE_DEST = 0 |
m_dest_axi_bready |
BREADY |
out |
DMA_TYPE_DEST = 0 |
m_dest_axi_arid |
ARID |
out [0:0] |
Disabled |
m_dest_axi_araddr |
ARADDR |
out [31:0] |
Disabled |
m_dest_axi_arlen |
ARLEN |
out [7:0] |
Disabled |
m_dest_axi_arsize |
ARSIZE |
out [2:0] |
Disabled |
m_dest_axi_arburst |
ARBURST |
out [1:0] |
Disabled |
m_dest_axi_arlock |
ARLOCK |
out [0:0] |
Disabled |
m_dest_axi_arcache |
ARCACHE |
out [3:0] |
Disabled |
m_dest_axi_arprot |
ARPROT |
out [2:0] |
Disabled |
m_dest_axi_arvalid |
ARVALID |
out |
Disabled |
m_dest_axi_arready |
ARREADY |
in |
Disabled |
m_dest_axi_rid |
RID |
in [0:0] |
Disabled |
m_dest_axi_rdata |
RDATA |
in [63:0] |
Disabled |
m_dest_axi_rresp |
RRESP |
in [1:0] |
Disabled |
m_dest_axi_rlast |
RLAST |
in |
Disabled |
m_dest_axi_rvalid |
RVALID |
in |
Disabled |
m_dest_axi_rready |
RREADY |
out |
Disabled |
Physical Port |
Logical Port |
Direction |
Dependency |
---|---|---|---|
m_sg_axi_awid |
AWID |
out [0:0] |
Disabled |
m_sg_axi_awaddr |
AWADDR |
out [31:0] |
Disabled |
m_sg_axi_awlen |
AWLEN |
out [7:0] |
Disabled |
m_sg_axi_awsize |
AWSIZE |
out [2:0] |
Disabled |
m_sg_axi_awburst |
AWBURST |
out [1:0] |
Disabled |
m_sg_axi_awlock |
AWLOCK |
out [0:0] |
Disabled |
m_sg_axi_awcache |
AWCACHE |
out [3:0] |
Disabled |
m_sg_axi_awprot |
AWPROT |
out [2:0] |
Disabled |
m_sg_axi_awvalid |
AWVALID |
out |
Disabled |
m_sg_axi_awready |
AWREADY |
in |
Disabled |
m_sg_axi_wid |
WID |
out [0:0] |
Disabled |
m_sg_axi_wdata |
WDATA |
out [63:0] |
Disabled |
m_sg_axi_wstrb |
WSTRB |
out [7:0] |
Disabled |
m_sg_axi_wlast |
WLAST |
out |
Disabled |
m_sg_axi_wvalid |
WVALID |
out |
Disabled |
m_sg_axi_wready |
WREADY |
in |
Disabled |
m_sg_axi_bid |
BID |
in [0:0] |
Disabled |
m_sg_axi_bresp |
BRESP |
in [1:0] |
Disabled |
m_sg_axi_bvalid |
BVALID |
in |
Disabled |
m_sg_axi_bready |
BREADY |
out |
Disabled |
m_sg_axi_arid |
ARID |
out [0:0] |
Disabled |
m_sg_axi_araddr |
ARADDR |
out [31:0] |
DMA_SG_TRANSFER = 1 |
m_sg_axi_arlen |
ARLEN |
out [7:0] |
DMA_SG_TRANSFER = 1 |
m_sg_axi_arsize |
ARSIZE |
out [2:0] |
DMA_SG_TRANSFER = 1 |
m_sg_axi_arburst |
ARBURST |
out [1:0] |
DMA_SG_TRANSFER = 1 |
m_sg_axi_arlock |
ARLOCK |
out [0:0] |
Disabled |
m_sg_axi_arcache |
ARCACHE |
out [3:0] |
DMA_SG_TRANSFER = 1 |
m_sg_axi_arprot |
ARPROT |
out [2:0] |
DMA_SG_TRANSFER = 1 |
m_sg_axi_arvalid |
ARVALID |
out |
DMA_SG_TRANSFER = 1 |
m_sg_axi_arready |
ARREADY |
in |
DMA_SG_TRANSFER = 1 |
m_sg_axi_rid |
RID |
in [0:0] |
Disabled |
m_sg_axi_rdata |
RDATA |
in [63:0] |
DMA_SG_TRANSFER = 1 |
m_sg_axi_rresp |
RRESP |
in [1:0] |
DMA_SG_TRANSFER = 1 |
m_sg_axi_rlast |
RLAST |
in |
DMA_SG_TRANSFER = 1 |
m_sg_axi_rvalid |
RVALID |
in |
DMA_SG_TRANSFER = 1 |
m_sg_axi_rready |
RREADY |
out |
DMA_SG_TRANSFER = 1 |
Physical Port |
Logical Port |
Direction |
Dependency |
---|---|---|---|
m_src_axi_awid |
AWID |
out [0:0] |
Disabled |
m_src_axi_awaddr |
AWADDR |
out [31:0] |
Disabled |
m_src_axi_awlen |
AWLEN |
out [7:0] |
Disabled |
m_src_axi_awsize |
AWSIZE |
out [2:0] |
Disabled |
m_src_axi_awburst |
AWBURST |
out [1:0] |
Disabled |
m_src_axi_awlock |
AWLOCK |
out [0:0] |
Disabled |
m_src_axi_awcache |
AWCACHE |
out [3:0] |
Disabled |
m_src_axi_awprot |
AWPROT |
out [2:0] |
Disabled |
m_src_axi_awvalid |
AWVALID |
out |
Disabled |
m_src_axi_awready |
AWREADY |
in |
Disabled |
m_src_axi_wid |
WID |
out [0:0] |
Disabled |
m_src_axi_wdata |
WDATA |
out [63:0] |
Disabled |
m_src_axi_wstrb |
WSTRB |
out [7:0] |
Disabled |
m_src_axi_wlast |
WLAST |
out |
Disabled |
m_src_axi_wvalid |
WVALID |
out |
Disabled |
m_src_axi_wready |
WREADY |
in |
Disabled |
m_src_axi_bid |
BID |
in [0:0] |
Disabled |
m_src_axi_bresp |
BRESP |
in [1:0] |
Disabled |
m_src_axi_bvalid |
BVALID |
in |
Disabled |
m_src_axi_bready |
BREADY |
out |
Disabled |
m_src_axi_arid |
ARID |
out [0:0] |
Disabled |
m_src_axi_araddr |
ARADDR |
out [31:0] |
DMA_TYPE_SRC = 0 |
m_src_axi_arlen |
ARLEN |
out [7:0] |
DMA_TYPE_SRC = 0 |
m_src_axi_arsize |
ARSIZE |
out [2:0] |
DMA_TYPE_SRC = 0 |
m_src_axi_arburst |
ARBURST |
out [1:0] |
DMA_TYPE_SRC = 0 |
m_src_axi_arlock |
ARLOCK |
out [0:0] |
Disabled |
m_src_axi_arcache |
ARCACHE |
out [3:0] |
DMA_TYPE_SRC = 0 |
m_src_axi_arprot |
ARPROT |
out [2:0] |
DMA_TYPE_SRC = 0 |
m_src_axi_arvalid |
ARVALID |
out |
DMA_TYPE_SRC = 0 |
m_src_axi_arready |
ARREADY |
in |
DMA_TYPE_SRC = 0 |
m_src_axi_rid |
RID |
in [0:0] |
Disabled |
m_src_axi_rdata |
RDATA |
in [63:0] |
DMA_TYPE_SRC = 0 |
m_src_axi_rresp |
RRESP |
in [1:0] |
DMA_TYPE_SRC = 0 |
m_src_axi_rlast |
RLAST |
in |
DMA_TYPE_SRC = 0 |
m_src_axi_rvalid |
RVALID |
in |
DMA_TYPE_SRC = 0 |
m_src_axi_rready |
RREADY |
out |
DMA_TYPE_SRC = 0 |
Physical Port |
Logical Port |
Direction |
Dependency |
---|---|---|---|
fifo_rd_clk |
CLK |
in |
DMA_TYPE_DEST = 2 |
Physical Port |
Logical Port |
Direction |
Dependency |
---|---|---|---|
fifo_wr_clk |
CLK |
in |
DMA_TYPE_SRC = 2 |
Physical Port |
Logical Port |
Direction |
Dependency |
---|---|---|---|
m_axis_aclk |
CLK |
in |
DMA_TYPE_DEST = 1 |
Physical Port |
Logical Port |
Direction |
Dependency |
---|---|---|---|
m_dest_axi_aclk |
CLK |
in |
DMA_TYPE_DEST = 0 |
Physical Port |
Logical Port |
Direction |
Dependency |
---|---|---|---|
m_sg_axi_aclk |
CLK |
in |
DMA_SG_TRANSFER = 1 |
Physical Port |
Logical Port |
Direction |
Dependency |
---|---|---|---|
m_src_axi_aclk |
CLK |
in |
DMA_TYPE_SRC = 0 |
Physical Port |
Logical Port |
Direction |
Dependency |
---|---|---|---|
s_axis_aclk |
CLK |
in |
DMA_TYPE_SRC = 1 |
Physical Port |
Logical Port |
Direction |
Dependency |
---|---|---|---|
m_dest_axi_aresetn |
RST |
in |
DMA_TYPE_DEST = 0 |
Physical Port |
Logical Port |
Direction |
Dependency |
---|---|---|---|
m_sg_axi_aresetn |
RST |
in |
DMA_SG_TRANSFER = 1 |
Physical Port |
Logical Port |
Direction |
Dependency |
---|---|---|---|
m_src_axi_aresetn |
RST |
in |
DMA_TYPE_SRC = 0 |
Physical Port |
Logical Port |
Direction |
Dependency |
---|---|---|---|
s_axis_ready |
TREADY |
out |
DMA_TYPE_SRC = 1 |
s_axis_valid |
TVALID |
in |
DMA_TYPE_SRC = 1 |
s_axis_data |
TDATA |
in [63:0] |
DMA_TYPE_SRC = 1 |
s_axis_strb |
TSTRB |
in [7:0] |
DMA_TYPE_SRC = 1 |
s_axis_keep |
TKEEP |
in [7:0] |
DMA_TYPE_SRC = 1 |
s_axis_user |
TUSER |
in [0:0] |
DMA_TYPE_SRC = 1 |
s_axis_id |
TID |
in [7:0] |
DMA_TYPE_SRC = 1 |
s_axis_dest |
TDEST |
in [3:0] |
DMA_TYPE_SRC = 1 |
s_axis_last |
TLAST |
in |
DMA_TYPE_SRC = 1 |
Physical Port |
Logical Port |
Direction |
Dependency |
---|---|---|---|
m_axis_ready |
TREADY |
in |
DMA_TYPE_DEST = 1 |
m_axis_valid |
TVALID |
out |
DMA_TYPE_DEST = 1 |
m_axis_data |
TDATA |
out [63:0] |
DMA_TYPE_DEST = 1 |
m_axis_strb |
TSTRB |
out [7:0] |
DMA_TYPE_DEST = 1 |
m_axis_keep |
TKEEP |
out [7:0] |
DMA_TYPE_DEST = 1 |
m_axis_user |
TUSER |
out [0:0] |
DMA_TYPE_DEST = 1 |
m_axis_id |
TID |
out [7:0] |
DMA_TYPE_DEST = 1 |
m_axis_dest |
TDEST |
out [3:0] |
DMA_TYPE_DEST = 1 |
m_axis_last |
TLAST |
out |
DMA_TYPE_DEST = 1 |
Physical Port |
Logical Port |
Direction |
Dependency |
---|---|---|---|
fifo_wr_en |
EN |
in |
DMA_TYPE_SRC = 2 |
fifo_wr_din |
DATA |
in [63:0] |
DMA_TYPE_SRC = 2 |
fifo_wr_overflow |
OVERFLOW |
out |
DMA_TYPE_SRC = 2 |
fifo_wr_xfer_req |
XFER_REQ |
out |
DMA_TYPE_SRC = 2 |
Physical Port |
Logical Port |
Direction |
Dependency |
---|---|---|---|
fifo_rd_en |
EN |
in |
DMA_TYPE_DEST = 2 |
fifo_rd_dout |
DATA |
out [63:0] |
DMA_TYPE_DEST = 2 |
fifo_rd_valid |
VALID |
out |
DMA_TYPE_DEST = 2 |
fifo_rd_underflow |
UNDERFLOW |
out |
DMA_TYPE_DEST = 2 |
Physical Port |
Logical Port |
Direction |
Dependency |
---|---|---|---|
irq |
INTERRUPT |
out |
Physical Port |
Direction |
Dependency |
Description |
---|---|---|---|
sync |
in |
SYNC_TRANSFER_START = 1 && DMA_TYPE_SRC != 1 || AXIS_TUSER_SYNC != 1 |
|
s_axis_xfer_req |
out |
DMA_TYPE_SRC = 1 |
|
m_axis_xfer_req |
out |
DMA_TYPE_DEST = 1 |
|
fifo_rd_xfer_req |
out |
DMA_TYPE_DEST = 2 |
|
dest_diag_level_bursts |
out [7:0] |
ENABLE_DIAGNOSTICS_IF = 1 |
Only present when |
Register Map#
DWORD |
BYTE |
Reg Name |
Description |
|||
---|---|---|---|---|---|---|
BITS |
Field Name |
Type |
Default Value |
Description |
||
0x0 |
0x0 |
VERSION |
Version of the peripheral. Follows semantic versioning. Current version 4.05.63. |
|||
[31:16] |
VERSION_MAJOR |
RO |
0x0004 |
|||
[15:8] |
VERSION_MINOR |
RO |
0x05 |
|||
[7:0] |
VERSION_PATCH |
RO |
0x63 |
|||
0x1 |
0x4 |
PERIPHERAL_ID |
||||
[31:0] |
PERIPHERAL_ID |
RO |
ID |
Value of the ID configuration parameter. |
||
0x2 |
0x8 |
SCRATCH |
||||
[31:0] |
SCRATCH |
RW |
0x00000000 |
Scratch register useful for debug. |
||
0x3 |
0xc |
IDENTIFICATION |
||||
[31:0] |
IDENTIFICATION |
RO |
0x444d4143 |
Peripheral identification (‘D’, ‘M’, ‘A’, ‘C’). |
||
0x4 |
0x10 |
INTERFACE_DESCRIPTION_1 |
||||
[3:0] |
BYTES_PER_BEAT_DEST_LOG2 |
RO |
BYTES_PER_BEAT_DEST_LOG2 |
Width of data bus on destination interface. Log2 of interface data widths in bytes.
|
||
[5:4] |
DMA_TYPE_DEST |
RO |
DMA_TYPE_DEST |
Value of |
||
[11:8] |
BYTES_PER_BEAT_SRC_LOG2 |
RO |
BYTES_PER_BEAT_SRC_LOG2 |
Width of data bus on source interface. Log2 of interface data widths in bytes.
|
||
[13:12] |
DMA_TYPE_SRC |
RO |
DMA_TYPE_SRC |
Value of |
||
[19:16] |
BYTES_PER_BURST_WIDTH |
RO |
BYTES_PER_BURST_WIDTH |
Value of |
||
0x5 |
0x14 |
INTERFACE_DESCRIPTION_2 |
||||
[0:0] |
CACHE_COHERENT |
RO |
CACHE_COHERENT |
Value of |
||
[7:4] |
AXI_AXCACHE |
RO |
AXI_AXCACHE |
Value of |
||
[10:8] |
AXI_AXPROT |
RO |
AXI_AXPROT |
Value of |
||
0x20 |
0x80 |
IRQ_MASK |
||||
[1:1] |
TRANSFER_COMPLETED |
RW |
0x1 |
Masks the TRANSFER_COMPLETED IRQ. |
||
[0:0] |
TRANSFER_QUEUED |
RW |
0x1 |
Masks the TRANSFER_QUEUED IRQ. |
||
0x21 |
0x84 |
IRQ_PENDING |
||||
[1:1] |
TRANSFER_COMPLETED |
RW1C |
0x0 |
This bit will be asserted if a transfer has been completed and the TRANSFER_COMPLETED bit in the IRQ_MASK register is not set. Either if all bytes have been transferred or an error occurred during the transfer. |
||
[0:0] |
TRANSFER_QUEUED |
RW1C |
0x0 |
This bit will be asserted if a transfer has been queued and it is possible to queue the next transfer. It can be masked out by setting the TRANSFER_QUEUED bit in the IRQ_MASK register. |
||
0x22 |
0x88 |
IRQ_SOURCE |
||||
[1:1] |
TRANSFER_COMPLETED |
RO |
0x0 |
This bit will be asserted if a transfer has been completed. Either if all bytes have been transferred or an error occurred during the transfer. Cleared together with the corresponding IRQ_PENDING bit. |
||
[0:0] |
TRANSFER_QUEUED |
RO |
0x0 |
This bit will be asserted if a transfer has been queued and it is possible to queue the next transfer. Cleared together with the corresponding IRQ_PENDING bit. |
||
0x100 |
0x400 |
CONTROL |
||||
[2:2] |
HWDESC |
RW |
0x0 |
When set to 1 the scatter-gather transfers are enabled. Note, this field is only valid if the DMA channel has been configured with SG transfer support. |
||
[1:1] |
PAUSE |
RW |
0x0 |
When set to 1 the currently active transfer is paused. It will be resumed once the bit is cleared again. |
||
[0:0] |
ENABLE |
RW |
0x0 |
When set to 1 the DMA channel is enabled. |
||
0x101 |
0x404 |
TRANSFER_ID |
||||
[1:0] |
TRANSFER_ID |
RO |
0x0 |
This register contains the ID of the next transfer. The ID is generated by the DMAC and after the transfer has been started can be used to check if the transfer has finished by checking the corresponding bit in the TRANSFER_DONE register. The contents of this register is only valid if TRANSFER_SUBMIT is 0. |
||
0x102 |
0x408 |
TRANSFER_SUBMIT |
||||
[0:0] |
TRANSFER_SUBMIT |
RW |
0x0 |
Writing a 1 to this register queues a new transfer. The bit transitions back to 0 once the transfer has been queued or the DMA channel is disabled. Writing a 0 to this register has no effect. |
||
0x103 |
0x40c |
FLAGS |
||||
[0:0] |
CYCLIC |
RW |
CYCLIC |
Setting this field to 1 puts the DMA transfer into cyclic mode. In cyclic mode the controller will re-start a transfer again once it has finished. In cyclic mode no end-of-transfer interrupts will be generated. |
||
[1:1] |
TLAST |
RW |
0x1 |
When setting this bit for a MM to AXIS transfer the TLAST signal will be asserted during the last beat of the transfer. For AXIS to MM transfers the TLAST signal from the AXIS interface is monitored. After its occurrence all descriptors are ignored until this bit is set. |
||
[2:2] |
PARTIAL_REPORTING_EN |
RW |
0x0 |
When setting this bit the length of partial transfers caused eventually by TLAST will be recorded. |
||
0x104 |
0x410 |
DEST_ADDRESS |
||||
[31:0] |
DEST_ADDRESS |
RW |
0x00000000 |
This register contains the destination address of the transfer. The address needs to be aligned to the bus width. This register is only valid if the DMA channel has been configured for write to memory support. |
||
0x105 |
0x414 |
SRC_ADDRESS |
||||
[31:0] |
SRC_ADDRESS |
RW |
0x00000000 |
This register contains the source address of the transfer. The address needs to be aligned to the bus width. This register is only valid if the DMA channel has been configured for read from memory support. |
||
0x106 |
0x418 |
X_LENGTH |
||||
[31:0] |
X_LENGTH |
RW |
X_LENGTH |
Number of bytes to transfer - 1.
|
||
0x107 |
0x41c |
Y_LENGTH |
||||
[31:0] |
Y_LENGTH |
RW |
0x00000000 |
Number of rows to transfer - 1. Note, this field is only valid if the DMA channel has been configured with 2D transfer support. |
||
0x108 |
0x420 |
DEST_STRIDE |
||||
[31:0] |
DEST_STRIDE |
RW |
0x00000000 |
The number of bytes between the start of one row and the next row for the destination address. Needs to be aligned to the bus width. Note, this field is only valid if the DMA channel has been configured with 2D transfer support and write to memory support. |
||
0x109 |
0x424 |
SRC_STRIDE |
||||
[31:0] |
SRC_STRIDE |
RW |
0x00000000 |
The number of bytes between the start of one row and the next row for the source address. Needs to be aligned to the bus width. Note, this field is only valid if the DMA channel has been configured with 2D transfer and read from memory support. |
||
0x10a |
0x428 |
TRANSFER_DONE |
If bit x is set in this register the transfer with ID x has been completed. The bit will automatically be cleared when a new transfer with this ID is queued and will be set when the transfer has been completed. |
|||
[0:0] |
TRANSFER_0_DONE |
RO |
0x0 |
If this bit is set the transfer with ID 0 has been completed. |
||
[1:1] |
TRANSFER_1_DONE |
RO |
0x0 |
If this bit is set the transfer with ID 1 has been completed. |
||
[2:2] |
TRANSFER_2_DONE |
RO |
0x0 |
If this bit is set the transfer with ID 2 has been completed. |
||
[3:3] |
TRANSFER_3_DONE |
RO |
0x0 |
If this bit is set the transfer with ID 3 has been completed. |
||
[31:31] |
PARTIAL_TRANSFER_DONE |
RO |
0x0 |
If this bit is set at least one partial transfer was transferred. This field will reset when the ENABLE control bit is reset or when all information on partial transfers was read through PARTIAL_TRANSFER_LENGTH and PARTIAL_TRANSFER_ID registers. |
||
0x10b |
0x42c |
ACTIVE_TRANSFER_ID |
||||
[4:0] |
ACTIVE_TRANSFER_ID |
RO |
0x00 |
ID of the currently active transfer. When no transfer is active this register will be equal to the TRANSFER_ID register. |
||
0x10c |
0x430 |
STATUS |
||||
[31:0] |
RESERVED |
RO |
0x00000000 |
This register is reserved for future usage. Reading it will always return 0. |
||
0x10d |
0x434 |
CURRENT_DEST_ADDRESS |
||||
[31:0] |
CURRENT_DEST_ADDRESS |
RO |
0x00000000 |
Address to which the next data sample is written to. This register is only valid if the DMA channel has been configured for write to memory support. |
||
0x10e |
0x438 |
CURRENT_SRC_ADDRESS |
||||
[31:0] |
CURRENT_SRC_ADDRESS |
RO |
0x00000000 |
Address form which the next data sample is read. This register is only valid if the DMA channel has been configured for read from memory support. |
||
0x112 |
0x448 |
TRANSFER_PROGRESS |
||||
[31:0] |
TRANSFER_PROGRESS |
RO |
0x00000000 |
This field presents the number of bytes transferred to the destination for the current transfer. This register will be cleared once the transfer completes. This should be used for debugging purposes only. |
||
0x113 |
0x44c |
PARTIAL_TRANSFER_LENGTH |
||||
[31:0] |
PARTIAL_LENGTH |
RO |
0x00000000 |
Length of the partial transfer in bytes. Represents the number of bytes received until the moment of TLAST assertion. This will be smaller than the programmed length from the X_LENGTH and Y_LENGTH registers. |
||
0x114 |
0x450 |
PARTIAL_TRANSFER_ID |
Must be read after the PARTIAL_TRANSFER_LENGTH registers. |
|||
[1:0] |
PARTIAL_TRANSFER_ID |
RO |
0x0 |
ID of the transfer that was partial. |
||
0x115 |
0x454 |
DESCRIPTOR_ID |
||||
[31:0] |
DESCRIPTOR_ID |
RO |
0x00000000 |
ID of the descriptor that points to the current memory segment being transferred. If HWDESC is set to 0, then this register returns 0. |
||
0x11f |
0x47c |
SG_ADDRESS |
||||
[31:0] |
SG_ADDRESS |
RW |
0x00000000 |
This register contains the starting address of the scatter-gather transfer. The address needs to be aligned to the bus width. This register is only valid if the DMA channel has been configured with SG transfer support. |
||
0x124 |
0x490 |
DEST_ADDRESS_HIGH |
||||
[31:0] |
DEST_ADDRESS_HIGH |
RW |
0x00000000 |
This register contains the HIGH segment of the destination address of the transfer. This register is only valid if the DMA_AXI_ADDR_WIDTH is bigger than 32 and if DMA channel has been configured for write to memory support. |
||
0x125 |
0x494 |
SRC_ADDRESS_HIGH |
||||
[31:0] |
SRC_ADDRESS_HIGH |
RW |
0x00000000 |
This register contains the HIGH segment of the source address of the transfer. This register is only valid if the DMA_AXI_ADDR_WIDTH is bigger than 32 and if the DMA channel has been configured for read from memory support. |
||
0x126 |
0x498 |
CURRENT_DEST_ADDRESS_HIGH |
||||
[31:0] |
CURRENT_DEST_ADDRESS_HIGH |
RO |
0x00000000 |
HIGH segment of the address to which the next data sample is written to. This register is only valid if the DMA_AXI_ADDR_WIDTH is bigger than 32 and if the DMA channel has been configured for write to memory support. |
||
0x127 |
0x49c |
CURRENT_SRC_ADDRESS_HIGH |
||||
[31:0] |
CURRENT_SRC_ADDRESS_HIGH |
RO |
0x00000000 |
HIGH segment of the address from which the next data sample is read. This register is only valid if the DMA_AXI_ADDR_WIDTH is bigger than 32 and if the DMA channel has been configured for read from memory support. |
||
0x12f |
0x4bc |
SG_ADDRESS_HIGH |
||||
[31:0] |
SG_ADDRESS_HIGH |
RW |
0x00000000 |
HIGH segment of the starting address of the scatter-gather transfer. This register is only valid if the DMA_AXI_ADDR_WIDTH is bigger than 32 and if the DMA channel has been configured with SG transfer support. |
Access Type |
Name |
Description |
---|---|---|
RO |
Read-only |
Reads will return the current register value. Writes have no effect. |
RW |
Read-write |
Reads will return the current register value. Writes will change the current register value. |
RW1C |
Read,write-1-to-clear |
Reads will return the current register value. Writing the register will clear those bits of the register which were set to 1 in the value written. Bits are set by hardware. |
Theory of Operation#
HDL Synthesis Settings#
Sizing of the internal store-and-forward data buffer#
An internal buffer is used to store data from the source interface before it is forwarded to the destination once that can accept it. The purpose of the buffer is to even out the rate mismatches between the source and destination. e.g if the destination is a FIFO interface with a fixed data rate and the source is a MM interface, the intent is to keep the buffer as full as possible so in case of the MM interface is not ready data can be still provided to the destination without risking an underflow. Similarly in case the destination is a MM interface and the source a FIFO interface with a fixed data rate, the intent is to keep the buffer as empty as possible so in case the MM interface is not ready data can be still accepted from the source without risking an overflow.
The size of the buffer in bytes is determined by the synthesis parameters of the
module and it is equal to FIFO_SIZE
* MAX_BYTES_PER_BURST
The width of the buffer is sized to be the largest width from the source and destination interfaces.
BUFFER_WIDTH_IN_BYTES = MAX(
DMA_DATA_WIDTH_SRC
,DMA_DATA_WIDTH_DEST
)/8BUFFER_DEPTH =
FIFO_SIZE
*MAX_BYTES_PER_BURST
/ BUFFER_WIDTH_IN_BYTES
Interfaces and Signals#
Register Map Configuration Interface#
The register map configuration interface can be accessed through the AXI4-Lite
S_AXI
interface. The interface is synchronous to the s_axi_aclk
. The
s_axi_aresetn
signal is used to reset the peripheral and should be asserted
during system startup until the s_axi_aclk
is active and stable.
De-assertion of the reset signal should by synchronous to s_axi_aclk
.
Data Interfaces#
AXI-Streaming subordinate#
The interface back-pressures through the s_axis_ready
signal. If the core is
in the idle state the s_axis_ready
signal will stay low until a descriptor
is submitted. The s_axis_ready
will go low once the internal buffer of the
core is full. It will go high only after enough space is available to store at
least a burst (MAX_BYTES_PER_BURST
bytes); Once the current transfer is
finished and a new descriptor was not submitted the s_axis_ready
will go
low. The s_axis_ready
will go low also when the TLAST is used that asserts
unexpectedly. Unexpectedly means that the transfer length defined by TLAST is
shorter than the transfer length programmed in the descriptor (X_LENGTH
register). If the next descriptor was already submitted the s_axis_ready
will assert within few cycles, in other hand will stay low until a new
descriptor is submitted.
The xfer_req
is asserted once a transfer is submitted to the descriptor
queue and stays high until all data from the current transfer is received/send
through the AXI Stream/FIFO interface. If during the current transfer another
descriptor is queued (submitted) it will stay high and so on.
Configuration Interface#
The peripheral features a register map configuration interface that can be
accessed through the AXI4-Lite S_AXI
port. The register map can be used to
configure the peripherals operational parameters, query the current status of
the device and query the features supported by the device.
Peripheral Identification#
The peripheral contains multiple registers that allow the identification of the
peripheral as well as discovery of features that were configured at HDL
synthesis time. Apart from the SCRATCH
register all registers in this
section are read only and writes to them will be ignored.
The VERSION
(0x000
) register contains the version of the peripheral. The
version determines the register map layout and general features supported by the
peripheral. The version number follows semantic versioning.
Increments in the major number indicate backwards incompatible changes, increments
in the minor number indicate backwards compatible changes, patch letter increments
indicate fixed incorrect behavior.
The PERIPHERAL_ID
(0x004
) register contains the value of the ID
HDL
configuration parameter that was set during synthesis. Its primary function is
to allow to distinguish between multiple instances of the peripheral in the same
design.
The SCRATCH
(0x008
) register is a general purpose 32-bit register that
can be set to an arbitrary values. Reading the register will yield the value
previously written (The value will be cleared when the peripheral is reset).
It’s content does not affect the operation of the peripheral. It can be used by
software to test whether the register map is accessible or store custom
peripheral associated data.
The IDENTIFICATION
(0x00c
) register contains the value of "DMAC"
.
This value is unique to this type of peripheral and can be used to ensure that
the peripheral exists at the expected location in the memory mapped IO register
space.
Interrupt Handling#
Interrupt processing is handled by three closely related registers. All three registers follow the same layout, each bit in the register corresponds to one particular interrupt.
When an interrupt event occurs it is recorded in the IRQ_SOURCE
(0x088
)
register. For a recorded interrupt event the corresponding bit is set to 1. If
an interrupt event occurs while the bit is already set to 1 it will stay set to
1.
The IRQ_MASK
(0x080
) register controls how recorded interrupt events
propagate. An interrupt is considered to be enabled if the corresponding bit in
the IRQ_MASK
register is set to 0, it is considered to be disabled if the
bit is set to 1.
Disabling an interrupt will not prevent it from being recorded, but only its propagation. This means if an interrupt event was previously recorded while the interrupt was disabled and the interrupt is being enabled the interrupt event will then propagate.
An interrupt event that has been recorded and is enabled propagates to the
IRQ_PENDING
(0x084
) register. The corresponding bit for such an
interrupt will read as 1. Disabled or interrupts for which no events have been
recorded will read as 0. Also if at least one interrupt has been recorded and is
enabled the external irq
signal will be asserted to signal the IRQ event to
the upstream IRQ controller.
A recorded interrupt event can be cleared (or acknowledged) by writing a 1 to
the corresponding bit to either the IRQ_SOURCE
or IRQ_PENDING
register.
It is possible to clear multiple interrupt events at the same time by setting
multiple bits in a single write operation.
For more details regarding interrupt operation see the Interrupts.
Transfer Configuration#
The DEST_ADDRESS
(0x410
) register contains the destination address of
the transfer. The address must be aligned to the destination bus width.
Non-aligned addresses will be automatically aligned internally by setting the
LSBs to 0. This register is only valid if the DMA channel has been configured
for write to memory support.
The SRC_ADDRESS
(0x414
) register contains the source address of the
transfer. The address must be aligned to the source bus width. Non-aligned
addresses will be automatically aligned internally by setting the LSBs to 0.
This register is only valid if the DMA channel has been configured for write
from memory support.
The X_LENGTH
(0x418
) register contains the number of bytes to transfer
per row. The number of bytes is equal to the value of the register + 1 (E.g. a
value of 0x3ff means 0x400 bytes).
The Y_LENGTH
(0x41C
) register contains the number of rows to transfer.
The number of rows is equal to the value of the register + 1 (E.g. a value of
1079 means 1080 rows). This register is only valid if the DMA channel has been
configured with 2D transfer support. If 2D transfer support is disabled the
number of rows is always 1 per transfer.
The SRC_STRIDE
(0x424
) and DEST_STRIDE
(0x420
) registers contain
the number of bytes between the start of one row and the next row. Needs to be
aligned to the bus width. This field is only valid if the DMA channel has been
configured with 2D transfer support.
The total number of bytes transferred is equal to (X_LENGTH
+ 1
) *
(Y_LENGTH
+ 1
).
The FLAGS
(0x40C
) register controls the behavior of the transfer.
If the
CYCLIC
([0]
) bit is set the transfer will run in Cyclic Transfers.If the
TLAST
([1]
) bit is set the TLAST signal will be asserted during the last beat of the AXI Stream transfer.
Transfer Submission#
Writing a 1 to the TRANSFER_SUBMIT
(0x408
) register queues a new
transfer. If the internal transfer queue is full the TRANSFER_SUBMIT
bit
will stay asserted until room becomes available, the bit transitions back to 0
once the transfer has been queued. Writing a 0 to this register has no effect.
Writing a 1 to the register while it is already 1 will also have no effect. When
submitting a new transfer software should always check that the
TRANSFER_SUBMIT
[0] bit is 0 before setting it, otherwise the transfer will
not be queued.
If the DMA channel is disabled (ENABLE
control bit is set to 0) while a
queuing operation is in progress it will be aborted and the TRANSFER_SUBMIT
bit will de-assert.
The TRANSFER_ID
(0x404
) register contains the ID of the next transfer.
The ID is generated by the DMA controller and can be used to check if a transfer
has been completed by checking the corresponding bit in the TRANSFER_DONE
(0x428
) register. The contents of this register is only valid if
TRANSFER_SUBMIT
is 0. Software should read this register before asserting
the TRANSFER_SUBMIT
bit.
Transfer Status#
The TRANSFER_DONE
(0x428
) register indicates whether a submitted
transfer has been completed. Each bit in the register corresponds to transfer
ID. When a new transfer is submitted the corresponding bit in the register is
cleared, once the the transfer has been completed the corresponding bit will be
set.
The ACTIVE_TRANSFER_ID
(0x42C
) register holds the ID of the currently
active transfer. When no transfer is active the value of register will be equal
to the value of the TRANSFER_ID
(0x404
) register.
Transfer length reporting#
When using MM or FIFO source interfaces the amount of data which the core will
transfer is defined by X_LENGTH
and Y_LENGTH
registers in the moment of
the transfer submission. Once the corresponding bit from the TRANSFER_DONE
is set the programmed amount of data is transferred.
When using streaming interface (AXIS) as source, the length of transfers will be
defined by the assertion of TLAST
signal which is unknown at the moment of
transfer submission. In this case X_LENGTH
and Y_LENGTH
specified during
the transfer submission will act as upper limits for the transfer. Transfers
where the TLAST occurs ahead of programmed length will be noted as partial
transfers. If PARTIAL_REPORTING_EN
bit from the FLAGS
register is set,
the length of partial transfers will be recorded and exposed through the
PARTIAL_TRANSFER_LENGTH
and PARTIAL_TRANSFER_ID
registers. The
availability of information regarding partial transfers is done through the
PARTIAL_TRANSFER_DONE
field of TRANSFER_DONE
register.
During operation the TRANSFER_PROGRESS
register can be consulted to check
the progress of the current transfer. The register presents the number of bytes
the destination accepted during the in progress transfer. This register will be
cleared once the transfer completes. This register should be used for debugging
purposes only.
Transfer Tear-down#
Non-cyclic transfers stop once the programmed amount of data is transferred to
the destination. Cyclic transfers needs to be stopped with software intervention
by setting the ENABLE
control bit to 0. In case if required, non cyclic
transfers can be interrupted in the same way. The transfer tear down is done
gracefully and is done at a burst resolution on MM interfaces and beat
resolution on non-MM interfaces. DMAC shuts down gracefully as fast as possible
while completing all in-progress MM transactions.
Source side: For MM interface once the ENABLE
bit de-asserts the DMAC won’t
issue new requests towards the source interface but will wait until all pending
requests are fulfilled by the source. For non-MM interfaces, once the ENABLE
bit de-asserts the DMAC will stop to accept new data. This will lead to partial
bursts in the internal buffer but this data will be cleared/lost once the
destination side completes all pending bursts.
Destination side: For MM interface the DMAC will complete all pending requests
that have been started by issuing the address. For non-MM interfaces once the
ENABLE
bit de-asserts the DMAC will stop to drive new data. All the data
from the internal buffer will be cleared/lost. In case of AXIS the DMAC will
wait for data to be accepted if valid is high since it can’t just de-assert
valid without breaking the interface semantics
Interrupts#
The DMA controller supports interrupts to allow asynchronous notification of certain events to the CPU. This can be used as an alternative to busy-polling the status registers. Two types of interrupt events are implemented by the DMA controller.
The TRANSFER_QUEUED
interrupt is asserted when a transfer is moved from the
register map to the internal transfer queue. This is equivalent to the
TRANSFER_SUBMIT
register transitioning from 1 to 0. Software can use this
interrupt as an indication that the next transfer can be submitted.
Note that a transfer being queued does not mean that it has been started yet. If other transfers are already queued those will be processed first.
The TRANSFER_COMPLETED
interrupt is asserted when a previously submitted
transfer has been completed. To find out which transfer has been completed the
TRANSFER_DONE
register should be checked.
Note that depending on the transfer size and interrupt latency it is possible for multiple transfers to complete before the interrupt handler runs. In that case the interrupt handler will only run once. Software should always check all submitted transfers for completion.
2D Transfers#
If the DMA_2D_TRANSFER
HDL synthesis configuration parameter is set the DMA
controller has support for 2D transfers.
A 2D transfer is composed of a number of rows with each row containing a certain number of bytes. Between each row there might be a certain amount of padding bytes that are skipped by the DMA.
For 2D transfers the X_LENGTH
register configures the number of bytes per
row and the Y_LENGTH
register configures the number of rows. The
SRC_STRIDE
and DEST_STRIDE
registers configure the number of bytes in
between start of two rows.
E.g. the first row will start at the configured source or destination address, the second row will start at the configured source or destination address plus the stride and so on.
If support for 2D transfers is disabled only the X_LENGTH register is considered and the number of rows per transfer is fixed to 1.
Cyclic Transfers#
If the CYCLIC
HDL synthesis configuration parameter is set the DMA
controller has support for cyclic transfers.
A cyclic transfer once completed will restart automatically with the same configuration. The behavior of cyclic transfer is equivalent to submitting the same transfer over and over again, but generates less software management overhead.
A transfer is cyclic if the CYCLIC
([0]
) bit of the FLAGS
(0x40C
) is set to 1 during transfer submission.
For cyclic transfers no end-of-transfer interrupts will be generated. To stop a cyclic transfer the DMA channel must be disabled.
Any additional transfers that are submitted after the submission of a cyclic transfer (and before stopping the cyclic transfer) will never be executed.
Scatter-Gather Transfers#
If the DMA_SG_TRANSFER
HDL synthesis configuration parameter is set the DMA
controller has support for scatter-gather transfers.
The scatter-gather optional feature allows the DMA to access noncontiguous areas of memory within a single transfer.
The DMA can read from or write to different memory addresses in one transaction by using a list of vectors called descriptors. Each descriptor provides the starting address and the length of the current memory block to be accessed, as well as the next address of the following descriptor to be processed. By chaining these descriptors, the DMA can gather the data into a contiguous transfer from the scattered memory data from multiple addresses.
The scatter-gather has its own dedicated AXI3/4 memory mapped interface
m_sg_axi
through which it receives the descriptor data.
Descriptor Structure#
The scatter-gather interface fetches the descriptor information from memory in the following order:
Size |
Name |
Description |
---|---|---|
32-bit |
flags |
This field includes 2 control bits:
|
32-bit |
id |
This field corresponds to an identifier of the descriptor. |
64-bit |
dest_addr |
This field contains the destination address of the transfer. |
64-bit |
src_addr |
This field contains the source address of the transfer. |
64-bit |
next_sg_addr |
This field contains the address of the next descriptor. |
32-bit |
y_len |
This field contains the number of rows to transfer, minus one. |
32-bit |
x_len |
This field contains the number of bytes to transfer, minus one. |
32-bit |
src_stride |
This field contains the number of bytes between the start of one row and the next row for the source address. |
32-bit |
dst_stride |
This field contains the number of bytes between the start of one row and the next row for the destination address. |
The y_len
, src_stride
and dst_stride
fields are only useful for 2D
transfers and should be set to 0 if 2D transfers are not required.
Transfer Configuration#
The scatter-gather transfers are enabled through the HWDESC
bit from the
CONTROL
(0x400
) register. Once this bit is set, cyclic transfers are
disabled, since the same cyclic behavior can be replicated using a descriptor
chain loop.
To start a scatter-gather transfer, the address of the first DMA descriptor must
be written to the register pair [SG_ADDRESS_HIGH
(0x4BC
), SG_ADDRESS
(0x47C
)].
To end a scatter-gather transfer, the last descriptor of the transfer must have
the flags[0]
bit set.
The scatter-gather transfer is queued in a similar way to the simple transfers,
through the TRANSFER_SUBMIT
. Software should always poll this bit to be 0
before setting it, otherwise the scatter-gather transfer will not be queued.
The scatter-gather transfers support the generation of the same two types of interrupt events as the simple transfers. However, the scatter-gather transfers have the distinct advantage of generating fewer interrupts by treating the chained descriptor transfers as a single transfer, thus improving the performance of the application.
Transfer Start Synchronization#
If the SYNC_TRANSFER_START
HDL synthesis configuration parameter is set, the
transfer start synchronization feature of the DMA controller is enabled. This
means that the start of a transfer is synchronized to a flag in the data stream
or a sync signal.
This is useful if the data stream does not have any back-pressure and one unit of data spans multiple beats (e.g. packetized data). This ensures that the data is properly aligned to the beginning of the memory buffer.
In addition, this feature allows the implementation of external timing synchronization for precisely timed buffers (For example, in combination with the Timing-Division Duplexing Controller).
On the transmit side, both the FIFO and AXI-Streaming interfaces use the sync
signal as the synchronization signal.
On the receive side, for the FIFO write interface the sync
signal represents
the synchronization flag signal. For the AXI-Streaming interface the synchronization
signal is carried in either s_axis_user[0]
or sync
, depending on the
value of S_AXIS_USER_SYNC
synthesis configuration parameter. In both cases
the synchronization signal is qualified by the same control signal as the data.
Note
The synchronization signal is assumed to be synchronous with the clock of the interface which needs to be triggered by the transfer start synchronization.
Cache Coherency#
To enable Cache Coherency between the DMA and the CPU, the CACHE_COHERENT
HDL synthesis configuration parameter must be set.
Two additional parameters are used to configure the Cache Coherent transactions:
AXI_AXCACHE
sets the ARCACHE/AWCACHE AXI cache support signals;AXI_AXPROT
sets the ARPROT/AWPROT AXI access permission signals.
They are initially set to the following default values through CACHE_COHERENT
:
AXI_AXCACHE
=CACHE_COHERENT
?4'b1111
:4'b0011
AXI_AXPROT
=CACHE_COHERENT
?3'b010
:3'b000
If Cache Coherency is enabled, the AXI_AXCACHE
and AXI_AXPROT
values can
be changed to support systems with different caching policies.
Diagnostics interface#
For debug purposes a diagnostics interface is added to the core.
The dest_diag_level_bursts
signal adds insight into the fullness of the
internal memory buffer during operation. The information is exposed in number
of bursts where the size of a burst is defined by the MAX_BYTES_PER_BURST
parameter. The value of dest_diag_level_bursts
increments for each burst
accumulated in the DMACs internal buffer. It decrements once the burst leaves
the DMAC on its destination port. The signal is synchronous to the destination
clock domain (m_dest_axi_aclk
or m_axis_aclk
depending on DMA_TYPE_DEST
).
Limitations#
AXI 4kByte Address Boundary#
Software must program the SRC_ADDRESS
and DEST_ADDRESS
registers in such
way that AXI burst won’t cross the 4kB address boundary. The following condition
must hold:
MAX_BYTES_PER_BURST
≤ 4096;MAX_BYTES_PER_BURST
is power of 2;SRC/DEST_ADDRESS
modMAX_BYTES_PER_BURST
== 0SRC/DEST_ADDRESS[11:0]
+ MIN(X_LENGTH
+1,MAX_BYTES_PER_BURST
) ≤ 4096
Address Alignment#
Software must program the SRC_ADDRESS
and DEST_ADDRESS
registers to be
multiple of the corresponding MM data bus. The following conditions must hold:
SRC_ADDRESS
MOD (DMA_DATA_WIDTH_SRC
/8) == 0DEST_ADDRESS
MOD (DMA_DATA_WIDTH_DEST
/8) == 0
Transfer Length Alignment#
Software must program the X_LENGTH
register to be multiple of the widest
data bus. The following condition must hold:
(
X_LENGTH
+1) MOD MAX(DMA_DATA_WIDTH_SRC
,DMA_DATA_WIDTH_DEST
)/8 == 0
This restriction can be relaxed for the memory mapped interfaces. This is done by partially ignoring data of a beat from/to the MM interface:
For write access the strobe bits are used to mask out bytes that do not contain valid data.
For read access a full beat is read but part of the data is discarded. This works fine as long as the read access is side effect free. I.e. this method should not be used to access data from memory mapped peripherals like a FIFO.
E.g. the length alignment requirement of a DMA configured for a 64-bit memory mapped interface and a 16-bit streaming interface is only 2 bytes instead of 8 bytes.
Note that the address alignment requirement is not affected by this. The address still needs to be aligned to the width of the MM interface that it belongs to.
Scatter-Gather Datapath Width#
The scatter-gather dedicated interface m_sg_axi
currently supports only
64-bit transfers. DMA_DATA_WIDTH_SG
can only be set to 64.
Software Support#
Analog Devices recommends to use the provided software drivers.
Known Issues#
1. When max bytes per burst matches the data width of destination interface an erroneous extra beat is inserted after every valid beat on the destination side. Example configuration:
axi mm -> axi stream
max bytes per burst = 128
destination width = 1024 bits
Workaround: increase the max bytes per burst to larger than 128
Technical Support#
Analog Devices will provide limited online support for anyone using the core with Analog Devices components (ADC, DAC, Video, Audio, etc) via the EngineerZone.
Glossary#
Term |
Description |
---|---|
beat |
Represents the amount of data that is transferred in one clock cycle. |
burst |
Represents the amount of data that is transferred in a group of consecutive beats. |
partial transfer |
Represents a transfer which is shorter than the programmed length that
is based on the |
Software Support#
No-OS project at drivers/axi_core/axi_dmac
No-OS device driver at drivers/axi_core/axi_dmac/axi_dmac.c
No-OS device driver documentation on wiki
References#
HDL IP core at library/axi_dmac