• 【转】NiosII中SDRAM相移计算


     

    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,也可以根据实际情况另做判断。比如在循环那里加断点,总之,是要判断程序是否进入死循环,从而判断读写数据是否一致。

     
  • 相关阅读:
    「CF722E Research Rover」
    「Luogu P4062 [Code+#1]Yazid 的新生舞会」
    【cf比赛记录】Codeforces Round #613 (Div. 2)
    【cf比赛记录】Educational Codeforces Round 78 (Rated for Div. 2)
    【cf补题记录】Codeforces Round #608 (Div. 2)
    【cf补题记录】Codeforces Round #607 (Div. 2)
    【cf比赛记录】Codeforces Round #606 (Div. 2, based on Technocup 2020 Elimination Round 4)
    【cf比赛记录】Codeforces Round #605 (Div. 3)
    【Codeforces】B. Div Times Mod
    【牛客练习赛53】A-超越学姐爱字符串
  • 原文地址:https://www.cnblogs.com/woshitianma/p/2957469.html
Copyright © 2020-2023  润新知