Xilinx MicroBlaze软核驱动DDR3

Xilinx MicroBlaze软核驱动DDR3

说明:通过Vivado生成MicroBlaze工程导入SDK实现DDR3的读写。
环境:Vivado2018.3。
IP核:MicroBlaze。
参考手册:
pg142: AXI UART Lite v2.0
ug586:7Series_MIS
工程:DDR3


1.DDR简介

MT41K256M16xx-125:
内存大小为512MB,数据接口为16bit。
为什么是512MB:256M空间,数据线为16bit,1Byte=8bit,256M×16bit=512M×8bit=512MB。
下图为型号参数的具体解析:

1.1DDR3地址

  DDR3的内部是一个存储阵列,将数据“填”进去,你可以它想象成一张表格。和表格的检索原理一样,先指定一个行(Row),再指定一个列(Column),我们就可以准确地找到所需要的单元格,这就是内存芯片寻址的基本原理。对于内存,这个单元格可称为存储单元,那么这个表格(存储阵列)就是逻辑 Bank(Logical Bank,下面简称Bank)。 DDR3内部Bank示意图,这是一个NXN的阵列,B代表Bank地址编号,C代表列地址编号,R代表行地址编号。在这里插入图片描述
以下列举了不同容量的DDR3地址:
在这里插入图片描述
在这里插入图片描述
注意以上单位为GBit。比如MT41K256M16TW-107容量为512MB=512×8Mbit=4096Mbit=4Gbit,就要看表2.11.4 4Gb中的256M×16。
在这里插入图片描述

2. MicroBlaze简介

  MicroBlaze嵌入式软核是一个被Xilinx公司优化过的可以嵌入在FPGA中的RISC处理器软核,具有运行速度快、占用资源少、可配置强等优点,和其他外设IP核一起,可以完成可编程系统芯片(SOPC)的设计。
  FPGA是可编程的硬件逻辑电路,MicroBlaze是一种处理器电路,使用MicroBlaze就相当于在FPGA内部做了一个CPU在里面,可以用C语言编写程序,在这个CPU上跑C语言的软件程序,FPGA偏向逻辑,做控制比较麻烦,CPU做控制比较方便。

3.MicroBlaze设计流程

新建Vivado工程…

3.2 DDR Block Design 流程

在这里插入图片描述
添加MicroBlaze IP:
在这里插入图片描述
Run Block Automation:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
添加串口IP:
在这里插入图片描述
添加MIG IP(DDR控制IP):
在这里插入图片描述
在这里插入图片描述
MIG介绍:详细请看FPGA_MIG驱动DDR3
如下图所示:FPGA用户逻辑↔MIG↔DDR3的端口连接示意图(可以理解MIG作为中间介质让我们间接的控制了DDR,简化了控制接口):
在这里插入图片描述
配置MIG IP:双击mig_7series
Next:
在这里插入图片描述
在这里插入图片描述
根据自己板子型号选择:
在这里插入图片描述
DDR类型:
在这里插入图片描述
时钟配置说明:
1.Clock Period
在这里插入图片描述
即MIG对DDR接口的速率为800M*2=1600M(双沿)。
MIG输出到app接口上的时钟ui_clk为800M/4=200M。
UI时钟频率ui_clk为DDR时钟频率的1/4,也就是一个用户时钟周期(两个边沿)对应8个DDR时钟边沿。burst length可以理解为MIG连续操作DDR地址的个数,故在4:1时钟比例下,一个用户时钟周期正好对8个地址进行了读/写操作,256bit数据分8次(32bit)写入DDR中,即逻辑用户以时钟ui_clk写256bit数据至MIG,MIG控制器将以时钟ddr_clk向DDR写8次(32bit(数据位宽配置为32bit))数据。由此分析,在写数据时让app_wdf_end = app_wdf_wren即可,并且读/写操作时地址递增步长为8。
在这里插入图片描述
2.Input Clock Period
输入给MIG的时钟为200M。
在这里插入图片描述

根据自己的DDR以及FPGAA性能选择工作时钟、位宽、型号:
在这里插入图片描述

①:工作时钟为什么选择400MHz
我所选FPGA部件和FPGA速度等级据定了允许该时钟的周期范围(1875-3300ps)
在这里插入图片描述
在这里插入图片描述
所以支持的频率为303.03-533.33MHz,在中间选择了400Mhz。即MIG对DDR接口的数据速率为400M×2=800M(双沿)。
②:UI时钟频率ui_clk为DDR时钟频率的1/4。
③:根据自己DDR型号
在这里插入图片描述
④数据位宽:用了一片MK41K256M16,数据位宽为16bit。
输入给MIG的时钟:在这里插入图片描述
选择所需的时钟配置:
在这里插入图片描述
内部终端阻抗:
在这里插入图片描述
在这里插入图片描述
管脚分配:输入或者直接导入XDC、UCK文件
在这里插入图片描述
在这里插入图片描述
…一直到Generate
在这里插入图片描述
执行Run Connection Automation
在这里插入图片描述
全貌:
在这里插入图片描述
対生成的网络做以下修改:
1、时钟
根据自己的板子,选择输入时钟大小和时钟方式,单端还是差分
在这里插入图片描述
PLL分别输出100MHz和200MHz的时钟、去除reset和locked信号:
在这里插入图片描述
删除多余端口、并将clk_in1引出:
在这里插入图片描述
2、复位
去除复位引脚,引入常量IP constant
在这里插入图片描述
在这里插入图片描述
因为是低电平复位,常量IP设置值为1
在这里插入图片描述
3、串口波特率
双击axi_uartlite,更改波特率:
在这里插入图片描述
4、配置DDR时钟
sys_clk、clk_ref说明如下,clk_ref输入时钟设置为200MHz
在这里插入图片描述
PLL clk_out2输出为200MHz连接至migG clk_ref
在这里插入图片描述
5、引出DDR3端口
在这里插入图片描述
进行设计验证
在这里插入图片描述
在这里插入图片描述
观察地址映射:
在这里插入图片描述
全貌:
在这里插入图片描述

Generate Block Design:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
进行管脚约束:
DDR在IP里已经约束完成,在这里也可以看到DDR的约束
在这里插入图片描述
生成bit流
在这里插入图片描述
Export Hardware:要包含.bit文件
在这里插入图片描述
Lanuch SDK:
在这里插入图片描述

4.SDK工程

新建一个hello word 工程
在这里插入图片描述
在.hdf文件中查看DDR3的地址范围位为0x8000_0000-0x9FFF_FFFF
寻址空间为1FFF_FFFF即536870912Byte=512MB。
在这里插入图片描述
将数据0-99写入DDR,并读出0-9、20、50。
介入以下测试代码:

#include <stdio.h>
#include "platform.h"
#include "xparameters.h"
#include "xil_printf.h"

int main()
{
    
    
	int i;
	u32 DDR_BUFF[10];
	u32 DDR_Val[3];
    init_platform();

    u32 *DDR_ADDR;
    DDR_ADDR = (u32 *)0x80000000;
    for(i=0;i<100;i++)
    {
    
    
    	*(DDR_ADDR+i) = i;
    }
    for(i=0;i<10;i++)
    {
    
    
    	DDR_BUFF[i] = *(DDR_ADDR+i);
    }

    DDR_Val[0] = *(DDR_ADDR+20);
    DDR_Val[1] = *(DDR_ADDR+50);
    DDR_Val[2] = *(DDR_ADDR+90);
    print("Finshed\n\r");
    cleanup_platform();
    return 0;
}

调试:先进行调试设置
在这里插入图片描述
在这里插入图片描述
结果:
在这里插入图片描述
更改地址:

#include <stdio.h>
#include "platform.h"
#include "xparameters.h"
#include "xil_printf.h"

int main()
{
    
    
	u32 i;
	u32 DDR_BUFF[10];
	u32 DDR_Val[3];
    init_platform();

    u32 *DDR_ADDR;
    DDR_ADDR = (u32 *)0x81000000;
    for(i=0;i<1000;i++)
    {
    
    
    	*(DDR_ADDR+i) = i;
    }
    for(i=0;i<10;i++)
    {
    
    
    	DDR_BUFF[i] = *(DDR_ADDR+i);
    }

    DDR_Val[0] = *(DDR_ADDR+200);
    DDR_Val[1] = *(DDR_ADDR+500);
    DDR_Val[2] = *(DDR_ADDR+999);
    print("Finshed\n\r");

    cleanup_platform();
    return 0;
}

在这里插入图片描述

注意:将DDR配置为内存时,系统内存区域就会映射到了DDR中,用的时候注意跳开此区域:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

5.SDK DDR用指令分别访问 DDR、BRAM速度

DDR3的频率配置的为200MHz、Mircroblaze时钟为100MHz。

以下时间仅仅是通过for循环对DDR和BRAM读写做了个时间对比,不要理解为DDR就这么慢…
利用for循环测试DDR3读写10000个数据:

#include <stdio.h>
#include "platform.h"
#include "xil_printf.h"
#include "xparameters.h"
#include "xgpio.h"

u32 DDR_BUFF[10000];
int main()
{
    
    
	u32 i;
	u32 j;
    init_platform();

    u32 *DDR_ADDR;
    u32 *LED_ADDR;
    DDR_ADDR = (u32 *)0x81000000;
    LED_ADDR = (u32 *)0x40000000;
    *LED_ADDR = 0x03;

    *LED_ADDR = 0x00;

		for(i=0;i<10000;i++)
		{
    
    
			*(DDR_ADDR+i) = i;
		}
		for(i=0;i<10000;i++)
		{
    
    
			DDR_BUFF[i] = *(DDR_ADDR+i) ;
		}
    *LED_ADDR = 0x03;

    cleanup_platform();
    return 0;
}

所需时间(低电平持续时间):8.1ms
在这里插入图片描述

利用for循环测试BRAM读写10000个数据:

#include <stdio.h>
#include "platform.h"
#include "xil_printf.h"
#include "xparameters.h"
#include "xgpio.h"

u32 BRAM_BUFF[10000];
int main()
{
    
    
	u32 i;
	u32 j;
    init_platform();

    u32 *DDR_ADDR;
    u32 *LED_ADDR;
    BRAM_ADDR = (u32 *)0x0000FFFF;
    LED_ADDR = (u32 *)0x40000000;
    *LED_ADDR = 0x03;

    *LED_ADDR = 0x00;

		for(i=0;i<10000;i++)
		{
    
    
			*(BRAM_ADDR -i) = i;
		}
		for(i=0;i<10000;i++)
		{
    
    
			BRAM_BUFF[i] = *(BRAM_ADDR -i) ;
		}
    *LED_ADDR = 0x03;

    cleanup_platform();
    return 0;
}

所需时间(低电平持续时间):5.4ms
在这里插入图片描述

测试20000个空for循环需要的时间:

#include <stdio.h>
#include "platform.h"
#include "xil_printf.h"
#include "xparameters.h"
#include "xgpio.h"

u32 DDR_BUFF[10000];
int main()
{
    
    
	u32 i;
	u32 j;
    init_platform();

    u32 *DDR_ADDR;
    u32 *LED_ADDR;
    LED_ADDR = (u32 *)0x40000000;
    *LED_ADDR = 0x03;

    *LED_ADDR = 0x00;

		for(i=0;i<10000;i++)
		{
    
    
			
		}
		for(i=0;i<10000;i++)
		{
    
    
			
		}
    *LED_ADDR = 0x03;

    cleanup_platform();
    return 0;
}

所需时间(低电平持续时间):2.4ms
在这里插入图片描述

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

猜你喜欢

转载自blog.csdn.net/qq_40147893/article/details/115342602
今日推荐