Xilinx MicroBlaze软核驱动DDR4
说明:通过Vivado生成MicroBlaze工程导入SDK实现DDR4的读写。
环境:Vivado2018.3。
IP核:MicroBlaze。
参考手册:
pg150:UltraScale Architecture-Based FPGAs Memory IP v1.4
基础知识:Xilinx MicroBlaze软核驱动DDR3(最好先看一下)
1.MicroBlaze设计流程
新建Vivado工程…
1.2 DDR Block Design 流程
Creat Block Design:
添加Microblaze核:
Run Block Automation:
添加Uartlite核:
双击更改波特率为115200
添加DDR4 IP:
双击配置DDR4 IP
根据自己DDR选择型号
即MIG对DDR接口的速率为1200M*2=2400M(双沿)。
MIG输出到app接口上的时钟ui_clk为1200M/4=300M。
UI时钟频率ui_clk为DDR时钟频率的1/4,也就是一个用户时钟周期(两个边沿)对应8个DDR时钟边沿。
Run Connection Automation:
对生成的网络进行一下修改:
1、时钟
双击
根据自己输入系统时钟,选择时钟频率和差分还是单端模式:
去除reset和locked选项:
删除多余的端口重新Run Connection Automation
2、复位
将DDR复位信号和rst_clk_wizIP的复位删除,引入常量IP将其连接
进行设计检查:
Great HDL Wrapper:
约束:
对管脚以及DDR端口进行约束
注意:DDR4的diff_clock_rtl_1这个时钟输入为100MHz的差分时钟输入,根据自己的板子
生成bit流文件
导入SDK,记得包含bit文件:
2.SDK工程
新建一个hello word 工程
在.hdf文件中查看DDR3的地址范围位为0x8000_0000-0x9FFF_FFFF
寻址空间为1FFF_FFFF即536870912Byte=512MB。
将数据0-99写入DDR,并读出。
介入以下测试代码:
#include <stdio.h>
#include "platform.h"
#include "xil_printf.h"
#include "xparameters.h"
#include "xgpio.h"
int main()
{
u32 i;
u32 j;
u32 DDR_BUFF[100];
init_platform();
u32 *DDR_ADDR;
u32 *LED_ADDR;
DDR_ADDR = (u32 *)0x80000000;
LED_ADDR = (u32 *)0x40000000;
for(i=0;i<100;i++)
{
*(DDR_ADDR+i) = i;
}
for(i=0;i<100;i++)
{
DDR_BUFF[i] = *(DDR_ADDR+i) ;
}
cleanup_platform();
return 0;
}
调试:先进行调试设置
结果:
2.1 不断电重新读数据
关闭写操作,未断电在改地址进行读数据
#include <stdio.h>
#include "platform.h"
#include "xil_printf.h"
#include "xparameters.h"
#include "xgpio.h"
int main()
{
u32 i;
u32 j;
u32 DDR_BUFF[100];
init_platform();
u32 *DDR_ADDR;
u32 *LED_ADDR;
DDR_ADDR = (u32 *)0x80000000;
LED_ADDR = (u32 *)0x40000000;
// for(i=0;i<100;i++)
// {
// *(DDR_ADDR+i) = i;
// }
for(i=0;i<100;i++)
{
DDR_BUFF[i] = *(DDR_ADDR+i) ;
}
cleanup_platform();
return 0;
}
结果
注意 cleanup_platform();函数会释放内存,断点设置在此函数前面,或者不用此函数。
★★★如有错误欢迎指导!!!