sram之timequest
0赞以前写verilog代码的时候,基本没有添加过约束,从现在开始,要好好的学习约束,因为是使用的是quartus,而quartus的时序分析和约束工具是timequest。
先要计划下要进行哪些约束
1、 时钟约束:这个系统是在50M时钟作用下,所以需要对这个时钟进行约束。
2、 输入延迟约束:有sram_data输入,所以需要对这个输入进行输入延迟约束
3、 输出延时约束:有sram的控制信号及地址信号,所以需要对这些输出进行输出延时约束
然后就准备开始了,首先得确定这些约束要约束多少,然后在用工具进行约束。
首先是时钟约束:
因为时钟就只有一个,50M时钟,所以这个约束就很简单,就约束个周期就可以了。
然后是输入延迟:
这个就比较麻烦了,这个我也是参考现在FPGA大名鼎鼎的特权大神的写的博客,sram时序约束分析才了解的。
画个简单的图,这里就直接引用特权大神博客中的图,只是加点东西。
这里说明下上述几个参数的意义:
Tco: 寄存器的延时输出,即时钟有效到输出有效的时间。
Treg2pin: 寄存器输出到pin1的延时。
Tpcb1: 从FPGA输出pin1到sram输入pin2间的pcb延时。
Tsram_delay: 从信号发到sram的输入pin2,到sram的输出pin3上数据有效的延时。
Tpcb2: 从sram输出pin3到FPGA输入pin4间的pcb延时。
Tpin2reg: 从FPGA输入pin4到寄存器的输入间的延时。
这个时候可以把sram看成是一个大的组合逻辑,这样路径就可以看成是FPGA内部reg1到reg2间寄存器到寄存器路径。
这里这些延时要查看手册。
根据手册,知道Tsram_delay为10ns。
Tpcb1和Tpcb2这个要根据pcb的路径长度来进行估算,但是由于不知道这路径有多长,所以这里就假设两个的延时都是0.5ns-1ns。
Tco这个可以看FPGA的datasheet知道,也可以通过timequest中看到。我之前看的是0.232ns。
Treg2pin: 这个是要布局布线后才知道的,但是这里我们是可以对他进行约束的,假设这个约束是1-2ns。
有了这些参数,就可以计算输入延迟了,即input delay。
Input max delay = Tco + Treg2pin(max)+ Tpcb1(max)+ Tsram_delay + Tpcb2(max)
=0.232 + 2 + 1 + 10 + 1
=14.232
Input min delay = Tco + Treg2pin(min)+ Tpcb1(min)+ Tsram_delay + Tpcb2(min)
= 0.232 + 0 + 0.5 + 10 + 0.5
=11.232
以上计算,没有考虑到时钟的偏移等情况,假设时钟造成影响是1ns。
那么现在的
Input max delay = 15.232
Input min delay = 11.232
这样,就确定输入延迟了。。
最后在确定输出延时:
输出延时主要就是约束Treg2pin这个时间了。这个时间不能太大,否则输出信号不能按时的传递到sram的输入管脚,就会造成控制sram时序不满足,就会出现读写错误情况。因为这里我们使用的是状态机来驱动,时序余量比较大,为一个周期,所以这里都假设所有的输出延时最大为10ns,最小是1ns。
这里要注意一下,为什么要设置下最小延迟,因为这个延迟是用来满足建立时间的,即信号不能传递得太快。因为这里时序余量太大,所以就没有去计算了,直接假设一个值。
有了上面这些参数,就可以进行时序约束了。
在quartus中时序约束,首先需要对工程进行全编译。因为时序约束是需要网表的。
全编译后,点击小闹钟的符号,进入到timequest。
首先是创建时序网表。
然后就可以添加约束了,添加约束都是在菜单constraints里面。
首先是创建时钟约束:
填入时钟的名字,这里的时钟名字可以随便取,然后设定周期。最后选择关联的时钟,选择系统时钟clk。最后run就行了。
然后添加input max delay
选择参考时钟,这里的参考时钟就是系统时钟,不过之前对系统时钟取了个别名clk_50M,这里这里选择这个。
然后选项选择最大。下面勾选add delay,填入刚刚计算的15.232.最后关联管脚,就是sram_data的16个管脚。最后run。
然后设定input min delay
和设置input max delay一样,只是延迟值不一样而已。
这样,就设置好了input delay了。
然后设置output delay。
选择参考时钟clk_50M,选项选择最大,勾选add delay ,填入2.选择关联输出,sram的控制信号及地址信号。然后run。
同理设置最小。
这样就设置好了output delay了。。
会发现,有些output 我们是没有约束output delay的。比如用到的25个led输出,我们就没有输出,因为led输出时序并不那么重要,因为我们的时钟比较慢,led完全反应的过来,这里就直接没有约束了。如果时钟高了话,就要设置了。
这样,就完成了整个的时序约束了。。
这个别忘记,我们刚刚虽然约束了,但是这约束并没有加入到设计。首先,我们需要保存约束。
这样,就生成了约束文件sram.sdc。
打开看看,里面就是我们刚刚添加的约束,只不过这约束是用脚本来写的。如果熟悉约束的脚本,可以直接用脚本编写,而不用刚刚之前用的图形化约束。
然后把约束文件加入到设计中,在重新编译。
最后别忘记点击下面的OK,这样约束才添加进设计了。
需要添加文件到设计中,都使用上述方式。
然后全编译。
经过漫长的编译,编译完了,然后在打开timequest查看时序。
打开报告。
发现没有红色的东西,说明时序是通过的。。然后我们去查看一下。
直接看第一条余量最小的那一个。
就弹出下面的框了。这个时候就可以分析路径了。
这里面列举了这条时序最差的路径上的所有延时。。
这里,强烈建立大家看看这个波形图,这个波形图形象的说明了,时序分析是怎么分析的。结合波形和左边的详细延时,可以更加的理解时序。
我们locate technology map viewer看一看。
就列出了这条路径上的逻辑电路。
放大看看。
可以看到,时序起点是从寄存器出发的,结点也是寄存器。
可以看到每个器件上有两个数字。这两个数字代表什么意思了。据我目前研究来看,第一个数字是值是连线延迟,第二个模块延时。
连线延迟就只信号通过延时到达模块的时间,模块延时指信号通过这个模块需要的时间。
还可以去看看组合逻辑模块底层有些什么东西。不过我认为看了也没有什么用,毕竟整个设计是很复杂的,我们不可能在像以前学数字电路那样,去化简电路,或者是列出真值表看看功能是什么。都直接通过仿真观察,功能是不是我们设计的那样。
从这个表就可以看出来了。
然后我们在定位到芯片底层中去看看。
这个时候,就体现工具的强大了,可以直接看底层的连线和模块,以及对应的延时。
对你要查看的路径双击,软件会自动定位到该路径上。
如图,定位的是连线,图上一条高亮的有方向的线就是连线,表上也显示了该延时是1.614ns。
依次可以看到所有路径。。
对一个模块放大看看。
左边的一个白色方框就是一个LE(应该是吧),右边第一个框是这个LE的内部结构,
白色方框中蓝色部分是对应内部结构的组合逻辑部分,即查找表部分,右边红色是对应内部结构的寄存器。红色部分的两根线,上面一个表示输入连线,下面的表示输出连线。
建议大家设计的时候,都去看看底层,看多了,就熟悉了。。
通过timequest分析,时序是满足的,下到板子中,也是按照我们想要的功能执行的。