L-Tile and H-Tile Avalon® Memory-mapped Intel® FPGA IP for PCI Express* User Guide

ID 683667
Date 4/03/2023
Public

A newer version of this document is available. Customers should click here to go to the newest version.

Document Table of Contents

8.1. Read DMA Example

This example moves three data blocks from the PCIe address space (system memory) to the Avalon-MM address space.

Note: Beginning with the 17.1 release, the Intel® Quartus® Prime Pro Edition software dynamically generates example designs for the parameters you specify in the using the parameter editor. Consequently, the Intel® Quartus® Prime Pro Edition installation directory no longer provides static example designs for Intel® Stratix® 10 devices. Static example designs are available for earlier device families, including Intel® Arria® 10 and Intel® Cyclone® 10 devices.
Figure 59.  Intel® Stratix® 10 Gen3 x8 Avalon-MM DMA Integrated Platform Designer

The following figures illustrate the location and size of the data blocks in the PCIe and Avalon® -MM address spaces and the descriptor table format. In this example, the value of RD_TABLE_SIZE is 127.

Figure 60. Data Blocks to Transfer from PCIe to Avalon-MM Address Space Using Read DMA

The descriptor table includes 128 entries. The status table precedes a variable number of descriptors in memory. The Read and Write Status and Descriptor Tables are at the address specified in the Read Descriptor Base Register and Write Descriptor Base Register, respectively.

Figure 61. Descriptor Table In PCIe* System Memory
  1. Software allocates memory for the Read Descriptor Status table and Descriptor table in PCIe* system memory. The memory allocation requires the following calculation:
    1. Each entry in the read status table is 4 bytes. The 128 read entries require 512 bytes of memory.
    2. Each descriptor is 32 bytes. The three descriptors require 96 bytes of memory.
      Note: To avoid a possible overflow condition, allocate the memory needed for the number of descriptors supported by RD_TABLE_SIZE, rather than the initial number of descriptors.
    The total memory that software must allocate for the status and descriptor tables is 608 bytes. The start address of the allocated memory in this example is 0xF000_0000. Write this address into the Read Descriptor Controller Read Status and Descriptor Base registers.
  2. Program the Read Descriptor Controller table starting at offset 0x200 from the Read Status and Descriptor Base. This offset matches the addresses shown in Data Blocks to Transfer from PCIe to Avalon-MM Address Space Using Read DMA. The three blocks of data require three descriptors.
  3. Program the Read Descriptor Controller Read Status and Descriptor Base register with the starting address of the descriptor status table.
  4. Program the Read Descriptor Controller Read Descriptor FIFO Base with the starting address of the on-chip descriptor table FIFO. This is the base address for the rd_dts_slave port in Platform Designer. In this example, the address is 0x0100_0000.
    Figure 62. Address of the On-Chip Read FIFO
  5. To get status updates for each descriptor, program the Read Descriptor Controller RD_CONTROL register with 0x1. This step is optional.
  6. Program the Read Descriptor Controller register RD_DMA_LAST_PTR with the value 3. Programming this register triggers the Read Descriptor Controller descriptor table fetch process. Consequently, writing this register must be the last step in setting up DMA transfers.
  7. The host waits for the MSI interrupt. The Read Descriptor Controller sends the MSI to the host after completing the last descriptor. The Read Descriptor Controller also writes the Update.
  8. If there are additional blocks of data to move, complete the following steps to set up additional transfers.
    1. Program the descriptor table starting from memory address 0xF000_0200 + (<previous last descriptor pointer> * 0x20). In this case the descriptor pointer was 3.
    2. Program the Read Descriptor Controller register RD_DMA_LAST_PTR with previous_value (3 in this case) + number of new descriptors. Programming this register triggers the Read Descriptor Controller descriptor table fetch process. Consequently, programming this register must be the last step in setting up DMA transfers.
      Note: When RD_DMA_LAST_PTR approaches the RD_TABLE_SIZE, be sure to program the RD_DMA_LAST_PTR with a value equal to RD_TABLE_SIZE. Doing so ensures that the rollover to the first descriptor at the lowest offset occurs, (0xF000_0200 in this example). Refer to the description of the RD_DMA_LAST_PTR in the Read DMA Descriptor Controller Registers section for further information about programming the RD_DMA_LAST_PTR register.