FPGA从Xilinx的7系列学起(13)

Reset分为全局Reset和局部Reset。全局Reset可以让所有存储类的元素处于一个已知的状态。全局的Reset一般是通过外部的引脚或者一个标准进程的完成或者等待PLL/MMCM锁定信号的有效来实现的。局部复位一般是有内部信号产生,他是让一些存储类的元素处于一个已知的状态,如利用内部的计数器。一般来说局部复位都是同步信号。

Reset又分为同步复位和异步复位,一个同步的局部复位是一个标准设计里面的一部分,一般都是使用状态机或者计数器让一些信号进入一个固定的状态,例如经常会用的0状态。综合工具一般是建议使用同步设计,不建议使用异步设计的。当使用异步复位设计的时候,可能会产生一个亚稳态,让电路处于一个不确定的状态。因此局部的异步复位,最好不要使用。对于全局的异步复位,需要一些方法来处理它,以前提过异步的同步化。

全局的同步置位/复位信号可以让存储类的元素进入一个已知的状态, 那么他带来的好处是什么?全局的同步置位/复位信号实现非常简单,可以在工程师需要的时候控制设计中的控制信号或者触发控制信号,确保设计万无一失,更可以使用让综合工具来进行减少控制信号功能。那么它的缺点是什么?当时钟不能保证正常工作的时候,同步复位信号将不能够生。另外,同步复位会占用一些同步资源,可能会影响用户的时序设计的目标。

全局的异步使用,以前我们就讲过,必须异步的同步化。这样才能保障用户的设计不进入到亚稳态。但是有时候,用户会必须使用异步复位,它的优点就是任何时候生效的时候都能工作,例如,当用户使用一个热插拔影响时候,这可能需要一个不依靠时钟产生复位来保障整个工作的启动。缺点也很明显,它不能使用减少控制信号的功能,也会大量占用布线资源。目前很多综合工具都是支持把异步复位转换为同步复位。

既然异步复位不应该使用,那么对于用户已经设计的代码我们应该怎么处理呢?有三种选择,第一,留下设计中的异步复位,清楚的了解他的缺陷。第二,你使用工具转换(如下图所示)。这个是非常危险的,因为异步复位毕竟和同步复位不一样,转换后,代码的综合结果可能和行为仿真出来的结果完全不同。第三,修改你的代码或者使用脚本来修改代码让异步变成同步,这个是我们推荐的方法。要记住只是顶层修改一下复位代码并不一定能够有一个正确的结果,还是应该把所有的代码检查一遍,然后把从HDL级上把所有的异步复位清除掉。

如何选择使用哪种方式来处理已有设计呢?如果已有设计的代码完全没有问题,能用满足时序要求,能够使用当前选用的器件,那么工程师就没有必须去做什么改动。综合工具不可能像修改代码一样的有效果,那么一定要仔细考虑使用该选项,虽然该功能可能会有一些问题,但是毕竟是简单易使用。

对大型的特别复杂的设计且时序等等都不满足要求,就只能修改代码了。再强调一下不要只是简单的修改顶层,因为综合工具都是从底层开始综合的,所以用户必须从Flip-Flops这个级别进行修改。

下图是一个用户的例子,他除了有专门的GSR的复位外,额外使用了同步全局复位,可以看到他大量的占用了布线资源,最后造成了用户设计的时序目标无法完成。要记住复位信号是需要和设计中的其他信号来竞争占用相同的设计资源,包括关键路径的时序,如果这些设计资源给其他信号使用能够更好满足设计的时序要求。有心的用户可以检查一下一个典型的复位,就会知道有多少扇出数量,这个扇出的数量会让用户觉得可怕。这也是为什么要在设计中删除复位的最大原因了。

在芯片中有一个GSR资源,有专门的慢速布线资源,他能够在几个毫秒的级别里面激活。如果用户需要时刻驾驭自己设计,同时需要在系统运行过程中去复位,那么GSR对该用户是没有意义的。这因为GSR还是太慢,毕竟它不是基于时间来复位的,这个条件下我们也不推荐用户使用GSR。然而,GSR将自动作为配置过程的一部分。配置完成后,所有的触发器都会处于一个已知状态。如果用户想尝试和使用,或以某种方式控制它,那么需要例化一个UPE2的原语进入到用户的设计中,并连接到GSR的输入上。但是这个实在是没有意义,因为它太慢了,因此不推荐它作为一个复位系统的方式。

文章来源:FPGA那点事儿