Xilinx MicroBlaze软核驱动DDR4

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();函数会释放内存,断点设置在此函数前面,或者不用此函数。

★★★如有错误欢迎指导!!!

在这里插入图片描述

  • 4
    点赞
  • 47
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

数字硬鉴

你的鼓励就是我创作的最大动力。

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值