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

  • Framelock

  • AutoRun

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

library/axi_dmac/axi_dmac.v

Verilog source for the peripheral.

Block Diagram

AXI DMAC 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**DMA_LENGTH_WIDTH.

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 MAX_BYTES_PER_BURST parameter. Must be power of 2 in the range of 2 to 32.

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

DMA_2D_TLAST_MODE

AXIS TLAST function.

0

End of Frame (0), End of Line (1)

FRAMELOCK

Framelock Support.

False

MAX_NUM_FRAMES_WIDTH

Max Number Of Frame Buffers.

3

4 buffers (2), 8 buffers (3), 16 buffers (4), 32 buffers (5)

USE_EXT_SYNC

External Synchronization Support.

False

AUTORUN

Enable AutoRun mode.

False

AUTORUN_FLAGS

Flags.

'h00000000

AUTORUN_SRC_ADDR

Source address.

'h00000000

AUTORUN_DEST_ADDR

Destination address.

'h00000000

AUTORUN_X_LENGTH

X length.

'h00000000

AUTORUN_Y_LENGTH

Y length.

'h00000000

AUTORUN_SRC_STRIDE

Source stride.

'h00000000

AUTORUN_DEST_STRIDE

Destination stride.

'h00000000

AUTORUN_SG_ADDRESS

Scatter-Gather start address.

'h00000000

AUTORUN_FRAMELOCK_CONFIG

Framelock config.

'h00000000

AUTORUN_FRAMELOCK_STRIDE

Framelock stride.

'h00000000

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

Logical Port

Direction

Dependency

m_frame_in s2m_framelock

in [2:0]

m_frame_in_valid s2m_framelock_valid

in

m_frame_out m2s_framelock

out [2:0]

m_frame_out_valid m2s_framelock_valid

out

Physical Port

Logical Port

Direction

Dependency

s_frame_in m2s_framelock

in [2:0]

s_frame_in_valid m2s_framelock_valid

in

s_frame_out s2m_framelock

out [2:0]

s_frame_out_valid s2m_framelock_valid

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

src_ext_sync

in

USE_EXT_SYNC = 1

dest_ext_sync

in

USE_EXT_SYNC = 1

dest_diag_level_bursts

out [7:0]

ENABLE_DIAGNOSTICS_IF = 1

Only present when ENABLE_DIAGNOSTICS_IF parameter is set.

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.64.

[31:16] VERSION_MAJOR RO 0x0004

[15:8] VERSION_MINOR RO 0x05

[7:0] VERSION_PATCH RO 0x64

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. BYTES_PER_BEAT_DEST_LOG2 = $clog2(DMA_DATA_WIDTH_DEST/8)

[5:4] DMA_TYPE_DEST RO DMA_​TYPE_​DEST

Value of DMA_TYPE_DEST parameter.(0 - AXI MemoryMap, 1 - AXI Stream, 2 - FIFO )

[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. BYTES_PER_BEAT_SRC_LOG2 = $clog2(DMA_DATA_WIDTH_SRC/8)

[13:12] DMA_TYPE_SRC RO DMA_​TYPE_​SRC

Value of DMA_TYPE_SRC parameter.(0 - AXI MemoryMap, 1 - AXI Stream, 2 - FIFO )

[19:16] BYTES_PER_BURST_WIDTH RO BYTES_​PER_​BURST_​WIDTH

Value of BYTES_PER_BURST_WIDTH interface parameter. Log2 of the real MAX_BYTES_PER_BURST. The starting address of the transfer must be aligned with MAX_BYTES_PER_BURST to avoid crossing the 4kB address boundary.

[24] AUTORUN RO AUTORUN

Run in the AUTORUN_* configuration.

[25] USE_EXT_SYNC RO USE_​EXT_​SYNC

Use external sync.

[26] DMA_2D_TLAST_MODE RO DMA_​2D_​TLAST_​MODE

TLAST behaviour for 2D transfer (0 - End of Frame; 1 - End of Line).

[31:27] MAX_NUM_FRAMES RO MAX_​NUM_​FRAMES

Max number of frames.

0x5 0x14 INTERFACE_DESCRIPTION_2

[0] CACHE_COHERENT RO CACHE_​COHERENT

Value of CACHE_COHERENT parameter. (0 - Disabled, 1 - Enabled)

[7:4] AXI_AXCACHE RO AXI_​AXCACHE

Value of AXI_AXCACHE parameter.

[10:8] AXI_AXPROT RO AXI_​AXPROT

Value of AXI_AXPROT parameter.

0x20 0x80 IRQ_MASK

[1] TRANSFER_COMPLETED RW 0x1

Masks the TRANSFER_COMPLETED IRQ.

[0] TRANSFER_QUEUED RW 0x1

Masks the TRANSFER_QUEUED IRQ.

0x21 0x84 IRQ_PENDING

[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] 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] 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] 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

[3] FRAMELOCK RW 0x0

Setting this field to 1 puts the DMA transfer into framelock mode. In framelock mode the data is hold to compensate frames rates mismatch between source and sink channels. This field is only valid if the DMA channel has been configured with framelock support.

If AUTORUN is set, the default value of the field is AUTORUN_FLAGS[4].

[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. If AUTORUN is set, the default value of the field is AUTORUN_FLAGS[3].

[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] 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] 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] 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. If AUTORUN is set, the default value of the field is AUTORUN_FLAGS[0].

[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. If AUTORUN is set, the default value of the field is AUTORUN_FLAGS[1].

[2] PARTIAL_REPORTING_EN RW 0x0

When setting this bit the length of partial transfers caused eventually by TLAST will be recorded. If AUTORUN is set, the default value of the field is AUTORUN_FLAGS[2].

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. If AUTORUN is set, the default value of the field is AUTORUN_DEST_ADDR.

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. If AUTORUN is unset, the default value of the field is AUTORUN_SRC_ADDR.

0x106 0x418 X_LENGTH

[31:0] X_LENGTH RW X_​LENGTH

Number of bytes to transfer - 1. If AUTORUN is set, the default value of the field is AUTORUN_FRAMELOCK_X_LENGTH. X_LENGTH = 2**$clog2(`MAX(DMA_DATA_WIDTH_SRC, DMA_DATA_WIDTH_DEST)/8)-1

0x107 0x41c Y_LENGTH

[31:0] Y_LENGTH RW 0x00000000

Number of rows to transfer - 1. If AUTORUN is set, the default value of the field is AUTORUN_FRAMELOCK_Y_LENGTH.

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. If AUTORUN is set, the default value of the field is AUTORUN_DEST_STRIDE.

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. If AUTORUN is set, the default value of the field is AUTORUN_SRC_STRIDE.

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] TRANSFER_0_DONE RO 0x0

If this bit is set the transfer with ID 0 has been completed.

[1] TRANSFER_1_DONE RO 0x0

If this bit is set the transfer with ID 1 has been completed.

[2] TRANSFER_2_DONE RO 0x0

If this bit is set the transfer with ID 2 has been completed.

[3] TRANSFER_3_DONE RO 0x0

If this bit is set the transfer with ID 3 has been completed.

[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.

0x116 0x458 FRAMELOCK_CONFIG

Configure the Framelock feature.

[23:16] DISTANCE RW 0x00

Used mainly in output delay mode. Set the output delay in frames. With a DISTANCE of 0, the reader is one frame behind with WAIT_WRITER set. In frame conversion mode, it will repeat reading frame 0 until frame 1 is fully written to memory. If AUTORUN is set, the default value of the field is AUTORUN_FRAMELOCK_CONFIG[23:16].

[15:8] FRAMENUM RW 0x00

The total number of video frame buffers - 1. Related to MAX_NUM_FRAMES synthesis parameter. If AUTORUN is set, the default value of the field is AUTORUN_FRAMELOCK_CONFIG[15:8].

[1] WAIT_WRITER RW 0x0

If WAIT_WRITER is unset, enable the generation of new request right away. In Simple Flock when WAIT_WRITER is set, the reader must wait until the writer completes a buffer. In Dynamic Flock just wait until the required number of buffers are filled, then enable the request generation regardless of the writer. If AUTORUN is set, the default value of the field is AUTORUN_FRAMELOCK_CONFIG[1].

[0] MODE RW 0x0

Select operating mode of the framebuffer.

  • 0 - Frame rate conversion mode (dynamic).

  • 1 - Output delay mode (simple).

In dynamic mode, the writer skips the current in-use reader buffer and the reader stays behind the writer’s buffer by repeating or skipping buffers.

If AUTORUN is set, the default value of the field is AUTORUN_FRAMELOCK_CONFIG[0].

0x117 0x45c FRAMELOCK_STRIDE

Configure the Framelock feature.

[31:0] STRIDE RW 0x00000000

The number of bytes between the start of one row and the next row for the framelock. If AUTORUN is set, the default value of the field is AUTORUN_FRAMELOCK_STRIDE.

Note, this field is only valid if the DMA channel has been configured with framelock support.

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. If AUTORUN is set, the default value of the field is AUTORUN_SG_ADDRESS.

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)/8

  • BUFFER_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

AutoRun mode

When the AUTORUN parameter is set the DMAC can initiate transfers without software intervention. Once the core comes out of reset, the core will operate on a transfer defined through the AUTORUN_* synthesis parameters. This is useful mostly in CYCLIC mode. In non cyclic mode, once the initial transfer is done the core will go to idle state and will wait for software interaction if that exists. In this mode the s_axi AXI configuration interface is optional.

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.

\[ROW\_SRC\_ADDRESS = SRC\_ADDRESS + SRC\_STRIDE * N\]
\[ROW\_DEST\_ADDRESS = DEST\_ADDRESS + DEST\_STRIDE * N\]

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:
  • bit0: if set, the transfer will complete after this last descriptor is processed and the DMA core will go back to idle state; if cleared, the next DMA descriptor pointed to by next_sg_addr will be loaded.

  • bit1: if set, an end-of-transfer interrupt will be raised after the memory segment pointed to by this descriptor has been transferred.

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.

External Synchronization

This feature allows external components to throttle the consumption of descriptors queued by the software. A transfer will start only after the assertion of the external sync signal for at least one clock cycle.

The sync signal can be either in source or destination clock domain or both. This feature does not ensure fixed latency from the assertion of external sync signal and the availability of the data at the destination interface.

Framelock Synchronization

This feature adds support for multiple 2D frame buffers, which are used in a cyclic way. On the same set of buffers, a second DMAC core can operate. The “Framelock” mechanism ensures no buffer is accessed by two DMACs at the same time.

The core can operate in two roles:

  • Writer mode - available in s2mm configuration.

  • Reader mode - available in mm2s configuration.

And two modes:

  • Frame conversion (dynamic mode):

    • Writer mode - the writer will always skip the current in-use reader’s buffer.

    • Reader mode - the reader will stay behind the writer’s buffer by either repeating or skipping buffers according to the speed relationship of the two cores.

  • Output delay (simple mode):

    • Writer mode - the writer will cycle through the buffers regardless of the reader.

    • Reader mode - the reader will always read a buffer at a predefined distance from the one currently accessed by the writer.

Also, in simple mode:

  • If ‘wait for writer’ is enabled the reader will output a frame only after the master wrote one to the memory

  • If the ‘wait for writer’ is not enabled the slave will start reading a buffer whenever it completed a previous buffer and receives an external sync signal if the external synchronization support is enabled.

Caution

In dynamic mode, the reader can still read a buffer being currently accessed by the writer if the number of frames and distance are close. Still, the distance is mainly used in output delay mode.

The writer and reader DMAC cores must be connected through the dedicated “framelock” interface. They must be programmed with similar settings regarding the buffers size, start address and stride through the FRAMELOCK_CONFIG and FRAMELOCK_STRIDE registers.

Notice that the reader DMA will start to read the frames only after the writer finished to store in the DDR at least FRAMELOCK_CONFIG_DISTANCE+1 frames. This means that while the FRAMELOCK_CONFIG_DISTANCE+1 frames are written into the memory, the reader DMA won’t output anything.

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 mod MAX_BYTES_PER_BURST == 0

  • SRC/DEST_ADDRESS[11:0] + MIN(X_LENGTH+1,MAX_BYTES_PER_BURST) ≤ 4096

Address Alignment

Software must program the SRC_ADDRESS and DEST_ADDRESSregisters to be multiple of the corresponding MM data bus. The following conditions must hold:

  • SRC_ADDRESS MOD (DMA_DATA_WIDTH_SRC/8) == 0

  • DEST_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 X_LENGTH and Y_LENGTH registers. This can occur on AXIS source interfaces when TLAST asserts earlier than the programmed length.

Software Support

References