本人第一次接触FPGA的设计与开发,在老师的指导下完成EP3C25Q240的实验,耗时大概3个月,两个月从零开始做实验板,一个月调试板子上的SSRAM,虽然参考了altera的EP3C25F324开发板原理图,但是自己做这样一个板子还是碰到了许多许多问题。
调试程序过程更是让人经常抓狂,有些是由于自己初次制作经验不足导致的,有些也是由于百度上相关的资料不全甚至有些错误,本人不才一个月调试一块芯片,但是还是想要将自己的经历分享给刚刚学习FPGA的同学,如有错误,欢迎指正~~
还有,由于第一次CSDN,文章的格式什么的不太懂,欢迎大佬指点~~
这是我第一次接触FPGA,使用的是altera系列的,对应使用Quartus II 13.1,版本不新,但是由于采用cyclone III系列的,再搞一点版本的软件,竟然不支持了。中间用到了Modelsim,也用到了SignalTap。本来是想要用nios II的,因为里面好像有直接的IP核可以控制IS61LPS25636A-200TQLI,但是我不会用。最终还是使用逻辑状态机的方式控制了它,实验大致分两块,一块是单词读写操作,另一块是连续读写操作。在这里附上自己的实验板:
存储器的功能读和写是可以相互验证的,也就是说先写入数据,然后读出,如果读出的数据和写的数据一致,则可以验证读和写操作均正确。所以本次SSRAM的单次读写实验,采用LED灯反馈方式,验证单次读写的正确性。
由于是同步存储器,实验采用状态机的设计模型,复位结束,程序进入初始状态,如果当前按键1按下,那么程序进入单次读的状态;如果当前按键2按下,那么程序进入单次读的状态;否则状态不变。参见图 2:单次读写程序模型。
存储器的功能读和写是可以相互验证的,也就是说先写入数据,然后读出,如果读出的数据和写的数据一致,则可以验证读和写操作均正确。所以本次SSRAM的单次读写实验,采用LED灯反馈方式,验证单次读写的正确性。
由于是同步存储器,实验采用状态机的设计模型,复位结束,程序进入初始状态,如果当前按键1按下,那么程序进入单次读的状态;如果当前按键2按下,那么程序进入单次读的状态;否则状态不变。参见图 2:单次读写程序模型。
图2:单次读写程序模型
表格3:单次读写状态说明
状态 |
说明 |
S0 |
初始状态,复位状态,默认状态 |
S1 |
单次写状态,其中包含多个子状态 |
S2 |
单次读状态,其中包含多个子状态 |
S3 |
检测状态,用于检测读出的数据是否与之前写入的数据 |
采用先写数据,后读数据的方式验证,并通过LED等反馈。本程序采用在初始状态反馈的策略,采用红灯(LED_RED)和蓝灯(LED_BLUE)两个指示灯表示当前程序执行情况,表格 4:单次读写验证方式说明。
表格4:单次读写验证方式说明
程序执行位置 |
LED灯的状态 |
反馈状态说明 |
状态S3 |
红灭,蓝灭 |
读数据结束,但数据不一致 |
红灭,蓝亮 |
写程序结束状态 |
|
红亮,蓝灭 |
默认初始为此状态 |
|
红亮,蓝亮 |
读数据结束,并且数据一致 |
首先阅读SSRAM的datasheet,并将芯片框图和读写时序图插入本报告中,参见图 3:IS61LPS25636A框图,参见图 4:IS61LPS25636A写操作时序图,参见图 5:IS61LPS25636A读操作时序图。
图3:IS61LPS25636A框图
图4:IS61LPS25636A写操作时序图
图5:IS61LPS25636A读操作时序图
通过仔细观察和分析,并参考参见下图,可以得到如下的结论:
1. 信号和数据的读写是在时钟信号CLK的上升沿有效
2. ADSP 信号的作用是将地址锁存进内部的地址寄存器(ADDRESS REGISTER)
3. ADSC信号的作用和ADSP信号作用一致并且不受 信号控制。
4. ADV信号控制内部二进制计数器(BINARY COUNTER)的输出,并改变突发模式的地址变化方式。
5. BWE是写使能信号,GW和BWx用于控制数据的有效字节。
6. CE,CE2 和 CE2n是芯片的使能端控制内部使能寄存器(ENABLE REGISTER)的输出。
7. OE是输出使能信号。
8. Address和dataout/datain是地址和数据。
9. 单次写操作至少需要1个周期,单次读操作至少需要3个周期。
根据上面的结论和操作时序图,得到表格 5:单次写操作状态表和图 6:单次写操作时序图。(注意:实验版为简化设计,ADV,GW 始终无效,CE2n,CE2始终有效。)
表格5:单次写操作状态表
状态 信号 |
S1 |
S11 |
ADSP | H |
H |
ADSC | H |
L |
Address | 无效 |
有效 |
BWE | H |
L |
BWx | “1111” |
“0000” |
CE | H |
L |
OE | H |
H |
DATA |
无效 |
有效 |
说明 |
状态S1为准备状态,从写时序图中,存在单周期的写操作,为了简化实验,采用单时钟写操作,所有信号同时有效。 |
图6:单次写操作时序图
根据上面的结论和操作时序图,得到表格 6:单次读操作状态表和图 7:单次读操作时序图。(注意:实验版为简化设计,ADV,GW始终无效,CE2n,CE2始终有效。)
表格6:单次读操作状态表
状态 信号 |
S2 |
S21 |
S22 |
S23 |
ADSP |
H |
H |
H |
H |
ADSC |
H |
H |
H |
H |
Address |
无效 |
有效 |
无效 |
无效 |
BWE |
H |
H |
H |
H |
BWx |
“1111” |
“1111” |
“1111” |
“1111” |
CE |
H |
L |
H |
L |
OE |
H |
H |
H |
L |
DATA |
无效 |
无效 |
无效 |
有效 |
说明 |
状态S2为准备状态,单次读操作的第一个时钟用于写入地址,第二个时钟用于等待(我认为是为了提高数据的准确性),第三个时钟读数据。 |
图7:单次读操作时序图
根据表格 5:单次写操作状态表和表格 6:单次读操作状态表,并分析各个状态间转移的条件,得到图 8:单次读写实验状态机。
图8:单次读写实验状态机
根据设计的状态机,将各个状态说明(各个状态所做的工作)如下:
表格7:单次读操作状态说明
状态 |
状态说明 |
S1 |
写操作准备周期 |
S11 |
写地址和数据 |
S2 |
读操作准备周期 |
S21 |
写要读数据的地址 |
S22 |
等待数据有效 |
S23 |
读出数据 |
S3 |
判断数据是否正确 |
在顶层文件中,采用三段式的方法编写状态机,完整代码,参见附件。
在下载到实验板之前,进行逻辑上的仿真验证,并与时序图进行比较,如果一致,则进行下一步,否则检查程序编写的错误。我经过多次调试,最终得到正确的仿真结果图 9:单次写操作RTL Simulation。(其中蓝色的线为高阻状态,红色的线为未知状态)
图9:单次写操作RTL Simulation
其中黄色竖线开始向右两个周期为一次写操作,可以看到每个状态中各信号和数据与表格 5:单次写操作状态表设计的状态一致。可以看到黄色竖线左侧DATA信号有一段“XXXXXXXX”,这是因为编写程序的不当造成的,具体的分析将在实验结果及分析中阐述。
图10:单次读操作RTL Simulation
其中黄色竖线开始向右四个周期为一次读操作,可以看到每个状态中各信号和数据除了DATA以外,都与表格 6:单次读操作状态表中设计的一致。(其中蓝色的线为高阻状态)
通过JTAG接口下载到实验板,并按照先读,再写,后读的顺序进行验证。由于RAM的掉电不保留数据特性,未写先读,必然读到错误数据,然后再写,写入正确的数据后,如果读到正确的数据,说明实验成功;如果读到错误数据,则需要从头开始检查设计的正确性。因为如果第二次读到错误数据,并无法验证任何东西。
由于实验的结果很难通过上述方法呈现于报告中,本文采用验证连续读写正确性的方式,通过SignalTap II片上逻辑分析仪的方式展现。
图11:单次写操作结果图
从图 11:单次写操作结果图中的各个信号的变化情况看,和图 9:单次写操作RTLSimulation中的信号变化情况是一致的,标号为-521黑色竖线所在的上升沿应该是一个写数据周期的S11,此时DATA数据应该有效,但是和逻辑仿真中的情况一样,存在一个无效数据的周期。然后在第二个写数据周期的S11(-517)中DATA信号有效了。
图12:单次读操作结果图
从图 12:单次读操作结果图中,我们可以看到在第一个读周期的S23中(标号-517的黑色竖线位置)信号OE有效,并且在OE的上升沿将有效数据读出,并在下一个状态中比较读出的数据是否是之前写入的数据,并通过LED_RED和LED_BLUE显示(红亮,蓝亮,均是低电平有效),可见,读出的数据和写入的数据是一致的。
用VHDL语言设计程序,需要将程序想象成一个实际电路,在实验步骤“进行RTLSimulation”中,我发现存在一个周期中数据出错的情况,经过仔细分析,发现是编写程序的一个bug,程序段如下:
定位于在第132和133行,由于按照状态机的思想设计程序,IDE将其整合成一个同步系统,那么每一个状态,都是在时钟的上升沿同步进行的,也就是说,虽然这两行代码相当于一条代码“data<=X”12345678”;”,但是却需要两个时钟。所以以后在编写代码的时候,需要特别注意这种细节,否则这种错误可能带来潜在危险。
根据这样的思考,重新编写,将两条代码合成一条,重新仿真,得到正确的时序图,可以与图 9:单次写操作RTLSimulation进行比较,发现那段不和谐的数据消失了。
图13:修改后单次写操作RTL Simulation
在实验一也说明了,存储器的读和写是需要相互验证,也就是说先写入数据,然后读出,如果读出的数据和写的数据一致,则可以验证读和写操作均正确,反之,有可能写操作错误或者读操作错误或者两者都错。所以本次SSRAM的连续读写实验,采用采用片上逻辑分析仪的方式验证连续读写操作的正确性。
与实验一相似,实验二也采用有限状态机的设计思想。定义一个Times(类型为signal,integer),用来标志需要连续读写的次数。在初始状态S0,将0赋给Times。按下按键1,进入连续写状态S1,每写一个数据 ,当Times==T时,返回至S0。按下按键2,进入连续读状态S2,每读一个数据 ,当Times==T时,返回至S0。
图14:连续读写程序模型
为了验证连续读写的正确性,实验一中的方法似乎有些不够理想,因为需要确定每一个数据的正确性,也要确定数据和地址的一致性。这时ALTERA公司为我们开发人员设计了一个工具SignalTap片上逻辑分析仪,只要资源足够,便能显示芯片内部信号的数据,这极大地提高了开发效率。
为了验证连续读写的正确性,我在SignalTap中定义按键1按下的边沿和按键2按下的边沿触发器,来触发SignalTap传回实时数据。这样便能直观的看到写入或者读出的数据以及相应的地址,并且能够分析当前数据的读写速度。
参考实验一的分析方法,写操作时序不变,只是将单次写操作拼接成连续写操作,而读操作则需要进行修改。
但是实验板在设计的时候默认不适用突发模式,所以只能通过连续的单次读操作模拟连续读写,但是简单的将单次读操作拼接却无法完成连续读的任务,参考网上资料引用,需要在单次读的等待周期将下一个地址写入,则能够实现连续读操作,设计连续读操作状态表,表格 8:连续读操作状态表。
表格8:连续读操作状态表
状态 信号 |
S2 |
S21 |
S22 |
S23 |
S24 |
ADSP | H |
H |
H |
H |
H |
ADSC |
H |
H |
L |
L |
H |
Address | 无效 |
有效 |
无效 |
有效(更新) |
无效 |
BWE | H |
H |
H |
H |
H |
BWx | “1111” |
“1111” |
“1111” |
“1111” |
“1111” |
CE | H |
L |
L |
L |
L |
OE | H |
H |
H |
H |
L |
DATA |
无效 |
无效 |
无效 |
无效 |
有效 |
说明 |
状态S2为准备状态(编写代码过程中省略),连续读操作的第一个时钟提前给出地址,第二个时钟写入地址,第三个时钟更新地址,第四个时钟读出数据。 |
并根据上面的状态表画出相应的时序图。
图15:连续读操作时序图
在Quartus II软件的tool菜单下找到SignalTap选项,进入界面后,选择对应的采样时钟(至少需要工作频率的两倍),选择需要查看的信号,并设置触发条件,设置结果参见下图。
图16:SignalTap配置图
设置完成后,测试通信是否正常,正常后下载并调试。
经过去抖处理的按键信号u1:keyout的下降沿是系统进行连续写的信号,该信号后每2个cklsram周期写入一个数据,为了简化编程采用公式 进行测试,可以从图 17:连续写操作结果图中标号为+189的黑色竖线为状态S11(写入数据)。
图17:连续写操作结果图
连续写操作完成后,另一个按键信号u2:keyout的下降沿是系统进行连续写的信号,该信号后每5个cklsram周期读出一个数据,可以看到读出的数据和地址满足 写入的公式,可见所读到的数据正是刚才写入的数据,这验证了连续写读操作均是正确的!
图18:连续读操作结果图
根据上面的实验结果,我们可以看到,在采用非突发读写的前提下,写数据至少需要2个时钟周期,而读操作至少需要5个时钟周期。
经过对不同输出时钟周期的测试:
# 情况一,输出给SSRAM的时钟信号在150MHz,SignalTap采样频率300Mhz的情况下,连续读写的数据是正确的。
# 情况二,输出给SSRAM的时钟信号在200MHz,SignalTap采样频率400Mhz的情况下,连续读写的数据是错误的。
参考CycloneIII系列的数据手册,实验板上的芯片速度等级C8的最高工作频率为402MHz(表格 1:EP3C25Q240C8参数),参考IS61LPS25636A芯片手册,最高输入时钟为200MHz(表格 2:IS61LPS25636A引脚说明),所以在理想情况下,“情况二”应该是能够正常工作的。但是由于实验板设计技术不到位,无法使两者同时达到最高频率工作。
计算最快连续读写数据的速度,则需要最高的时钟频率,最大的数据位宽以及最少的操作周期,上述连续读写实验的状态都是最少操作周期的情况。
通过分析,我们可以通过以下公式计算读写数据的最高速度:
其中:
l Vmax为读写数据的最高速度,单位为:M·bit/s。
2 Lmaxdata为1次读写的最大数据宽度,单位为:bit/次
3 Fmax为安全工作的最高时钟频率,单位为:MHz
4 Cmin为正确进行1次读/写操作的最小周期数,单位为:周期/次
将“情况一”带入上述公式,可以算得最高写数据速度约为300MB/s,最高读数据速度约为120MB/s。
经过此次实验,我深刻学习并体会了一颗芯片的调试工作过程,掌握了Quartus软件,Modelsim软件以及SignalTap的基本操作。
实验过程中也明白了硬件语言编写的程序和其他高级语言编写程序的不同,最大的不同就在于硬件语言编写的是一个实际的电路,而不是面向过程或者对象的一种编程模式。实际电路的最大特点是实时性以及并发性,在设计硬件语言程序时最好能够将程序转换为电路,比如C语言中的for循环,如果想要在硬件语言程序中实现的话,可能需要转化为一个同步计数器和一个比较器等。
对于硬件开发,需要熟读并理解开发芯片的特性。比如本实验的SSRAM芯片的 信号和 信号,这两个信号在手册中的BLOCK DIAGRAM部分中可以非常清楚的看到两个信号的作用几乎是一模一样的,这样在设计电路的时候便可以有依据的化简设计,也能更加清楚设计的原理。
如果是自己焊接的实验板,那么在实验过程中需要时刻保持警惕,不能因为焊接的短路断路毁坏实验板,在认为程序设计没有问题但是实验现象与预期的不相符合的时候,可以考虑一下实验板的焊接问题。
实验遇到瓶颈的时候,可以查阅资料,无论是请教学校的老师,或者网上前辈的开发经验,或者图书馆中相关资料的书籍,或许就是那么一句话,便可以让你恍然大悟。
在实验过程中,发现FPGA和SSRAM芯片均有不同程度的发热现象。尤其在工作频率较高(FPGA,300MHz;SSRAM,150MHz)的时候,即使在工作时间较短的情况下也能接近体表温度。
在学习全新的器件时,需要首先掌握器件各个引脚的功能,不仅仅是看明白数据手册上的引脚说明,还有系统框图,内部寄存器的含义,时序等等,需要清楚地理解器件的工作原理以及工作过程,这能够很大程度的减少开发成本。
本来这是我在word上写好了的,粘贴过来格式变量很多,手动调整……
最后声明一下,未经本人许可,不可转载。