赞
踩
DDR2/3的进阶之创建MIG
1.在左下角window图标点击找到xilinx Design tools软件下,找到core generator 双击打开,创建一个 core generator;
2.在打开的界面下直接进行创建一个工程(不需要重新打开ISE进行创建)
1).part 按照芯片的型号选择,点击apply
2).generation 选择编写语言verilog,点击apply
3).点击ok结束创建
3.双击MIG Virtex6 and Spartan6 启动 MIG IP 的生成和配置工具
4.更改component name 为ddr3
5.选择兼容芯片,跳过
6.选择bank,根据原理图设计,ddr3连接FPGA
7.设置时钟周期3000ps=333.3Mhz,选择DDR芯片的型号MT47H64MHR-25E
8.输出阻抗与内部的ODT电阻,用于改善DDR2的数据完整性
9.用户接口设置6个端口:两个双向,一个写,一个读,两个读,以及排列形式bank-row-col;但是设计中只需要一个读一个写,因此个性化设置为勾选port2,port3
10.默认两个端口的优先级
11.RZQ与ZIO电阻分配,C2,L6单端
12.完成设置
13.licence 接受
14.生成MIG
15.关闭CORE Generator,查看生成的文件夹;
生成ddr3文件夹下面有docs文件,案列(太复杂),用户设计(最重要)。
16.新建一个工程命名ddr3_test
17.将之前生成的用户设计文件夹下rtl文件夹拷贝到当前的ddr3_test工程文件夹内
18.在ddr3_test工程中添加rtl内所有的.v文件,包含mcb_contorller内的rtl文件
ddr3.v:文件mig 的 IP 核顶层文件,后续的控制 DDR2 的一些列操作要通过该文件;
infrastructure.v:DDR2 控制器的时钟模块,里面例画了一个 PLLIP 核,为操作 IP 核提供时钟。
memc_wrapper.v:DDR2控制器
对DDR的操作只需要对ddr3.v文件进行例化,由于这个fpga芯片并不是AXI4接口,因此并不需要更改时钟,因为DDR3是需要进行时钟分频,芯片外界为50Mhz,DDR系统时钟需要625Mhz进行系修改分频参数;
19.修改时钟参数!!!
对于DDR2来说,没有分频率的设置,没有输出时钟频率的设置;
仅仅设置了DDR2的内存频率为333.33Mhz,即在ddr3.v文件中,只有系统输入时钟,DDR2内存时钟,用户时钟概念;
DDR内存频率:C3_MEMCLK_PERIOD:3000ps
系统时钟:FPGA输入时钟:c3_sys_clk;(一般为FPGA主频/倍频后的时钟频率);
C3_CLKOUT0_DIVIDE-C3_CLKOUT3_DIVIDE:为分频时钟;
C3_CLKFBOUT_MULT:是倍频倍数
C3_DIVCLK_DIVIDE:是分频系数
C3_CLKOUT0_DIVIDE和C3_CLKOUT1_DIVIDE是锁相环出来的时钟 0 与时钟 1,对他们不分频,因此参数都为1;这两个也是用了提供给 IP 核的时钟;
DDR2参数设置3000ps,=333.3Mhz
DDR2的内存时钟频率=c3_sys_clkC3_CLKFBOUT_MULT/(C3_DIVCLK_DIVIDE2)
还有一个公式
DDR2内存时钟频率=333.3Mhz,双向数据2=666.7Mhz
DDR2内存时钟频率=c3_sys_clkC3_CLKFBOUT_MULT/(C3_DIVCLK_DIVIDE)
因此可以设置C3_CLKFBOUT_MULT=27;
用户时钟ddr3.v文件中的c3_clk0,为DDR时钟/2=100M;
20.本次我将FPGA的时钟频率倍频到200Mhz作为c3_sys_clk系统时钟,DDR2要求只需要到200Mhz,因此C3_CLKFBOUT_MULT=2;C3_DIVCLK_DIVIDE=2;由于最小的DDR2设置为3000ps,所以想单独设置的时刻可以定制;
c3_clk0设置为85M;
21.参照了野火开发板的设置,以及DDR3的普及,发现DDR3AXI4接口有分频设置用于生成用户时钟频率,注意:时钟频率比与数据位带宽成反比;因此DDR3中有DDR3内存时钟频率,PHY to Controller Clock Ratio,输入时钟频率,系统时钟频率,参考时钟频率
DDR3的时钟设置如下
c3_memeroy_period:800Mhz
PHY to Controller Clock Ratio,该时钟是MIG输出给UI的时钟,分频率4:1
input clock_period:800M/4=200Mhz,输入时钟频率,这是输入给MIG 核的时钟,IP核内部会自己调用pll和MMCM 来产生自己的工作时钟
sys_clk:FPGA输入DDR模块的时钟(主频50M或者PLL输出200Mhz)。Reference clock,是设置MIG的参考时钟,这个时钟频率是固定的,如果工作频率>666MHz ,参考时钟固定为300MHz/400MHz,其他工作频率固定为200MHz。
注:如果system clock的频率在199-201MHz之间,这里会出现一个use system clock 的选项,意思就是用系统时钟作为参考时钟。
数据位宽:64bit,DDR数据位宽 64/4=16bit,常用的DDR数据位宽32bit,则数据位宽为128bit;
如果想额外增加时钟输出,则需要更改ddr.3v文件中C3_CLKOUT2_DIVIDE-C3_CLKOUT3_DIVIDE分频参数,并在infrastucture.v文件中添加对应的全局时钟资源缓冲,原语BUFG,IBUFG;
全部设置完成之后,IP核就设置成功了,接下来就根据MCB的控制时序进行封装控制IP核实现DDR的读取。
22.关于DDR2与DDR3时序的区别上链接!
https://blog.csdn.net/weixin_43070186/article/details/89005226;
但是这个终究都是根据接口是AXI4来设置的,还有Native接口,还是看ug416.pdf
23.DDR2读写时序
写:先写数据FIFO,再写指令,突发长度,地址;cmd_en为一个时钟周期,cmd_instr=010;cmd_bl=50,cmd_addr=50;(为了避免数据刷新,不使用前50个地址);后wr_en,wr_data,一直到50个数据写完,wr_en=0;再返回写
cmd_en,cmd_bl,cmd_addr,cmd_instr,写数据,,,一直到数据全部写入DDR中后再读!!!
24.DDR2读时序
读:先写读指令(cmd_en=1,一个时钟周期),突发长度50,地址:从50开始,cmd_bl,cmd_addr,cmd_en,cmd_instr;=011;间隔一段时间后,再读数据FIFO,rd_en,rd_data,每50个地址数据读完再重新写cmd_bl,cmd_addr,cmd_en,cmd_instr;=011,再读FIFO内的数据,一直到读的数据全部读完!结束
25.对于突发长度可能会有一些疑问,本来说的是只能突发4/8个长度,怎么能>8???是因为每次都是四个四个地址进行写数据,过于麻烦和繁琐,所以我们创建一个写FIFO和读FIFO 进行大容量的数据取写,去读。将一个FIFO的写入/读出数据个数作为一个突发长度,进行大批量的数据写入/读出!!!因此再这个DDR2中需要一个读写控制模块和一个写FIFO ,一个读FIFO,和一个顶层将DDR2MIG ip核接口与用户接口进行封装到top层例化接口;
26.AXI4接口
27.具体的有关DDR3的时序代码以及实验流程可参考百度云
链接:https://pan.baidu.com/s/1hyrp8hvakh6BoT0CS4bQLA
提取码:7777
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。