DDR设计总结

本文针对DDR的一些知识做一个统一的整理,一个项目是18年开始,基于光纤通信的一块通信板卡,作为一个开发,硬件如果按开发板设计原理图,逻辑配置一直参考原有的demo,可能会对一些基本的认识了解不够深,最近刚好发生一起由于物料差异引起的DDR不良问题,刚好有个机会,对DDR做个深入的了解,做了一个统一的梳理,同时将前前后后遇到的一些问题,都有一个总结,一方面加深自己对DDR设计的认识,一方面希望可以帮助到他人处理类似问题。

本文分5个部分进行介绍:

DDR原理介绍;

DDR硬件设计注意事项;

xilinx  DDR控制器mig介绍;

基于MicroBlaze 的DDR测试方法及原理介绍;

DDR初始化流程介绍。

不做知识的创造者,只做知识的搬运工,在其中都根据自己遇到的一些项目经验,增加了一些注意事项的描述。

  • DDR介绍

DDR3的内部是一个存储阵列,将数据“填”进去,你可以它想象成一张表格。和表格的检索原理一样,先指定一个行(Row),再指定一个列(Column),我们就可以准确地找到所需要的单元格,这就是内存芯片寻址的基本原理。对于内存,这个单元格可称为存储单元,那么这个表格(存储阵列)就是逻辑 Bank(Logical Bank,下面简称Bank)。

https://i-blog.csdnimg.cn/blog_migrate/dcb7a10f9f63996647666d4811f6f158.png

DDR3内部Bank示意图,这是一个NXN的阵列,B代表Bank地址编号,C代表列地址编号,R代表行地址编号。如果寻址命令是B1、R2、C6,就能确定地址是图中红格的目前DDR3内存芯片基本上都是8个Bank设计,也就是说一共有8个这样的“表格”。寻址的流程也就是先指定Bank地址,再指定行地址,然后指列地址最终的确寻址单元。

 目前DDR3系统而言,还存在物理Bank的概念,这是对内存子系统的一个相关术语,并不针对内存芯片。内存为了保证CPU正常工作,必须一次传输完CPU 在一个传输周期内所需要的数据。而CPU在一个传输周期能接受的数据容量就是CPU数据总线的位宽,单位是bit(位)。控制内存与CPU之间数据交换的北桥芯片也因此将内存总线的数据位宽等同于CPU数据总线的位宽,这个位宽就称为物理Bank(Physical Bank,有的资料称之为Rank)的位宽。目前这个位宽基本为64bit。

在实际工作中,Bank地址与相应的行地址是同时发出的,此时这个命令称之为“行激活”(Row Active)。在此之后,将发送列地址寻址命令与具体的操作命令(是读还是写),这两个命令也是同时发出的,所以一般都会以“读/写命令”来表示列寻址。根据相关的标准,从行有效到读/写命令发出之间的间隔被定义为tRCD,即RAS to CAS Delay(RAS至CAS延迟,RAS就是行地址选通脉冲,CAS就是列地址选通脉冲),我们可以理解为行选通周期。tRCD是DDR的一个重要时序参数,广义的tRCD以时钟周期(tCK,Clock Time)数为单位,比如tRCD=3,就代表延迟周期为两个时钟周期,具体到确切的时间,则要根据时钟频率而定,DDR3-800,tRCD=3,代表30ns的延迟。

https://i-blog.csdnimg.cn/blog_migrate/6ba802284e9e51fc027c8055309a3409.png

接下来,相关的列地址被选中之后,将会触发数据传输,但从存储单元中输出到真正出现在内存芯片的 I/O 接口之间还需要一定的时间(数据触发本身就有延迟,而且还需要进行信号放大),这段时间就是非常著名的 CL(CAS Latency,列地址脉冲选通潜伏期)。CL 的数值与 tRCD 一样,以时钟周期数表示。如 DDR3-800,时钟频率为 100MHz,时钟周期为 10ns,如果 CL=2 就意味着 20ns 的潜伏期。不过CL只是针对读取操作。

由于芯片体积的原因,存储单元中的电容容量很小,所以信号要经过放大来保证其有效的识别性,这个放大/驱动工作由S-AMP负责,一个存储体对应一个S- AMP通道。但它要有一个准备时间才能保证信号的发送强度(事前还要进行电压比较以进行逻辑电平的判断),因此从数据I/O总线上有数据输出之前的一个时钟上升沿开始,数据即已传向S-AMP,也就是说此时数据已经被触发,经过一定的驱动时间最终传向数据I/O总线进行输出,这段时间我们称之为 tAC(Access Time from CLK,时钟触发后的访问时间)。

https://i-blog.csdnimg.cn/blog_migrate/8be09c39a6a727793f1ba28db82c25f2.png

目前内存的读写基本都是连续的,因为与CPU交换的数据量以一个Cache Line(即CPU内Cache的存储单位)的容量为准,一般为64字节。而现有的Rank位宽为8字节(64bit),那么就要一次连续传输8次,这就涉及到我们也经常能遇到的突发传输的概念。突发(Burst)是指在同一行中相邻的存储单元连续进行数据传输的方式,连续传输的周期数就是突发长度(Burst Lengths,简称BL)。

在进行突发传输时,只要指定起始列地址与突发长度,内存就会依次地自动对后面相应数量的存储单元进行读/写操作而不再需要控制器连续地提供列地址。这样,除了第一笔数据的传输需要若干个周期(主要是之前的延迟,一般的是tRCD+CL)外,其后每个数据只需一个周期的即可获得。https://i-blog.csdnimg.cn/blog_migrate/031a6776c3e29d2a78fa6fe34ca178d7.png

突发连续读取模式:只要指定起始列地址与突发长度,后续的寻址与数据的读取自动进行,而只要控制好两段突发读取命令的间隔周期(与BL相同)即可做到连续的突发传输。

谈到了突发长度时。如果BL=4,那么也就是说一次就传送4×64bit的数据。但是,如果其中的第二笔数据是不需要的,怎么办?还都传输吗?为了屏蔽不需要的数据,人们采用了数据掩码(Data I/O Mask,简称DQM)技术。通过DQM,内存可以控制I/O端口取消哪些输出或输入的数据。这里需要强调的是,在读取时,被屏蔽的数据仍然会从存储体传出,只是在“掩码逻辑单元”处被屏蔽。DQM由北桥控制,为了精确屏蔽一个P-Bank位宽中的每个字节,每个DIMM有8个DQM 信号线,每个信号针对一个字节。这样,对于4bit位宽芯片,两个芯片共用一个DQM信号线,对于8bit位宽芯片,一个芯片占用一个DQM信号,而对于 16bit位宽芯片,则需要两个DQM引脚。

 在数据读取完之后,为了腾出读出放大器以供同一Bank内其他行的寻址并传输数据,内存芯片将进行预充电的操作来关闭当前工作行。还是以上面那个Bank示意图为例。当前寻址的存储单元是B1、R2、C6。如果接下来的寻址命令是B1、R2、C4,则不用预充电,因为读出放大器正在为这一行服务。但如果地址命令是B1、R4、C4,由于是同一Bank的不同行,那么就必须要先把R2关闭,才能对R4寻址。从开始关闭现有的工作行,到可以打开新的工作行之间的间隔就是tRP(Row Precharge command Period,行预充电有效周期),单位也是时钟周期数。

https://i-blog.csdnimg.cn/blog_migrate/83009533dbd0c3cbd1faaa5591c8dba6.png

在不同Bank间读写也是这样,先把原来数据写回,再激活新的Bank/Row。

数据选取脉冲(DQS),DQS 是DDR中的重要功能,它的功能主要用来在一个时钟周期内准确的区分出每个传输周期,并便于接收方准确接收数据。每一颗芯片都有一个DQS信号线,它是双向的,在写入时它用来传送由北桥发来的DQS信号,读取时,则由芯片生成DQS向北桥发送。完全可以说,它就是数据的同步信号。

在读取时,DQS与数据信号同时生成(也是在CK与CK#的交叉点)。而DDR内存中的CL也就是从CAS发出到DQS生成的间隔,DQS生成时,芯片内部的预取已经完毕了,由于预取的原因,实际的数据传出可能会提前于DQS发生(数据提前于DQS传出)。由于是并行传输,DDR内存对tAC也有一定的要求,对于DDR266,tAC的允许范围是±0.75ns,对于DDR333,则是±0.7ns,有关它们的时序图示见前文,其中CL里包含了一段DQS 的导入期。

DQS 在读取时与数据同步传输,那么接收时也是以DQS的上下沿为准吗?不,如果以DQS的上下沿区分数据周期的危险很大。由于芯片有预取的操作,所以输出时的同步很难控制,只能限制在一定的时间范围内,数据在各I/O端口的出现时间可能有快有慢,会与DQS有一定的间隔,这也就是为什么要有一个tAC规定的原因。而在接收方,一切必须保证同步接收,不能有tAC之类的偏差。这样在写入时,芯片不再自己生成DQS,而以发送方传来的DQS为基准,并相应延后一定的时间,在DQS的中部为数据周期的选取分割点(在读取时分割点就是上下沿),从这里分隔开两个传输周期。这样做的好处是,由于各数据信号都会有一个逻辑电平保持周期,即使发送时不同步,在DQS上下沿时都处于保持周期中,此时数据接收触发的准确性无疑是最高的。

https://i-blog.csdnimg.cn/blog_migrate/1e289455cd6d73f76f83eaf187a91428.png

在写入时,以DQS的高/低电平期中部为数据周期分割点,而不是上/下沿,但数据的接收触发仍为DQS的上/下沿。

以下是DDR3的各个管脚定义

https://i-blog.csdnimg.cn/blog_migrate/d5dafb5e91eb2ec87c7d6301f60634c6.png

https://i-blog.csdnimg.cn/blog_migrate/6344a3fb06095a9dc734434ea2417ef2.png

https://i-blog.csdnimg.cn/blog_migrate/8cd98761f299d18ad50d2e4024f0aa12.png

https://i-blog.csdnimg.cn/blog_migrate/ba3f1c40a334e90471c0ddb48f2bac0d.png

  • DDR硬件设计注意事项

原理图设计:需要注意引脚约束,每一组数据线和对应控制线需放在一起,其中DQS为FPGA固定管脚,其余DQ管脚和DM管脚可根据布局布线,适当调整。此时需注意VTTREF这个管脚,如果外置了参考电压,则在MIG核设计时,不需要勾选内部参考电压,对于高速数据传输这个参考电压很关键,对于800M以下速率,原则上可以使用内部参考电压。

PCB设计:

  1. 确定拓扑结构,分为星行拓扑核菊花链拓扑。DDR1/2采用星形结构,DDR3采用菊花链结构,但是也不是所有。只影响地址线,不影响数据线。下图为菊花链拓扑结构示意图·  ,其中到各个端粒的短接线要求尽可能短。                                         
  2. 设置线宽与线距

以下时PCB设计时一些时序约束。,另外同一组信号线,注意放在同一层。绕线时尽量采用3倍线宽,45度角绕等长,

  • Xilinx DDR控制器介绍

在MIG控制器之前,先简单介绍以下Xilinx的MIG核,使用时,只需要进行相应的配置。以下将对MIG的每一个设置做详细介绍。

1、打开vivado,新建一个工程,工程路径和名字自己定。

2、点击左侧的“IP Catalog”

https://i-blog.csdnimg.cn/blog_migrate/f0f3ad50692f91805b1d73aae1077f5f.png

3、输入“MIG”,搜索MIG控制器。

https://i-blog.csdnimg.cn/blog_migrate/6fed75d3c122a52270ce16a0982ad000.png

4、双击“MIG”控制器,对MIG控制器进行设置。

5、然后会出来一个MIG控制器编辑界面,选择对应的FPGA器件,如下。直接NEXT.

https://i-blog.csdnimg.cn/blog_migrate/c6e74aa38c90c47a459a44d6a283d410.png

6、选择“Create Design”,然后Next。(Number of Controllers 指的是你要几个控制器,AXI4 Interface指的是MIG是AXI4接口的,其他的选项你不用了解了,一般选择AXI接口)。

https://i-blog.csdnimg.cn/blog_migrate/997f139b439b1b0ad0ce1c828e5a08d6.png

7、 这里问的是你要不要兼容其他芯片,这里不用兼容,直接Next。

https://i-blog.csdnimg.cn/blog_migrate/997f139b439b1b0ad0ce1c828e5a08d6.png

8、 选择“DDR3 SDRAM”,然后Next

https://i-blog.csdnimg.cn/blog_migrate/63f78a99b207a4357f44d35bacbaf564.png

9、这个界面很重要,有很多东西需要理解。按照如下设置,其他不变,然后Next。

https://i-blog.csdnimg.cn/blog_migrate/731b2ef67c1bb1dcd4ef2c235c1b792f.png解释:1、这里的400MHz指的是在DDR3这个芯片里面实际跑的时钟频率

  2、4:1,指的是    DDR3时钟频率 : MIG控制器给用户的时钟频率 = 4:1。也就是,如果你设置DDR3的工作频率是400MHz,那么MIG控制器会给你一个100MHz的用户时钟。那这个用户时钟拿来跟什么呢?这个用户时钟是用来作为读MIG控制器地址生成的时钟。

 3、Components指的是DDR3的型号是元件类,而不是像笔记本那种的插条类。笔记本是SODIMMs。这里一共有四个选项。

 4、这是DDR3芯片型号,根据你的DDR3芯片手册来选。

 5、电压,根据你的DDR3芯片手册来选。

 6、DDR3的物理位宽,这个需要根据你自己的芯片来选择。

10、按如下设置,这个页面的选项也很重要。

https://i-blog.csdnimg.cn/blog_migrate/9ea5ddbb3621eb46f6d6cef0ecb5f22d.png1、这里的Input Clock Period 指的是输入到MIG里面的时钟是400MHz

2、这里设置读写为顺序读写,并且burst的长度设置为8。注意界面的小字部分。

3、这个我也不太清楚。

11、这个界面也很重要。按照如下设置,然后Next.

https://i-blog.csdnimg.cn/blog_migrate/4d714d16437201fef361c3f4adc1ea9e.png

https://i-blog.csdnimg.cn/blog_migrate/fea808d354a881910f2ac432db1987e5.png第一个是系统时钟System Clock: No Buffer, 为甚么选No Buffer,我也不太清楚,

第二个是参考时钟Reference Clock:No Buffer,为甚么选No Buffer,我也不太清楚

第三个是系统复位极性,是对MIG控制器复位。这里选择低电平复位。

第四个是不需要系统调试信号。所以第五个Sample Data Depth 就不可选了。

第七个IO Power Reduction 是指打开低功耗。

第八个是XADC补偿使能。

12、内部终端电阻设置50欧姆。然后Next.

https://i-blog.csdnimg.cn/blog_migrate/dc2260b7a762fc4a197605b2d4dc912f.png

13、选择DDR3芯片引脚。这些引脚可以在电路原理图上查到,但是这样配置芯片引脚会很慢的。选择第二个,然后Next

https://i-blog.csdnimg.cn/blog_migrate/c3b91aa50fcc6dca46ff906ec9aa53a5.png

  选择第二个,直接读取DDR3的引脚,这样就不用进行配置了。

    14、选“Read XDC/UCF” 直接读取DDR3的引脚。然后再点“Validate”,验证已经选择的引脚是否正确。只有验证正确了才可以点击Next.,其中这个UCF文件可以通过原理图去导,Cadence有这个功能。

https://i-blog.csdnimg.cn/blog_migrate/43a09c802dcccbf44ffcedd4eb29f512.png

         

15、剩下的就一直Next,遇到Accept就Accept ,最后Generate。

注意事项:上面过程有个注意事项就是有个内部参考电压的勾选,如果硬件设计没有预留外部参考电压,则需要勾选内部参考电压,否则DDR使用不了。

  • DDR测试方法介绍

测试内容时将DDR3L扩展为软核的内存,利用软核去调用,软核官方SDK提供代码,这样可以省去很大时间。整个DDR测试顶层文件如下所示:

https://i-blog.csdnimg.cn/blog_migrate/f663956b92751d384ff71aa15e12d39b.png

2. 修改clk_wizard,增加一个输出clk_out2,如图2

https://i-blog.csdnimg.cn/blog_migrate/23684f19cb274bf89e1f3bb09ca2c7da.png

3. 修改MIG,修改系统时钟为no buffer如图3,分配sys_rst为MIG的复位信号,如图4

https://i-blog.csdnimg.cn/blog_migrate/e27771e14e631ee8515b0fd50416a968.png

后续步骤参考MIG的配置部分添加MIG的管脚约束。打开SDK,下载程序进行验证

  • DDR初始化流程介

https://i-blog.csdnimg.cn/blog_migrate/5e53023438b5f9bce3ec40acffa2eac2.png

1.首先上电(RESET#推荐保持在 0.2XVDD;其他的输入没有定义)。RESET#信号需要用稳定电源保持最少200us。在图中可以看出来,CKE需要在RESET#拉高之前被拉低,且最少维持10ns。

2. 在RESET#被拉高之后,需要等待500us直到CKE被拉高。在这段时间内,DRAM会开始内部状态的初始化,这个过程是独立于外部时钟完成的。

3.在CKE拉高之前,时钟(CK,CK#)必须开始且稳定至少10ns或5个tCK。图中可以看到一个tIS时间,这个时间是CKE关于时钟的setup时间,因为CKE是一个同步信号。在CKE拉高之前且使用tIS设定自己的同时,NOP和Deselect命令也必须registed。在Reset之后当CKE拉高,CKE就必须持续拉高直到初始化过程结束。图中可以看到CKE持续拉高到tDLLK和tZQinit都截止的时候。

4.在Reset#拉低的时候,DDR3 SDRAM的ODT一直保持高阻态。除此之外,ODT还在RESET#拉高到CKE变高这段时间维持了高阻态。在tIS之前,ODT的输入信号可能在一个未定义的状态。在CKE拉高之后,ODT的输入信号不会变化,一直处于LOW或者HIGH的状态。若是在MR1中设置打开了RTT_NOM,ODT输入信号会处于LOW状态。总的来看,ODT输入信号会维持不动直到初始化过程结束,直到tDLLK和tZQinit截止。

5. 在CKE拉高之后,在发送第一个MRS命令到load mode register之前,需要等待tXPR,这个时间是RESET CKE的exit时间。(tXPR公式: tXPR=Max(tXS,5x tCK))

6. 发送MRS命令给MR2(BA0,2=0 and BA1=1)

7. 发送MRS命令给MR3(BA2=0 and BA0,1=1)

8. 发送MRS命令给MR1 且激活DLL(发送DLL enable命令,需要A0=0,BA0=1且BA1,2=0)

9.发送MRS命令给MR0且 RESET DLL(发送DLL RESET命令,需要A8=1,BA0,1,2=0)

10. 发送ZQCL命令开始ZQ校准过程。

11. 等待tDLLK和tZQinit完成。

12. DDR3 SDRAM可以开始进行一般操作了。

注意事项:这个时序图很关键,有助于判断各个阶段的时序,在初始话失败时,有助于定位判断出错在哪里。其中有个案例就是DDR初始化不良,通过查询时序,判断是FPGA内部MIG核失效。

以上就是对DDR各个知识及一些注意事项的汇总。

第二层皮-合肥 2020.4.20

以下是知识的原版参考地址:

DDR3内存的初始化过程

DDR3内存的初始化过程_达则兼济天下SEU的博客-CSDN博客_ddr3初始化完成信号一直为低

Xilinx MIG 控制器使用详解

Xilinx MIG 控制器使用详解(一)_为中国IC之崛起而读书的博客-CSDN博客_mig控制器

DDR原理详细介绍

转:DDR原理详解 - 鳄鱼泪 - 博客园

MicroBlaze测试DDR3

MicroBlaze测试DDR3_Frank~_~FPGA的博客-CSDN博客

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

第二层皮-合肥

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

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

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

打赏作者

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

抵扣说明:

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

余额充值