1.首先介绍一下Zedboard的存储资源
在Zedboard板子上面有三个存储器,分别是DDR3、QSPI和SD卡,另外在PL端有Block RAM存储器阵列,为了与DRAM(分布式RAM)区分开,所以叫块RAM。ZYNQ的每一个BRAM 36KB,7020的BRAM有140个(4.9M),7030有265个(9.3M),7045有545个(19.2M)。每一个BRAM都有两个共享数据的独立端口,当然是可以配置的,可用于片内数据缓存、FIFO缓冲。
2.本实验首先使用ARM端的DDR3,是纯PS的操作,也很简单。
首先建立VIVADO工程,创建block,添加ZYNQ IP,然后自动连好线,可以看见DDR已经引出来了;
,双击zynq,配置使能uart1,然后连接时钟线。就这样硬件上设计完成。完全不需要使用PL的资源,接下来就是生成顶层文件,生成比特流,导入到SDK。
在SDK中,创建工程,然后编写逻辑驱动程序。
先打开文件 “xparameters_ps.h”,可以看到DDR3的地址分配情况。
然后直接操纵这些地址来读写就行了。
附上程序:
#include "stdio.h"
#include "xparameters_ps.h"
#include "xil_printf.h"
#include "xil_io.h"
#define DDR_BASEARDDR XPAR_DDR_MEM_BASEADDR+0x10000000 //在地址的0x10000000 处执行读写操作(先写了在读出来)
int main()
{
int i ,j,k;
printf("Hello World\n\r");
for(i=0;i<32;i++)
{
Xil_Out32(DDR_BASEARDDR+i*4, i);
}
for(j=0;j<32;j++)
{
k = Xil_In32(DDR_BASEARDDR+j*4);
printf("the addr at %x is %d\n\r",DDR_BASEARDDR+j*4,k);
}
return 0;
}
编译后运行可以看见,写进去的数据依次被读出来了。
3.接下来是BRAM的使用
BRAM的介绍前面以及说过了,接下来是直接使用,因为是PL的资源,所以会使用到AXI的IP,使用Block Memory Generator,它使用FPGA的BRAM资源为我们提供可编程的RAM。然后使用AXI BRAM Cotroller来控制读写。
因此先设计硬件图,
具体的流程参照:https://blog.csdn.net/u014485485/article/details/78882027
Block Memory Generator的IP,有两个端口,一个用来读一个用来写,分别被AXI总线控制。接下来就是生成顶层文件,生成比特流,导入到SDK。在SDK中,创建工程,然后编写逻辑驱动程序。首先也要查看一下生成的BRAM的地址,(可以在VIVADO修改)
地址已经知道了,就可以在驱动程序里面进行读写的操作了,也很简单。附上程序:
#include <stdio.h>
#include "xparameters.h"
#include "xil_io.h"
int main()
{
int i;
u32 Value = 0x00;
printf("Hello World\n\r");
for(i = 0 ; i < 3 ; i++)
Xil_Out32(XPAR_AXI_BRAM_CTRL_0_S_AXI_BASEADDR + 4*i, Value + i);
for(i = 0 ; i < 3 ; i++)
{
Value = Xil_In32(XPAR_AXI_BRAM_CTRL_0_S_AXI_BASEADDR + 4*i);
xil_printf("Address:%x Value:%x\r\n",XPAR_AXI_BRAM_CTRL_0_S_AXI_BASEADDR + 4*i,Value);
}
printf("\r\n");
printf("\r\n");
for(i = 0 ; i < 3 ; i++)
{
Value = Xil_In32(XPAR_AXI_BRAM_CTRL_1_S_AXI_BASEADDR + 4*i);
xil_printf("Address:%x Value:%x\r\n",XPAR_AXI_BRAM_CTRL_1_S_AXI_BASEADDR + 4*i,Value);
}
return 0;
}
这样可以实现从两个不同地址访问到同一片RAM 里面进行读写操作,极大的提高了效率。