对于同步单元,可以选择同步复位、异步复位或者不复位。有些人对不复位存有疑问,在ASIC设计中也许不行,但在FPGA设计中这个真的可以有。
一、能不用复位的就别用了。
reset,作为一个实际存在的物理信号,需要占用FPGA内部的route资源,往往reset的fanout又多得吓人。这就很容易造成route难度上升,性能下降,编译时间增加。因此,在FPGA设计中能省略的复位应尽量省略。
举几个我经常省略复位的地方,但不是绝对适用:
1.分频用的计数器
除非需要控制初始相位,否则分频用的计数器往往都是自由运行的,只要每个时钟加1就好。
2.移位寄存器
为了使pipeline配合正确,设计中经常会存在移位寄存器。这种情况下,你只要复位第一级寄存器,然后保持若干个周期,移位寄存器就被彻底复位了,而不用为每个bit都添加复位。移位寄存器不使用复位的又一个好处是可以利用SRL。
3.moore型状态机输出
对于那些moore型状态机的输出,你只要复位了状态机,下一个周期就会被复位。
不用复位可能会引起的一个问题是仿真时出现一堆的X。这个问题可以通过在HDL文件中为寄存器赋初值解决。
二、同步复位和异步复位
异步复位的优点:
不和时钟挂钩,EDA工具route起来更容易。
在没有时钟的时候也可以将电路复位。
输入时钟突然消失,为了防止逻辑混乱导致错误,那么就用异步复位吧,可以把PLL的lock信号当做异步复位。
异步复位的缺点:
无法进行时序分析,可能因为skew的问题造成逻辑错误。比如state[3:0]是一个状态机信号,由于异步复位的skew,可能造成state[3]比state[2]多复位了一个时钟周期。
毛刺会造成复位
有时上电可以工作,有时上电不能工作,看看是不是复位的问题。
同步复位的优点:
改善了异步复位的缺点
同步复位的缺点:
在高速时钟域比较难满足时序要求,或者为了满足时序造成编译时间增加。
总体来讲,在拿不准的情况下,用同步复位会更为可靠一些。同步复位要先将复位信号同步到该时钟域——打几拍时钟就可以了。
三、复位信号的选择
复位信号可能有多种源可供选择,常见的有外部的复位信号(例如复位电路产生的信号,push button, cpu的gpio等等),PLL的lock信号,内部逻辑产生的复位信号等等。
对于一般的逻辑,一起复位是没有问题的,但有时几个模块的复位最好有先后次序。
1.级联的锁相环
可以将第一级锁相环的lock信号经过几个时钟的延时,作为第二级锁相环的复位。
2.IODELAY和IDELAYCTRL
可以用IDELAYCTRL的rdy信号去复位IODELAY
3.GTP/GTX
这里面有一堆的复位,懒的专门去查一下资料了,回头有空再补吧。
四、总结
复位是容易被忽略的部分,但很重要,起始状态都不对电路还跑个屁啊。在给每个寄存器写复位的时候要想一下,不要想当然的加上if(!rstn)...否则最后发现设计工作不稳定,查原因可是很难的。