电子说
1、为什么要设计复位?
首先回想一下,在平常的设计中我们是不是经常采用同步复位或者异步复位的写法,这一写法似乎都已经形成了肌肉记忆----每次我们写always块的时候总是会对所有的寄存器写一个复位赋初值的语句。
这样设计的目的是什么?似乎是为了给寄存器一个初值,避免仿真不定态或初始化操作错误。又似乎是为了在调试时能方便地使用按键进行复位(最常用的全局复位)。这么一看复位似乎是蛮重要的。
2、复位是否有必要?
似乎在平常的设计中,多数会使用异步复位的方式,异步复位由于是异步信号,所以不可避免地引入了亚稳态的可能,这一可能性随着时钟频率的提高而增加。好像在平常的设计与使用中,异步复位电路也不会引发什么问题。这是因为随着器件工艺的提升,现在器件的上升时间在0.0x 纳秒级,而一般设计的时钟周期可能在100~200M。只要复位的释放不是刚好在这0.0x 纳秒内就不会引发亚问题问题,显然这个概率极小(比例--0.0x:10),基本可以说是99.99不会有问题。但是著名的墨菲定律高速我们:再小概率的事情都会发生。所以不管怎样这种事情我们都应该要想办法避免。
再来看我们使用复位的主要目的:为了给寄存器一个初始值,从而避免仿真或使用错误。然而实际上,Xilinx的FPGA的内部资源(触发器和RAM)等都会在上电后默认赋初值,一般是0,或者可以在定义寄存器时手动赋值,如:
reg [1:0] test = 2'b01; //定义时即赋初值
这么看的话仅仅为了赋初值而存在的赋值就没有意义的。数据链路上有初值就够了,因为后来的数据总会冲走之前的数据,数据仍然能稳步传递。但是控制链路就一定需要被复位后一定要恢复到初始状态,不然会“乱跑‘从而导致代码运行异常。其中最经典的例子就是状态机了,显然,如果状态机的状态模块没有复位的话,那么可能在出现异常后永远无法恢复到正常状态了。
最后,复位所使用的资源远超你的想象:
3、应该怎样设计复位?
说了这么多,那到底要怎么设计复位?
同步or异步?
在一文中探讨过同步复位与异步复位的特点。
同步复位:
有利于仿真
由于只在时钟有效电平到来时才有效,所以可以滤除高于时钟频率的复位毛刺,没有亚稳态问题
可以使所设计的系统成为 100%的同步时序电路,有利于时序分析
复位信号的有效时长必须大于时钟周期,才能真正被系统识别并完成复位任务。同时还要考虑延时因素
大多数的FPGA的DFF都只有异步复位端口,采用同步复位的话,综合器就会在寄存器的数据输入端口插入组合逻辑,这样会耗费逻辑资源
异步复位
大多数目标器件库的dff都有异步复位端口,因此采用异步复位可以节省资源
设计相对简单,异步复位信号识别方便,而且可以很方便的使用FPGA的全局复位端口GSR
复位信号容易受到毛刺的影响且容易存在亚稳态问题
建议使用同步复位的方式,若一定要使用异步复位的话,则建议使用异步复位、同步释放的方法。
高or低?
选择高还是低,需要根据具体的电平标准、器件结构来选择,并不是一概而论低电平有效的好或者高电平有效的好。简单经验:Altera的用低电平复位,Xilinx的用高电平复位。
总结
复位信号能不用就不要用,需要特定初值的可以在定义寄存器时赋值
如果一定需要则使用异步复位、同步释放的方法,并将复位信号局部化,避免高扇出。
审核编辑:汤梓红
全部0条评论
快来发表一下你的评论吧 !