Module simple_dma

This document contains technical documentation for the simple_dma module. This module has a register interface, so make sure to study the register interface documentation as well as this top-level document. To browse the source code, visit the repository on GitHub.

This module contains an incredibly simplified Direct Memory Access (DMA) component for streaming data from FPGA to DDR memory over AXI. Being simplified, it has the following limitations:

  • Can only handle writing to continuous ring buffer space in DDR. Has no scatter-gather capability.

  • Does not support data strobing or narrow AXI transfers. All addresses must be aligned with the AXI data width.

  • Each streaming beat becomes an AXI burst, giving poor AXI performance if data rate is high. This will be fixed in the future with the packet_length_beats generic.

  • Stream data width must be the same as AXI data width. This will be fixed in the future with the stream_data_width and axi_data_width generics.

  • Has no “event aggregator” feature for the write_done interrupt bit. Meaning an interrupt will be generated for each beat, which can bog down software if data rate is high. This will be implemented in the future with the write_done_aggregate_count and write_done_aggregate_ticks generics.

Register interface

This module has register definitions. Please see separate HTML page for register documentation.

simple_dma_axi_lite.vhd

View source code on GitHub.

component simple_dma_axi_lite is
  generic (
    address_width : positive range 1 to axi_a_addr_sz;
    stream_data_width : positive range 8 to axi_data_sz;
    axi_data_width : positive range 8 to axi_data_sz;
    packet_length_beats : positive range 1 to axi_max_burst_length_beats;
    enable_axi3 : boolean
  );
  port (
    clk : in std_ulogic;
    --# {{}}
    stream_ready : out std_ulogic;
    stream_valid : in std_ulogic;
    stream_data : in std_ulogic_vector;
    --# {{}}
    regs_m2s : in axi_lite_m2s_t;
    regs_s2m : out axi_lite_s2m_t;
    interrupt : out std_ulogic;
    --# {{}}
    axi_write_m2s : out axi_write_m2s_t;
    axi_write_s2m : in axi_write_s2m_t
  );
end component;

Top level for the simple DMA module, with an AXI-Lite register interface. This top level is suitable for instantiation in a user design. It integrates simple_dma_core.vhd and an AXI-Lite register file.

Resource utilization

This entity has netlist builds set up with automatic size checkers in module_simple_dma.py. The following table lists the resource utilization for the entity, depending on generic configuration.

Resource utilization for simple_dma_axi_lite netlist builds.

Generics

Total LUTs

FFs

Maximum logic level

address_width = 29

stream_data_width = 64

axi_data_width = 64

burst_length_beats = 1

232

279

15

simple_dma_core.vhd

View source code on GitHub.

component simple_dma_core is
  generic (
    address_width : positive range 1 to axi_a_addr_sz;
    stream_data_width : positive range 8 to axi_data_sz;
    axi_data_width : positive range 8 to axi_data_sz;
    packet_length_beats : positive range 1 to axi_max_burst_length_beats;
    enable_axi3 : boolean
  );
  port (
    clk : in std_ulogic;
    --# {{}}
    stream_ready : out std_ulogic;
    stream_valid : in std_ulogic;
    stream_data : in std_ulogic_vector;
    --# {{}}
    regs_up : out simple_dma_regs_up_t;
    regs_down : in simple_dma_regs_down_t;
    interrupt : out std_ulogic;
    --# {{}}
    axi_write_m2s : out axi_write_m2s_t;
    axi_write_s2m : in axi_write_s2m_t
  );
end component;

Main implementation of the simple DMA functionality. This entity is not suitable for instantiation in a user design, use instead e.g. simple_dma_axi_lite.vhd.

simple_dma_sim_pkg.vhd

View source code on GitHub.

Package with functions to simulate and check the DMA functionality.