最近一个星期,用EP1C3T144C8这个FPGA嵌入NIOS2,研究了一下FLASH和SDRAM的驱动,最后终于是好用了,但中间遇到了不少曲折,现在就把我的一些经验分享给大家,希望大家以后在这方面不要走弯路。
首先,先提一个名词--SOPC.任何一本关于FPGA嵌入式的书籍都会有的一个名词,翻译过来是“片上可编程系统”。也就是说我们在用FPGA作嵌入式的时候其实相当于自己根据自己的需要作一个处理器,这个处理器的内核就是NIOS2处理器,而外围可以根据自己的需要添加我们需要的任何外设,包括定时器,UART,IO,SPI接口等等。这些都是我们在用单片机和ARM时经常接触和使用的东西,所以以前用单片机和ARM的时候在使用SOPC的时候会觉得非常的熟悉。它的灵活性在于可以根据我们的需要任意搭配一个最节省的CPU,而且使用AVALON总线连接你的外设,不需要自己去搭建结构,但缺点在于它是一种软核,是用语言实现的一种硬件算法,所以比较占资源。具体的细节大家可以上网上去搜索。
搭建好了这个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的时钟输入,具体的原因看后面的解释。
SDRAM的特殊性决定了它的驱动的复杂性,想要完全明白它的所有时序的意义需要很长的时间积累,但是应用的话不需要那么多,所以下面简单介绍一下最关键的几个。
1 tsu--输入建立时间,SDRAM里的参数
2 ton--输出保持时间,SDRAM里的参数
3 tinsu--FPGA从引脚输入到内部逻辑的建立时间
4 toutco--FPGA内部逻辑到输出的建立时间
这是我们计算SDRAM的CLK所需要的几个最关键的参数,tsu意义是说当NIOS的地址线和数据线到达SDRAM时,需要保持这么长的时间,toh是说SDRAM在读取的时候,需要这么长的时间才能把输出值输出到总线上,设CLK为时钟信号,CLK1为SDRAM的时钟,CLK2为FPGA外部引脚的时钟,可以看出来,CLK2-CLK=toutco,关于CLK2与CLK1我们可以仿真得到他们之间的相差,所以我们要做到的是,1 CLK2-CLK1=tsu 2 CLK1-CLK2=(tinsu+ton) (以上的计算是相差的计算),相差是正的话说明被减数在减数之后。 所以通过上边的公式可以确定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开始接,而ADRAM是从0开始,所以设计公用总线的时候,原理图上SDRAM的A1要接FLASH的A0,这点一定要注意,但发现ALTERA部推荐这么去设计,因为SDRAM需要自己的一套时序,共用的话会大大降低SDRAM的性能,在实际中也发现了这点,所以在资源部紧张的情况下还是部要复用。还有NIOS对AMD的FLASH支持的很好,其他的象SST的FLASH ,对以前的200,400,800系列支持的好,但之后的160,320,640就支持部好了,所以用NIOS的时候最好用AMD的FLASH.