竞争&冒险
在逻辑电路中,如果有多条输入信号线上面的信号同时发生跳变(并没有按照设计的时序改变),就会产生一些信号尖峰(噪声)。这会影响到电路的正常工作,就是俗称信号毛刺。因为做过嵌入式开发,对于这一种现象是非常讨厌的(一般是传感器出来的信号),毕竟会增加系统出错几率。一般处理会延时接收信号,或者硬件滤波(并上小电容),或者软件滤波算法。
竞争&冒险的产生原因
原因有很多,例如材料物理特性(不同器件)、电磁干扰问题、电路制造工艺等都会造成这个情况。下面有具体分析:
1)物理特性
因为半导体里面,可能需要参杂一些杂质才可以制作出来(低纯度硅,又可能非硅)。不同半导体材料的导电性能是不一样的, 这样导致信号从传输速度不一样,也就不好统一控制。
2)电磁干扰
很可能你原来设计的电路没问题的,可是有的硬件工程师们不懂EMC设计,把你的输入电路和时钟线这样特强干扰源线路平行放在一起了。 结果你设计的电路输出信号被时钟线的干扰耦合到了,出现了很多尖峰。 时钟频率越高,干扰越离谱。
3)制造工艺
如果制造工艺落后,处理不好,导致产品上面的线路阻抗不太统一(也就是因为工艺造成物理特性上的差异),从而导致信号通过速度不太好把控。
如何解决?
当然,一个电路系统不可能完全没有信号毛刺的,那么在设计电路时候如何避免呢?有两个思路:
1)加一个寄存器作为不同模块电路中的交互模块。因为寄存器在时钟信号跳变的时候刷新状态,只要杂质信号没有在时钟信号跳变的时候出现即可避免毛刺信号出现。这个要看几率,如果非要在时钟跳变时候常出现毛刺,那也毫无办法了。
例子(参考上一篇):
module flow_led(
input sys_clk ,
input sys_rst_n,
input ina,
input inb,
input inc,
output outf);
//作为逻辑运算的中间值寄存器
reg f_buf0;
reg f_buf1;
reg f_buf2;
//每次时钟上升沿刷新都把中间数据运算并放到寄存器中
always @ (posedge sys_clk or negedge sys_rst_n) begin
if(!sys_rst_n) begin//如果复位成立,寄存器清零
f_buf0 <= 1'b0;
f_buf1 <= 1'b0;
f_buf2 <= 1'b0;
end
else begin//上升沿的话计算出中间值
f_buf0 <= ina&inb;
f_buf1 <= inb&inc;
f_buf2 <= ina&inc;
end
end
assign outf=f_buf2|f_buf1|f_buf0;
endmodule
2)利用时序逻辑对信号进行处理。例如在一个逻辑组合电路里面有好几步逻辑运算。那么把逻辑运算的任务用时钟周期分割成好几步即可。
例子省略。
这些方法都属于减少毛刺出现几率,并不能根治,只要满足系统要求就可以。