FPGA学习之毛刺问题

在FPGA的设计中,毛刺现象是长期困扰电子设计工程师的设计问题之一,是影响工程师设计效率和数字系统设计有效性和可靠性的主要因素。由于信号在FPGA的内部走线和通过逻辑单元时造成的延迟,在多路信号变化的瞬间,组合逻辑的输出常常产生一些小的尖峰,即毛刺信号,这是由FPGA内部结构特性决定的。毛刺现象在FPGA的设计中是不可避免的,有时任何一点毛刺就可以导致系统出错,尤其是对尖峰脉冲或脉冲边沿敏感的电路更是如此。因此,克服和解决毛刺问题对现代数字系统设计尤为重要。本文从FPGA的原理结构的角度探讨了产生毛刺的原因及产生的条件,在此基础上,总结了多种不同的消除方法,在最后结合具体的应用对解决方案进行深入的分析。

1 毛刺产生的原因
1.1 建立时间和保持时间
建立时间(setup time)是指在触发器的时钟信号上升沿到来以前,数据稳定不变的时间,如果建立时间不够,数据将不能在这个时钟上升沿被打入触发器;保持时间(hold time)是指在触发器的时钟信号上升沿到来以后,数据稳定不变的时间, 如果保持时间不够,数据同样不能被打入触发器, 如图1。 数据稳定传输必须满足建立和保持时间的要求,当然在一些情况下,建立时间和保持时间的值可以为零。
FPGA学习之毛刺问题_第1张图片
1.2 竞争和冒险
FPGA芯片是由可构造的输入输出块(Input/OutputBlock,IOB)、可构造逻辑块(Cinfigurable Logic Block,CLB)和可编程连线资源(Programmable Interconnect Array,PIA)3种可构造单元构成的。IOB位于芯片内部四周,在内部逻辑阵列与外部芯片封装引脚之间提供一个可编程接口,他主要由逻辑门、触发器和控制元组成。CLB组成了FPGA的核心阵列,能完成用户指定的逻辑功能;每个CLB主要有一个组合逻辑、几个触发器、若干个多选一电路和控制单元组成;PIA位于芯片内部的逻辑块之间,经编程后形成连线网络,用于芯片内部逻辑间的相互连接,并在他们之间传递信息。信号在FPGA器件内部通过连线和逻辑单元时,都有一定的延时。延时的大小与连线的长短和逻辑单元的数目有关,同时还受器件的制造工艺、 工作电压、温度等条件的影响。信号的高低电平转换也需要一定的过渡时间。由于存在这两方面因素,多路信号的电平值发生变化时,在信号变化的瞬间,组合逻辑 的输出有先后顺序,并不是同时变化(及竞争现象),往往会出现一些不正确的尖峰信号,这些尖峰信号称为"毛刺"。如果一个组合逻辑电路中有"毛刺"出现,就说明该电路存 在"冒险"。(与分立元件不同,由于PLD内部不存在寄生电容电感,这些毛刺将被完整的保留并向下一级传递,因此毛刺现象在PLD、FPGA设计中尤为突 出)也就是说,在FPGA设计中,毛刺产生的根本原因是信号在芯片内部走线时产生的延迟。

2 毛刺产生的条件
由于延迟的作用,多个信号到达终点的时间有先有后,形成了竞争,由竞争产生的错误输出就是毛刺。所以,毛刺发生的条件就是在同一时刻有多个信号输入发生改变。

3 消除毛刺的方法
知道了毛刺产生的条件,就可以通过改变设计,破坏其条件来减少毛刺的发生。例如,利用格雷码计数器每次输出只有一位跳变的特性,代替普通的二进制计数器,避免了毛刺的产生。还可以对电路进行改进,以消除毛刺对系统的影响。下面对各种方法做分别介绍:
3.1 利用冗余项法
利用冗余项消除毛刺有2种方法:代数法和卡诺图法,两者都是通过增加冗余项来消除险象,只是前者针对于函数表达式而后者针对于真值表。以卡诺图为例,若两个卡诺圆相切,其对应的电路就可能产生险象。因此,修改卡诺图,在卡诺图的两圆相切处增加一个圆,以增加多余项来消除逻辑冒险。但该法对于计数器型产生的毛刺是无法消除的。

3.2 采样法
由于冒险多出现在信号发生电平跳变的时刻,即在输出信号的建立时间内会产生毛刺,而在保持时间内不会出现,因此,在输出信号的保持时间内对其进行采样,就可以消除毛刺信号的影响,常用的采样方法有2种:一种使用一定宽度的高电平脉冲与输出相与,从而避开了毛刺信号,取得输出信号的电平值。这种方法必须保证采样信号在合适的时间产生,并且只适用于对输出信号时序和脉冲宽度要求不严的情况。另一种更常见的方法叫锁存法,是利用D触发器的输入端D对毛刺信号不敏感的特点,在输出信号的保持时间内,用触发器读取组合逻辑的输出信号。由于在时钟的上升沿时刻,输出端Q=D,当输入的信号有毛刺时,只要不发生在时钟的上升沿时刻,输出就不会有毛刺。这种方法类似于将异步电路转化为同步电路,实现简单,但同样会涉及到时序问题。

3.3 吸收法
由于产生的毛刺实际上是高频窄脉冲,故增加输出滤波,在输出端接上小电容C就可以滤除毛刺。但输出波形的前后沿将变坏,在对波形要求较严格时,应再加整形电路,该方法不宜在中间级使用。

3.4 延迟法
因为毛刺最终是由于延迟造成的,所以可以找出产生延迟的支路。对于相对延迟小的支路,加上毛刺宽度的延迟可以消除毛刺。但有时随着负载增加,毛刺会继续出现,而且,当温度变化,所加的电压变化或要增加逻辑门时,所加的延迟是不同的,必须重新设计延迟线,因而这种方法也是有局限性的。而且采用延迟线的方法产生延迟会由于环境温度的变化而使系统可靠性变差。

3.5 硬件描述语言法
这种方法是从硬件描述语言入手,找出毛刺产生的根本原因,改变语言设计,产生满足要求的功能模块,来代替原来的逻辑功能块。

3.6 用verilog代码,实现消除一个glitch
(1) 滤掉小于1个周期glitch的原理图如下:
FPGA学习之毛刺问题_第2张图片
verilog代码实现如下:

module digital_filter_(clk_in,rst,host_rst,host_rst_filter);
input  clk_in;
input  rst;
input  host_rst;
output host_rst_filter;
 
reg host_rst_d1;
reg host_rst_d2;
 
always@(posedge clk_in or negedge rst)
  begin
    if(!rst)
    begin
        host_rst_d1 <= 1'b1;
        host_rst_d2 <= 1'b1;
       end
    else
      begin
        host_rst_d1 <= host_rst;
        host_rst_d2 <= host_rst_d1;
 
      end
  end
 
assign host_rst_filter = host_rst_d1 | host_rst_d2;
endmodule

(2)滤掉大于1个周期且小于2个周期glitch的原理图如下:
FPGA学习之毛刺问题_第3张图片
verilog代码实现如下:

module digital_filter_(clk_in,rst,host_rst,host_rst_filter);
input  clk_in;
input  rst;
input  host_rst;
output host_rst_filter;
 
reg host_rst_d1;
reg host_rst_d2;
reg host_rst_d3;
 
always@(posedge clk_in or negedge rst)
  begin
    if(!rst)
    begin
        host_rst_d1 <= 1'b1;
        host_rst_d2 <= 1'b1;
        host_rst_d3 <= 1'b1;
      end
    else
  begin
        host_rst_d1 <= host_rst;
        host_rst_d2 <= host_rst_d1;
        host_rst_d3 <= host_rst_d2;
       end
  end
 
assign host_rst_filter = host_rst_d1 | host_rst_d2 | host_rst_d3;
 
endmodule

参考:
(1)http://www.cnblogs.com/adxiaowei/p/4045532.html
(2)https://wenku.baidu.com/view/9b67c5d649649b6648d747ed.html
(3)https://blog.csdn.net/wangyanchao151/article/details/83374982

你可能感兴趣的:(FPGA学习总结)