1毛刺产生的原因
竞争与冒险:
有两种情况会产生竞争:门电路两个输入信号同时向相反的逻辑电平跳变或同一信号经不同路径到达终点的时间有先有后的现象。
例1:信号 A、B 不可能突变,需要经历一段极短的过渡时间。而门电路的传输时间也各不相同,故当A、B同时改变状态时可能在输出端产生虚假信号。
例2:同一信号经不同路径到达终点的时间有先后(或者两个不同信号变化不同步)
结果,在t1-t2 时间内,电路输出端产生了Y=1的尖峰脉冲,不符合静态下,Y恒为0的逻辑关系:
竞争:在组合电路中,信号经由不同的途径达到某一会合点的时间有先有后,这种现象称为竞争。
冒险:由于竞争而引起电路输出发生瞬间错误现象称为冒险。表现为输出端出现了原设计中没有的窄脉冲,常称其为毛刺。
竞争与冒险的关系:有竞争不一定会产生冒险,但有冒险就一定有竞争
2毛刺造成的危害
当毛刺信号成为系统的启动信号,控制信号,握手信号,触发器的清零信号,预置信号,时钟信号,或锁存器的输入信号时就会产生逻辑错误
组合逻辑产生的毛刺也会大量消耗功耗。毛刺会提高电路的活动因子增加功耗
毛刺并不是对所有的输入都有危害,例如D触发器的D输入端,只要毛刺不出现在时钟的上升沿并且满足数据的建立和保持时间,就不会对系统造成危害,因此可以 说D触发器的D输入端对毛刺不敏感。
3毛刺消除的方法
消除或者增加互补项
利用冗余项消除毛刺有 2 种方法:代数法和卡诺图法,两者都是通过增加冗余项来消除险象,只是前者针对于函数表达式而后者针对于真值表。以卡诺图为例,若两个卡诺圆相切,其对应的电路就可能产生险象。因此,修改卡诺图,在卡诺图的两圆相切处增加一个圆,以增加多余项来消除逻辑冒险。但该法对于计数器型产生的毛刺是无法消除的。
输出端并联电容器吸收
由于产生的毛刺实际上是高频窄脉冲,故增加输出滤波,在输出端接上小电容 C 就可以滤除毛刺。但输出波形的前后沿将变坏,在对波形要求较严格时,应再加整形电路,该方法不宜在中间级使用。
引入时序逻辑采样
利用 D 触发器的输入端 D 对毛刺信号不敏感的特点,在输出信号的保持时间内,用触发器读取组合逻辑的输出信号。由于在时钟的上升沿时刻,输出端 Q=D,当输入的信号有毛刺时,只要不发生在时钟的上升沿时刻,输出就不会有毛刺。这种方法类似于将异步电路转化为同步电路,实现简单,但同样会涉及到时序问题。
延迟法 因为毛刺最终是由于延迟造成的,所以可以找出产生延迟的支路。对于相对延迟小的支路,加上毛刺宽度的延迟可以消除毛刺。但有时随着负载增加,毛刺会继续出现,而且,当温度变化,所加的电压变化或要增加逻辑门时,所加的延迟是不同的,必须重新设计延迟线,因而这种方法也是有局限性的。而且采用延迟线的方法产生延迟会由于环境温度的变化而使系统可靠性变差。 硬件描述语言法 这种方法是从硬件描述语言入手,找出毛刺产生的根本原因,改变语言设计,产生满足要求的功能模块,来代替原来的逻辑功能块。一个 3 位计数器可能会在 011 到 100 和 101到 110 发生跳变时产生毛刺,究其原因是因为一次有 2 位发生跳变,可以采用 格雷码或者lsfr计数器,产生的计数模块代替原来普通的计数器。
用verilog代码,实现消除一个glitch
(1) 滤掉小于1个周期glitch的原理图如下:
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的原理图如下:
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