【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】
前面说过,fpga上面最基础的部分是寄存器,而所有寄存器存在每一个clock下,都有被翻转的可能性。至于这些寄存器是不是真的翻转,或者说是保持不变,取决于当时的状态。所以在clock运行的区间内,我们习惯于把任务切分成若干个状态,不同状态下的register是不一样的,当然只有一部分register参与工作,大部分保持不变。等到条件成熟的时候,再切换到下一个状态。这就是fpga下状态机运行的基本原理。
1、时序逻辑是基础
寄存器是fpga的基本电路。或者可以这么说,fpga的基本构成就是一个一个的时序逻辑。这些时序逻辑或者置0,或者置1,或者取反,或者保持不变。针对这些寄存器的运算,那就是组合逻辑。当然组合逻辑不能链路太长,否则影响时序。除了寄存器的运算之外,组合逻辑的另外一个信号来源就是外部输入。所有的外部输入都可以看成是组合逻辑。
2、组合逻辑是辅助
时序逻辑可以保证,信号在clock的周期内保持不变,这是极为重要的特性。如果信号随时发生改变,那也就没有办法参与运算了,因为很多的运算本身就是依赖于其他信号的存在,这样才会一步一步向前推进,而组合逻辑则不一样。
就拿外部信号举例,假设来一个gpio信号,fpga正常运行,此时由于gpio优先级高,那么下一个clock就要优先处理这个gpio。但是如果下一个clock来临之前,又有一个gpio信号出来。不失一般性,前者命名为signal A,后者命名为signal B,那么此时就会发生仲裁,如果signal B优先级高,下一次优先处理的信号就是signal B。在clock之间的这段时间,时序电路是不变的,但是组合逻辑可能随时由于外部的输入而发生变化,这就是组合逻辑的特点。
3、clock和rst是最重要的两个信号
clock是寄存器的发动机,它推动着寄存器,或者是时序电路不停向前走。形象一点比喻,它就类似于交响乐队的指挥棒,每一个演奏者都要跟着这个指挥棒进行操作。而rst就是复位信号,在板子还没有启动的时候,或者说clock还不稳的时候,rst保证了信号最初始的一个状态。所以,正是由于clock和rst的存在,让fpga可以按照我们的设计来处理各种各样的信号。
4、小模块的状态机和系统状态机
状态机不仅仅是小模块可以使用,大模块也可以使用。在小模块里面,不同状态下,相当于一部分register参与运算,另外一部分register不参与运算。而在大模块下,则相当于一部分模块参与运算,另外一部分模块不参与运算。本质上,两者是一样的。
5、从波形到代码,再到波形
了解了时序逻辑、组合逻辑和状态机之后,我们发现fpga的颗粒度很低,本质上,它就是一个信号计算器。抽象出来,就是一个一个波形。所以,如果我们需要设计什么功能,可以先设计出原型、状态机,或者是自己先把波形画出来,接着把这些波形转成verilog代码,最后在仿真测试、实际测试,验证一下实际的波形和设计的波形是不是同一个,这样就可以验证自己写的到底对不对,是设计的问题、写的问题、还是测试的问题。
6、时刻牢记寄存器的并发性
fpga最大的不同,就是寄存器的并发性。只要有时钟在驱动,所有寄存器就有翻转、改变的可能性。至于是不是真的改变,完全取决于当时的状态。所以编写verilog的时候,可以考虑下,当前信号属于什么信号,什么时候复位,什么时候改变,改变的时候属于什么状态,什么时候又保持不变,这样不停思考下去,fpga才能越写越好,越写越稳定。
不同的task,一旦发现数据合法性不对,就立马恢复到初始状态。等到所有input和register都ok之后,再去开始对应的工作,这样就可以让fpga一直稳定地运行下去。