A Template for standalone FPGA (ADM-XRC-5T2 LX330T) User Application.

This is a template for programming the ADM-XRC-5T2 FPGA accelerator in the AXEL cluster system. The example is modified from the "memory" application in the SDK. Resources related in this document are located in the fpga directory after extracting the axel_template package.

The host program first initializes the FPGA and the associated DDR2 SDRAM. Then it writes two 20 bytes data to FPGA memory Bank 0 and Bank 1 through DMA. In the example, both sequences are: [0, 1, 2, 3, ... 19]. After kicked start by the host program, the FPGA design reads the data in memory Bank 0 and Bank 1; sums each element in the sequences together and writes the results back to Bank 1. The host program reads the data in Bank 1 after FPGA processed them and print them out on screen.

A Makefile is provided to build the simulation executable (tb), the FPGA configuration file (admxrc5t2.bit) and the host program (myapp). All user logic should be placed within the "user_app" module in VHDL. This template depends on the existence of the AXEL SDK package which is pointed by inside the Makefile.

Note:

  1. This example set the host-FPGA interface clock, LCLK, to 80MHz. The DDR2 SDRAM clock, MCLK, is set to 333.3MHz. The actual clock to the external memory chip set is 4*300MHz and all user logic in FPGA is synchronize with the memory clock MCLK.

  2. The device driver for ADM-XRC-5T2 board provides a memory mapped I/O interface with 4MB size. The first (lower address) 2MB memory is mapped to a memory page on the external memory associated with the FPGA accelerator. The second (byte address starts from 0x200000) 2MB memory mapped to a register interface to communicate with FPGA logic. In the "myapp" host program, these two segments of memory can be accessed through the pointers

    (volatile uint8_t *)fpgaMem
    (volatile uint32_t *)fpgaReg.
    

  3. There are 6 (physical) banks of memories on the ADM-XRC-5T2 board.

        Bank 0 (DDR-II SDRAM): unbuffered, row 13, col 10, bank 3, phys banks 1
        Bank 1 (DDR-II SDRAM): unbuffered, row 13, col 10, bank 3, phys banks 1
        Bank 2 (DDR-II SDRAM): unbuffered, row 13, col 10, bank 3, phys banks 1
        Bank 3 (DDR-II SDRAM): unbuffered, row 13, col 10, bank 3, phys banks 1
        Bank 4 (DDR-II SRAM): burst length 4, DLL enabled
        Bank 5 (DDR-II SRAM): burst length 4, DLL enabled
       

    Each of this memory bank is partitioned to 2MB pages by the admxrc5t2 host interface logic. User host program should set the Bank and Page values in the corresponding registers before accessing the memory. The external memories support shared access between host program and FPGA logic through an arbiter. The FPGA "user_app" logic can access all memory location without any paging mechanism.

    For DDR2 SDRAM, the default data bus interfacing to the "user_app" is 128-bit in width. The address placed on default address bus is indexing these 128-bit width words.

  4. The host program use the following API functions to read/write data to FPGA associated memory.

    int  fpga_dmawrite(void *buf, unsigned long size, uint32_t addr);
    int  fpga_dmaread(void *buf, unsigned long size, uint32_t addr);
    

    Detail information of the API functions are described in the SDK Reference. The last parameter in these functions is the starting address in a virtual memory space in the FPGA side. This virtual memory is created by cascading the six banks of FPGA associated memories. The bank and page is set automatically within the function according to the given address.

  5. The first a few registers in the fpgaReg[] array is used in the initialization process for system related controls such as memory management. Users can freely use the registers at and after fpgaReg[USER_REG]. On the FPGA side, the input data bus, reg_in, of the register interface is 64-bit in width. While the elements in fpgaReg[] is 32-bit data, there is a mapping between the host and device register space: The byte select signal, "reg_wr", is a bit mask indicating which register is actually being written by host. Assertion in reg_wr[3:0] means the first user register, fpgaReg[USER_REG], is presented on the data bus; and reg_wr[7:4] means the second user register, fpgaReg[USER_REG+1], is presented and so on. The contents of fpgaReg[USER_REG] form host will be on reg_in[31:0] and the content of fpgaReg[USER_REG+1] from host will be on reg_in[63:32]. The third register fpgaReg[USER_REG+2] comes in reg_in[31:0] again. All signals from the host interface (reg_in and reg_wr) are resynchronized with MCLK. The output registers from FPGA to host, reg_out, are presented as 256 bytes parallel bus. Host program reads fpgaReg[USER_REG] from reg_out[31:0], fpgaReg[USER_REG+1] from req_out[63:32] and fpgaReg[USER_REG+2] from reg_out[95:64]. FPGA design has no information about when the host reads which register.