随着半导体技术的飞速发展,fpga(field programmable gate array)的计算能力、容量以及可靠性也有了很大的提高。它正以高度灵活的用户现场编程功能、灵活的反复改写功能、高可靠性等优点,成为数字电路设计、数字信号处理等领域的新宠。但和所有的数字电路一样,毛刺也是fpga电路中的棘手问题。它的出现会影响电路工作的稳定性、可靠性,严重时会导致整个数字系统的误动作和逻辑紊乱。因此,如何有效正确的解决设计中出现的毛刺,就成为整个设计中的关键一环。 本文就fpga设计中出现的毛刺问题,根据笔者自己的经验和体会,提出了几种简单可行的解决方法和思路,供同行供交流与参考。 fpga电路中毛刺的产生 我们知道,信号在fpga器件中通过逻辑单元连线时,一定存在延时。延时的大小不仅和连线的长短和逻辑单元的数目有关,而且也和器件的制造工艺、工作环境等有关。因此,信号在器件中传输的时候,所需要的时间是不能精确估计的,当多路信号同时发生跳变的瞬间,就产生了“竞争冒险”。这时,往往会出现一些不正确的尖峰信号,这些尖峰信号就是“毛刺”。另外,由于fpga以及其它的cpld器件内部的分布电容和电感对电路中的毛刺基本没有什么过滤作用,因此这些毛刺信号就会被“保留”并传递到后一级,从而使得毛刺问题更加突出。 可见,即使是在最简单的逻辑运算中,如果出现多路信号同时跳变的情况,在通过内部走线之后,就一定会产生毛刺。而现在使用在数字电路设计以及数字信号处理中的信号往往是由时钟控制的,多数据输入的复杂运算系统,甚至每个数据都由相当多的位数组成。这时,每一级的毛刺都会对结果有严重的影响,如果是多级的设计,那么毛刺累加后甚至会影响整个设计的可靠性和精确性。下面我们将以乘法运算电路来说明毛刺的产生以及去除,在实验中,我们使用的编程软件是quartus ii2.0,实验器件为cyclone ep1cf400i7。需要说明一点,由于示波器无法显示该整数运算的结果,我们这里将只给出软件仿真的结果。而具体的编程以及程序的下载我们在这里也不再详述,可以参考相关的文献书籍。 毛刺的消除方法 首先,我们来设计一个简单的乘法运算电路。运算电路如图1所示。
图 1 乘法运算运算电路及结果
如图1(c)所示,如果在不加任何的去除毛刺的措施的时候,我们可以看到结果c中含有大量的毛刺。产生的原因就是在时钟的上升沿,每个输入(a和b)的各个数据线上的数据都不可能保证同时到达,也就是说在时钟读取数据线上的数据的时候,有的数据线上读取的已经是新的数据,而有的数据线上读取的仍然是上一个数据,这样无疑会产生毛刺信号,而当数据完全稳定的时候,毛刺信号也就自然消失了。 输出加d触发器 这是一种比较传统的去除毛刺的方法。原理就是用一个d触发器去读带毛刺的信号,利用d触发器对输入信号的毛刺不敏感的特点,去除信号中的毛刺。这种方法在简单的逻辑电路中是常见的一种方法,尤其是对信号中发生在非时钟跳变沿的毛刺信号去除效果非常的明显。 但是对于大多数的时序电路来说,毛刺信号往往发生在时钟信号的跳变沿,这样d触发器的效果就没有那么明显了(见图2,加d触发器以后的输出q,仍含有毛刺)。另外,d触发器的使用还会给系统带来一定的延时,特别是在系统级数较多的情况下,延时也将变大,因此在使用d触发器去除毛刺的时候,一定要视情况而定,并不是所有的毛刺都可以用d触发器来消除。
图2 加d触发器后的运算电路及结果
信号同步法 在很多**中都提到,设计数字电路的时候采用同步电路可以大大减少毛刺。另外,由于大多数毛刺都比较短(大概几个纳秒),只要毛刺不出现在时钟跳变沿,毛刺信号就不会对系统造成危害了。因此很多人认为,只要在整个系统中使用同一个时钟就可以达到系统同步的目标了。但是这里面有一个非常严重的问题,就是时钟信号和其他所有的信号一样,在fpga器件中传递的时候是有延时的,这样根本就无法预知时钟跳变沿的精确位置。也就是说我们无法保证在某个时钟的跳变沿读取的数据是一个稳定的数据,尤其是在多级设计中,这个问题就更加突出了。因此,做到真正的"同步"就是去除毛刺信号的关键问题。我认为这里同步的关键就是保证在时钟的跳变沿读取的数据是稳定的数据而不是毛刺数据。以这个思想为出发点,提出了以下几种具体的信号同步方法。 信号延时同步法 首先,我们给出了一个两级乘法(c=a b;q=d c)的运算结果(如图3所示,这里不再给出运算电路)。可以看到,在没加任何处理过程的时候,两级结果c和q中都含有大量的毛刺信号。其中毛刺信号产生的原因就是在计算时钟跳变时刻,数据信号同时发生了跳变。另外,第一级信号c中含有大量的毛刺,在经过第二次乘法运算以后被明显放大了,从图3可以看出q中毛刺更加严重了。但在很多实际工作中,我们最关心的往往是最后的输出结果(q),只要中间信号的毛刺对后面的输出没有什么影响我们就不需要对它们作任何处理了。因此,这里所提出的信号同步的核心思想就是消除这些中间毛刺信号的影响。
图 3 两级乘法运算的结果仿真
信号延时法,它的原理就是在两级信号传递的过程中加一个延时环节,从而保证在下一个模块中读取到的数据是稳定后的数据,即不包含毛刺信号。这里所指的信号延时可以是数据信号的延时,也可以是时钟信号的延时。由于篇幅的关系,这里我们主要以对时钟信号的延时来说明信号延时法的原理。对上述计算过程加时钟信号延时的原理及结果如图4所示。
图4 加了时钟延时的两级乘法运算及结果
图4中的clkdelay就是时钟延时环节。在加这个环节以前的时钟信号是直接连到模块b上的,这样两个模块使用同一时钟,好像已经做到了同步,但是如图3所示,结果中含有大量的毛刺,其原因就是产生毛刺的根本原因--“竞争冒险"现象没有得到根本性的消除。加时钟延时环节的作用就是要从根本上消除“竞争冒险”,其过程是将控制模块b的时钟延时一段时间,使得模块b的控制时钟在上跳变化时数据c已经达到了稳定,即不含毛刺信号的数据,而这时数据d也已达到稳定,这样竞争冒险现象消除了,从而毛刺信号也得到了有效的抑制,如图4 (c) 所示。 与时钟延时法的原理相同,我们也可以在数据信号加延时环节来消除竞争冒险的现象,达到真正的同步。这里的延时环节可以使用quartus ⅱ提供的lcell实现,也可以使用d触发器和一个高频的计数脉冲灵活实现。另外我们也可以从综合结果(图4 (c)所示)看到,所加的延时环节占用的芯片资源是很少的,是一种简单有效而且节约资源的方法。 时钟信号的灵活使用 和上述方法的原理相似,灵活使用时钟信号的目的也是尽可能的消除竞争冒险。比如在时钟的第一个跳变沿触发模块a,下一个跳变沿控制触发模块b,这样时钟的交替控制也在一定程度上消除了竞争冒险,从而抑制了毛刺信号。还比如分别使用时钟的上升沿或者下降沿控制不同的模块。但是这些方法不适合使用在比较复杂的设计中,否则会使设计的条理非常的混乱,给以后的阅读修改带来很大的困难。因此,在选用这种方法的时候一定要慎重。 状态机控制 对于大型的数字电路设计,状态机是一种非常理想的选择,能使运行性能和硬件资源的占用达到最佳的优化,另外灵活的使用状态机也可以实现信号的同步和消除毛刺的目的。在数据传递比较复杂的多模块系统中,由状态机在特定的时刻分别发出控制特定模块的时钟信号或者模块使能信号,状态机的循环控制就可以使得整个系统协调运作,同时减少毛刺信号。那么只要我们在状态机的触发时间上加以处理,就可以避免竞争冒险,从而抑制毛刺的产生。原理如图5所示。
图 5 状态机控制原理
限于篇幅的原因,这里我们只讲述状态机控制的原理,提出一种新的思路。 总结 由于毛刺信号对fpga器件的运行有很大的影响,如何有效抑制毛刺信号就成了一个非常突出的问题。但是必须强调的一点就是,我们首先必须对程序设计本身进行优化和改进,使毛刺信号的产生降低到最小,比如将一些信号用变量代替来减小延时等。另外,在实际应用中如何选用适合的方法也非常的重要,一定要慎重考虑。比如延时环节的加入会使整个系统的延时增大,加入太多时就会影响系统的运行等。 |