Buscar este blog

jueves, 27 de noviembre de 2014

PRACTICA # 2 MANEJO DE MEMORIA BRAM

En esta práctica se elaborara una interfaz AXI para el control de memoria BRAM de la parte PL. Para este ejemplo se especificara solo 8kbyte de memoria. Y se comparara las velocidades de transmisión de este tipo de memoria con la DDR.


  • La parte PS (VIVADO diagrama de bloques) queda de la siguiente manera:



  • Tanto la dirección otorgada por vivado así como su rango de memoria se ve en la siguiente imagen:



  • Des habilitamos todos los periféricos a excepción del UART 1:
                                       


  • Establecemos el UART 1 como 115200 bps:


  • Deshabilitamos periféricos a excepción de UART 1:


  • El código para la parte de SDK eclipse C/C++ es el siguiente:

#include <stdio.h>


#include <stdlib.h>
#include <string.h>

#include "xparameters.h"
#include "xparameters_ps.h"
#include "xil_types.h"
#include "xtime_l.h"
#include "xil_testmem.h"
#include "xstatus.h"

typedef unsigned long ulong;
typedef unsigned char uchar;

#define CPU_CLOCK_FREQ                                             XPAR_PS7_CORTEXA9_0_CPU_CLK_FREQ_HZ
#define FPGA_CLOCK_FREQ                   100000000
#define BRAM_BASE_ADDR                                             0x40000000

const int COPY_BYTES = 8*1024;  //8K
const int num_word = COPY_BYTES / 4;

uchar buff1[COPY_BYTES];
uchar buff2[COPY_BYTES];                                   // Memoria DDR
//uchar *buff2 = (uchar *) BRAM_BASE_ADDR;    // Memoria BRAM


bool TestMemory();

int main()
                        {

                        printf("Hello World %s\n", (buff2 == (uchar *) BRAM_BASE_ADDR) ? "BRAM" : "DDR");

                        XTime t1, t2;

                        XTime_GetTime(&t1);                                                                                                          // Get time before memcpy
                        memcpy(buff1, buff2, COPY_BYTES);       // Copy bytes from BRAM or DDR3
                        XTime_GetTime(&t2);                                                                                                          // Get time after memcpy
                        ulong clocks = 2 * (t2 - t1);                           // Compute time for memcpy (Note: ARM PERIPHCLK is twice period of CPU clock)

                        double dt = clocks / double(CPU_CLOCK_FREQ);       // Compute clock time
                        double rate = COPY_BYTES / dt;                                                                                                               // Compute throughput

                        double cpu_clocks_per_word = double(clocks) / num_word;

                        double fpga_clocks_per_word = (double(FPGA_CLOCK_FREQ) / CPU_CLOCK_FREQ) * cpu_clocks_per_word;

    printf("  buff1            = 0x%08X\n", buff1);
    printf("  buff2            = 0x%08X\n", buff2);
    printf("  CPU clock        = %.1f MHz\n", CPU_CLOCK_FREQ / 1.0e6);
    printf("  FPGA clock       = %.1f MHz\n", FPGA_CLOCK_FREQ / 1.0e6);
                        printf("  num_byte         = %d\n", COPY_BYTES);
                        printf("  num_word         = %d\n", num_word);
                        printf("  CPU clocks       = %d\n", clocks);
                        printf("  CPU clocks/word  = %.1f\n", cpu_clocks_per_word);
                        printf("  FPGA clocks/word = %.1f\n", fpga_clocks_per_word);
                        printf("  rate             = %.1f MB/s\n", rate / 1.0e6);
                        printf("  Memory Tests     = %s\n", TestMemory() ? "PASSED" : "FAILED");

                        TestMemory();

                        return 0;
                        }

/*
 * Memory check to verify functionality.
 */
bool TestMemory()
                        {
                        XStatus status;

                        status = Xil_TestMem8(buff2, COPY_BYTES, 0xA5, XIL_TESTMEM_ALLMEMTESTS);
                        if(status != XST_SUCCESS)
                                                return false;

                        status = Xil_TestMem32((u32 *) buff2, COPY_BYTES/4, 0xAAAA5555, XIL_TESTMEM_ALLMEMTESTS);
                        if(status != XST_SUCCESS)
                                                return false;

                        // Simply test
                        memset(buff1, 0, COPY_BYTES);

                        for(int i = 0; i < COPY_BYTES; i++)
                                                buff2[i] = i % 256;

                        memcpy(buff1, buff2, COPY_BYTES);

                        return memcmp(buff1, buff2, COPY_BYTES) == 0;
                        }

  • Entorno de eclipse funcionando:


  • Resultados:

Hello World BRAM

  buff1            = 0x00124224
  buff2            = 0x40000000
  CPU clock        = 666.7 MHz
  FPGA clock       = 100.0 MHz
  num_byte         = 8192
  num_word         = 2048
  CPU clocks       = 38034
  CPU clocks/word  = 18.6
  FPGA clocks/word = 2.8
  rate             = 143.6 MB/s
  Memory Tests     = PASSED

Hello World DDR
  buff1            = 0x00124224
  buff2            = 0x00126224
  CPU clock        = 666.7 MHz
  FPGA clock       = 100.0 MHz
  num_byte         = 8192
  num_word         = 2048
  CPU clocks       = 6026
  CPU clocks/word  = 2.9
  FPGA clocks/word = 0.4
  rate             = 906.3 MB/s
  Memory Tests     = PASSED












No hay comentarios.:

Publicar un comentario