分享

【转】NiosII中SDRAM相移计算

 tmmdh_zz 2015-07-23

SDRAM和Nios II连接的典型电路框图如下图所示。SDRAM和System使用同一个PLL输出时钟,可以保证System Clock和SDRAM Clock的相对抖动比较小。外部晶振的时钟送入PLL,然后由PLL产生两个同频的时钟一个供给Nios II系统使用,另一个供给SDRAM使用。(把PLL设置成Zero Buffer Mode可以比较方便地控制SDRAM Clock和输入时钟Extern Clock的相位关系。)Nios II系统中的SDRAM控制器和SDRAM通过双向数据线以及其它的单向控制线和SDRAM相连。

 

SDRAM Clock通常是E0输出或者C2输出,E0和C2都是PLL专用于输出外部时钟的,有比较小的抖动。由于一个FPGA中通常有若干个PLL,综合后使用哪个PLL是由输入时钟Extern Clock决定的,所以SDRAM Clock必须和Extern Clock是同一个PLL的专用输入管腿和专用输出管腿。调试SDRAM和Nios II 的最关键是调整SDRAM Clock的相位。下面推导SDRAM Clock和Extern Clock的相位关系。

 

用实线向上箭头表示Extern Clock的上升沿,用虚线向上箭头表示Sdram Clock的上升沿。先看第一种情况:FPGA输出数据,而SDRAM采样数据。FPGA在Extern Clock上升沿的时候送出数据,经过最大Tcoutmax(FPGA)的时间在FPGA的管腿输出,由于SDRAM的输入建立时间为Tsu(SDRAM),所以Sdram Clock的采样时机必须在信号到达SDRAM后再等Tsu(SDRAM)。忽略PCB板传输延时,有:

Tlead=T-(Tcoutmax(FPGA)+ Tsu(SDRAM));其中Tlead 为SDRAM Clock相对Extern Clock的最大提前量,T为时钟周期。

在下一个时钟上升沿来了后,FPGA会驱动新的信号,在经过最小Tcoutmin(FPGA)的时间(相当于输出保持时间)可能把先前驱动的信号冲掉,而SDRAM要求输入信号要求在采样的时候保持Tih(SDRAM)的时间,所以SDRAM的采样时机必须在Tcoutmin(FPGA)到来之前Tih(SDRAM)。忽略PCB板传输延时,有:

Tlag=Tcoutmin(FPGA)-Tih(SDRAM);其中Tlag 为SDRAM Clock相对Extern Clock的最大落后量,Tih(SDRAM)为SDRAM输入保持时间。

第二种情况:SDRAM输出数据,FPGA采样数据。分析和上面类似,最后有:

Tlead=Tcoutmin(SDRAM)-Tih(FPGA);

Tlag= T-(Tcoutmax(SDRAM)+ Tsu(FPGA));

选取最小的Tlead和最小的TlagSDRAM Clock的允许最大提前量和最大的落后量。举个例子:Nios II 和 SDRAM(MT48LC4M32B2-7)相连主频100MHz。其数据如下:

-        Data In: Tsu = 2 ns, Tih = 1 ns

-        Data Out: Toh (Tcoutmin )= 2.5 ns, Thz/tac (Tcoutmax)= 5.5 ns (CL=3)

l       2.5 – 5.5 ns (Data Undefined)

FGPA的数据可以在编译报告的时序分析部分得到,Tcoutmax(FPGA) ,Tsu(FPGA),Tih(FPGA)分别可以从Tco,Tsu,Th部分得到各个SDRAM相关信号的最大值。而Tcoutmin(FPGA)则可以运行Fast timing model timing analyzer 来得到。

比如:

-        Data In: Tsu = 1.75 ns, Tih = 0 ns

-        Data Out: Tcoutmin(FPGA) = 2 ns, Tcoutmax(FPGA)=5.5 ns

Tlead=T-(Tcoutmax(FPGA)+ Tsu(SDRAM))=10ns-5.5ns-2ns=2.5ns

Tlead=Tcoutmin(SDRAM)-Tih(FPGA)=2.5ns-0ns=2.5ns

选一个小的,仍然是2.5ns。即Tlead=2.5ns

Tlag=Tcoutmin(FPGA)-Tih(SDRAM)=2ns-1ns=1ns

Tlag= T-(Tcoutmax(SDRAM)+ Tsu(FPGA))=10-5.5ns-1.75ns=2.75ns

选一个小的,即Tlag=1ns。

所以SDRAM Clock的相对External Clock相位为-2.5ns~+1ns之间。在生成PLL时指定在这个范围内的相位偏移就可以了。

注意:因为FPGA的时序分析报告都是以External Clock来算的,所以我们并没有使用System Clock来分析。


搭建好了这个SOPC之后就可以用NIOS来实现我们想要的功能了。下面转入正题,用NIOS内部的SDRAM控制器,在SOPC里添加了这个项目之后,我们就可以狠方便的实现SDRAM的驱动了。因为控制器已经为你引出了SDRAM需要的连线,我们所作的工作只是需要把这些线连起来就可以了,下面简单的介绍一下这些引脚的功能。 CLK--时钟输入 CKE--内部刷新时钟控制端 CS--片选 BA1,0--BANK的选择 A0--A11--地址线,包括行地址与列地址 RAS--行地址选通 CAS--列地址选通 WE--写使能 LDQM,UDQM--字节与字控制端 DQ0--DQ15--数据端 看了这些控制线,大家应该感到狠痛苦了,确实SDRAM的控制确实狠复杂。但是NIOS里的控制器帮我们解决了这些问题,当我们正确的连好了这些线之后,我们就不需要去管它了,NIOS会帮我们处理好这些时序,也就是说我们要作的工作是:1 在SOPC里设计一个根我们用的SDRAM时序一样的控制器,这需要参考SDRAM的资料。2 正确地连接好NIOS与外部SDRAM的连线。3 也是最麻烦的一点,CLK的时序问题。下面着重介绍一下CLK的时序设置。 我们先看一下原理,FPGA里的NIOS2需要一个时钟,SDRAM需要一个时钟,那这两个时钟之间是什么关系呢?答案是很复杂。首先来讲这两个时钟都是PLL的输出,PLL里根据不同的FPGA有不同的选项。

一般来讲,PLL的输出有C1,C0,E1,E0........,C就是说PLL经过内部的复杂逻辑的输出,所以它根原始的时钟输入之间是相位差的,E就是说直接时钟输出,它的相位差几乎位0,但是它需要特定的引脚。我们在设计的时候最好用E端作SDRAM的时钟输入,具体的原因看后面的解释。

这段解析比较勉强,可以说是错误的,其实E0这个信号是Altera用来对外输出的,并非E0就没有经过复杂的运算。在CycloneIII中,好像没有区分内部和外部,估计所以信号都可以对外输出。

 SDRAM的特殊性决定了它的驱动的复杂性,想要完全明白它的所有时序的意义需要很长的时间积累,但是应用的话不需要那么多,所以下面简单介绍一下最关键的几个。 1、                         --输入建立时间,SDRAM里的参数

 2、  --输出保持时间,SDRAM里的参数

 3、 --FPGA从引脚输入到内部逻辑的建立时间

4、 ---FPGA内部逻辑到输出的建立时间

 这是我们计算SDRAM的CLK所需要的几个最关键的参数, 意义是说当NIOS的地址线和数据线到达SDRAM时,需要保持这么长的时间,  是说SDRAM在读取的时候,需要这么长的时间才能把输出值输出到总线上,设CLK为时钟信号,CLK1为SDRAM的时钟,CLK2为FPGA外部引脚的时钟,可以看出来,CLK2-CLK= ,关于CLK2与CLK1我们可以仿真得到他们之间的相差,所以我们要做到的是:

1、   CLK2-CLK1=  

2、   CLK1-CLK2=( + ) (以上的计算是相差的计算)

相差是正的话说明被减数在减数之后。所以通过上边的公式可以确定CLK1的范围,所以在PLL里设置一下就可以让我们的SDRAM满足系统的要求了。关于为什么要用E0来作SDRAM的时钟的问题,首先我们每次编译的结果的时序都不一样,虽然变化部大,但在高频的时候部可忽视,而E0的相位与编译无关,其次,它的抖动比C端要小。现在我的系统跑在75M上,还可以,但感觉这种方法在高频中会有潜在的问题,以后我会进行相应的测试,然后告诉大家结果。 上边算是对SDRAM的一个小结。 下面对FLASH作一下解释,跟SDRAM一样,FLASH只需要连好相应线就可以。但在实际的应用中有一个小问题,就是说假如FLASH的总线是22位的,既21..0,NIOS会给你22..0,所以我们在连接的时候需要错一位,也就是说NIOS的1接FLASH的0,依次类推下去。但有的时候我们需要SDRAM和FLASH公用总线,这就存在一个问题,FLASH需要从1开始接,而SDRAM是从0开始,所以设计公用总线的时候,原理图上SDRAM的A1要接FLASH的A0,这点一定要注意,但发现ALTERA不推荐这么去设计,因为SDRAM需要自己的一套时序,共用的话会大大降低SDRAM的性能,在实际中也发现了这点,所以在资源部紧张的情况下还是部要复用。还有NIOS对AMD的FLASH支持的很好,其他的象SST的FLASH ,对以前的200,400,800系列支持的好,但之后的160,320,640就支持部好了,所以用NIOS的时候最好用AMD的FLASH.
       SDRAM使用注意事项:

 1. 首先要在sopc里加入sdram控制器,根据器件手册设置好数据宽度,行列地址宽度等;

 2. 加入PLL移相。因为SDRAM为动态的存储器,对时序要求比较高.因为有延迟,所以加入PLL来调整相位,一般的经典值为-63deg,要是不行,可以每5度增加或者减少;用cylone器件时最好用e0输出SDRAM的时钟,同时用专用的时钟输出引脚输出;cycloneⅡ用c2;

 3. 数据线设置成双向,同时因为管脚比较多,务必要保证管脚锁定正确;

#include "system.h"
#include "altera_avalon_pio_regs.h"
#include "alt_types.h"
int main (void) __attribute__ ((weak, alias ("alt_main")));
int alt_main (void)
{unsigned char sdrw_d[60],sdrr_d[60],i;
  for(i=0;i<50;i++)
    {
      sdrw_d = 0x0;
    }
    for(i=0;i<50;i++)
    {
      sdrw_d = i;
      IOWR(SDRAM_BASE, i, sdrw_d);
    }
    for(i=0;i<50;i++)
    {
      sdrr_d = 0x0;
    }
    for(i=0;i<50;i++)
    {
      sdrr_d = IORD(SDRAM_BASE, i);
      if(sdrr_d != sdrw_d)
        while(1){IOWR_ALTERA_AVALON_PIO_DATA(LED_PIO_BASE, 0xff);};
    }
}

在sopc里加入SDRAM控制器,命名为SDRAM,让程序在片上RAM执行,
本例中,当读写的数据不一致时,输出信号来点亮LED,也可以根据实际情况另做判断。比如在循环那里加断点,总之,是要判断程序是否进入死循环,从而判断读写数据是否一致。

 

 

 

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多