基于SPARTAN6的DDR2的IP核的研究(转)
Xilinx公司发布的SP6,V6系列的FPGA中的DDR2的IP核是一大改变。它由原来的软核变为了硬核,此举让开发DDR2变的简单,因为不需要太多的时序调试,当然也带来了麻烦,这是因为当DDR2出现问题时,不知道从哪里下手找原因。而这篇文章的目的就是简单的探讨DDR2的使用,以及DDR2使用中会遇到的问题。其中这篇文章包含以下几个方面
1 : 如何生成IP
2 : 使用IP的注意事项。
3 : 关于DDR2中内部FIFO的处理
4 : 一个BANK如何连接2个DDR2。
以下会对下面进行介绍
一 : 如何生成IP
生成DDR2很简单,就是按照mig生成的顺序一路next下去,需要注意2点
1) : 选择fifo的位宽和大小,因为一般的DDR2是突发为4,所以针对8位的DDR2,每次操作需要32位宽,16位的是64位宽。
2) : 选择软件校准的模式,如果在BANK中有接地的引脚,那么可以采用这个引脚(Calibrate Input Termination)为校准端,如果没有,可以选择(un-calibrated input Termination 或者 External Input Termination) ,这两者差别在于在DQ/DQS的引脚上会上下拉电阻,还是不上下拉电阻。选择任何一个都不会影响使用
3) : 关于DDR2的时钟,因为FIFO是分开的,所以可以选择所有的时钟共用一个CLK,也可以分开选择。,可以根据
C1_CLKOUT0_DIVIDE
C1_CLKOUT1_DIVIDE
C1_CLKOUT2_DIVIDE
C1_CLKOUT3_DIVIDE
C1_CLKFBOUT_MULT
C1_DIVCLK_DIVIDE
几个变量来设置DDR2的clk时钟,一般来讲,生成的IP核中默认的时钟c5_clk0是DDR2的理论时钟的1/2,所以我们缩小DIVIDE来提高c5_clk0的速率。同时我们也可以重新定义一个时钟CLKOUT4来使用
二 :使用IP的注意事项: 在生成的IP中,我们可以添加到工程中,下图是添加到工程中的截图
1.png
红色的缺失文件不影响我们的使用,因此 不需要担心
在使用IP的时候,最好注意以下事项:
1) : 地址,在生成的UG388文档中如下表所示
2.png
这个图表示控制的地址使用如果我们选择了256MB*8,那么根据这个表格,我们得知生成的IP核中的30位地址addr[29:0]中的[29:26]位是没有用处的,只会用到addr[29:的[25:0]位, 同时因为突发为4,所以每进行一次突发操作后,地址的变化为 Addr = {4’b0000 ,addr_op } addr_op = addr_op +- 4(mask == 0)记住如果突发为4,那么地址的变化为4,如果是8,那么地址的变化就是8。
2) : 关于刷新的操作,在ip中,有刷新,读刷新,写刷新,还有引脚控制刷新selfrefresh_enter,这几个的不同之处在于刷新操作是每个7.6us,就进行打开bank,并且刷新一次,而读写刷新是每次操作读写之前都要打开, 刷新一次,而手动刷新时启动信号的时候刷新,这三者的不同之处在于,每次读写刷新会浪费几个时钟周期,手动刷新引脚是设置刷新而刷新,其中推荐采用手动刷新,可以在空闲的时候刷新DDR2, 就可以避免操作的时候因为打开刷新而浪费的几个时钟周期。
三 : 关于DDR2中内部FIFO的处理 因为DDR2硬核的结构是 FIFO-DDR2操作,所以与应用层联系最紧密的应该就是FIFO接口的处理,在这方面我吃了其中的一个大亏,提起它还是心有余悸!!! DDR2生成的FIFO端口可以是双向,也可以是单向,如果生成了双向端口,那么fifo端会提供WR_EN 与RD_EN, WR_EMPTY,RD_EMPTY,在这里说一下切忌不要把DDR2内部的双向端口当成FPGA中的FIFO端口,如果当成,那肯定就被害惨了,以下图为证:
3.png
发现rd_count与wr_count 不会保持一致,而且rd_empty 和 wr_emptyu 也没有保持一致,并且如果设置rd_en时能信号,发现完全没有效果。。。。。。。。
图片4.png
上图是设置rd_en后,发现wr_count完全没有变化,从上面操作可以发现实际上的双向端口就是2个FIFO的合并,一个双向端口的FIFO相当于两个FIFO,每个的操作都是独立的。。。。。。。(大亏啊,当时当成内部FIFO处理了,xilinx太不厚道了啊)。
所以推荐以下两种方法进行处理FIFO
1 :复位,这是最简单的方法,这个复位复位了整体的DDR2,为了方便起见,可以单纯的复位DDR2的硬核,而DDR2中的PLL逻辑可以不用复位。
2 : 读空,写空逻辑,当WR_COUNT中的个数不为0的时候,要进行写入DDR2操作,当RD_count中的个数不为0的时候,要进行读空操作。建议采用2号操作,因为2号操作需要的延迟更小,而复位机制需要的时间要大于2号操作需要的时间。
四 : 一个BANK如何连接2个DDR2 本身spartan6是不支持一个BANK连接两个DDR2的,这是因为DDR2是硬核,延迟都是固定的,为了帮助那些不小心把SP6当成V5系列的误把一个BANK连接2个或者多个DDR2的朋友们,同时在12.9月份的时候,我也遇到过这个问题,当时在21IC的论坛上发了好多帖子来探讨这个问题,幸亏大家的帮助,终于把这个问题解决,所以决定把这一面也简述一下。 在V5系列的DDR2的IP为软核,可以自由自在的调节延迟等信息,所以V5的一个bank理论上可以支持多个DDR2,并且也实现了连接多个的设置与调试,而在SP6中一个BANK连接了一个DDR2,连接是相对应的引脚相连接,这个比较容易实现。而SP6中连接两个或者多个DDR2,一般连接方法是除了相对应的时钟分开外,地址,数据线是共用的,这就导致了时钟线与地址/数据线不匹配的问题。 上面出现的这个问题可能会导致其中的一个DDR2工作不正常,或者两个DDR2都工作不正常,但是不影响calibdone信号,在calibdone信号拉高后,我们可以放心的调试FPGA了,调试FPGA的关键在于时钟的处理,如何处理好时钟的延迟。[/p][p=30, 2, left]下图是FPGA中的DDR2的IP引脚的结构图。
5l.png
此时我们需要做的工作就是来调节这个时间,根据spartan6的结构我们知道IO的结构包含了IODELAY 还有 ILOGIC/OLOGIC因此我们可以在CLK端添加IODELAY模块信息,其中IODELAY的引脚说明不再文档中介绍了,有不理解IODELAY的可以问猴哥啊。修改FPGA程序,添加了IODELAY后的planhead结构图为
6.png
此时根据IOdelay的特性,我们便可以设置IO的延迟参数当然这个的延迟最重要的还是硬件PCB的设计,我们可以先进行SI仿真后,得到DDR2的延迟走线参数,根据这个参数我们来调节时间差。经过很长时间的验证,发现IOdelay不会随温度有太剧烈的变化,调节好了正确的参数后,放心大胆的用一个BANK连接多个DDR2把。当然不推荐使用,因为调试需要的时间很长,当时浪费了很长时间才调试成功。(恼火啊)
以上就是我做DDR2的心得体会。FPGA眼中的DDR2,当然和硬件人员眼中的DDR2的看法也许不太一致,比如对于ODT这些,希望有人能够讲解一下,希望同大家共同交流进步。
关键词:
DDR2
SPARTAN6