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