前面几节,创建了NIOS II软核,并添加进了工程,这一节说一下FPGA工程中的时序约束。可能有些啰嗦,为什么点个灯这么麻烦,这,,,,确实要多注意一些!
问:为什么FPGA要进行时序约束?
答:不约束,有的时候真的会功能异常。
单片机要不要时序约束?单片机工作频率范围固定(别超频),每行代码对应固定的汇编指令,每个汇编指令执行的周期固定。程序员写什么代码,单片机执行什么指令。所以从单片机内部来说,没有时序方面的问题。
但是FPGA和单片机不一样,FPGA本质上来说,并不是CPU,它就是一大堆的逻辑门电路。而FPGA的每行代码,并没有明确的工作指令,更没有固定的执行周期。
FPGA代码的功能是用于组合这些逻辑门电路。代码要求的功能越多,耗费的逻辑资源就越多,需要的时间就越多。所以,单个周期内,不要给FPGA安排太多的工作。而是要把工作细分,逐个周期进行推进。
打个比方,这里有个房间,10分钟内,我需要进行一个大扫除,给再多的人,这也是不可能实现的。正确的方法:先用5分钟清理桌面,然后用5分钟扫地,然后用5分钟擦地,然后用5分钟倒垃圾,等等等等,逐步进行。
回到FPGA这里,时序优化的意义在于,你要告诉FPGA,你工作的频率是多少。Quartus II会根据你要求的速率,对逻辑资源进行分配。单位时间内,功能复杂的话,多分配一些资源,功能简单的话,少分配一些资源。最终,实现目标频率下的稳定工作。
Quartus II内部提供了丰富的工具,可以进行时序分析。这里简单说下timequest timing analyzer wizard的使用。
一、打开timequest timing analyzer wizard
点击菜单栏中的Assignments,在下拉框中点击:timequest timing analyzer wizard。
弹出如下对话框:
二、配置输入时钟
点击next,进入时钟配置页面。如下图所示,位置1,给该路时钟信号起个名字。这里写的是:clk。
位置2,选择FPGA的时钟输入管脚,也就是实体中的Clk。
位置3,提供该时钟的周期,我们提供的是50Mhz的晶振,所以单个周期是20ns。
位置4,该周期内,上升沿和下降沿的时间。
填好之后,一路next,后面的配置不用管,一直到结束。
这时,在文件列表中,会出现一个新的文件:nios_led.sdc,双击打开,能看到我们配置的信息:
三、编译
点击菜单上的快捷键:Start Compilation,编译。
结束后,查看Compilation Report。
按顺序,依次点击1、2、3、4,可以看到经过时许约束后的工作状态。
Clk,就是外接50Mhz的时钟管脚,它最高能工作到250Mhz;
U0那里,就是创建的nios软核,最高速度能跑到123Mhz,我们实际给它接的是100Mhz的时钟,所以肯定是没问题的。
至于tck,不用管。
所以,通过上述方法,我们实现了FPGA程序的时许约束,确保程序在目标条件下正常运行。
四、补充,不满足怎么办
其实前面说的很清楚,写程序的时候要注意,不要在一个时钟周期里安排太多的工作,否则FPGA肯定难以满足。
报错的时候,会提示哪个模块的哪些信号时钟速度不满足,根据经验调整吧。
其实还有一个偷懒的方法。
假设,目标需求100Mhz的运行速度,但时序约束以后只能达到95Mhz。那么我们可以把目前提高到150或者120Mhz,这样的话,quartus II在进行约束后,肯定达不到120Mhz,但是会有一定的提升。只要超过100Mhz就行了。
至此,时序约束的内容讲完了。有些程序,不用约束,也能运行,但不代表它运行稳定。因为我确实遇到过时序约束达不到目标,实际运行故障的现象。所以,务必慎重。
我是单片机爱好者-MCU起航,打完收工!