数字电路“竞争-冒险”现象的产生与消除

最近在学数电,遇到了“竞争-冒险”现象。它在数字电路设计过程中常常会给输出带来意外的结果,成为数字电路设计中不得不考虑的一环。

故文章先从概念、分类说起,分析该现象产生的原因,提出判断是否存在“竞争-冒险”现象的方法,最后提供一些解决方案。

概念

竞争(Race):信号由于经由不同路径传输达到某一汇合点的时间有先有后的现象,就称之为竞争。

冒险(Hazard):由于竞争现象所引起的电路输出发生瞬间错误的现象(一些不正确的尖峰信号),就称之为冒险。

有竞争不一定有冒险,但出现了冒险就一定存在竞争。

产生原因

信号在传输过程中存在一定的延时。延时的大小与连线的长短和逻辑单元的数目有关,同时还受器件的制造工艺、工作电压、温度等条件的影响。此外,信号的高低电平转换也需要一定的过渡时间。由于存在这两方面因素,多路信号的电平值发生变化时,在信号变化的瞬间,组合逻辑的输出往往有先后顺序,并不是同时变化。

以下面这个简单的电路为例,电路满足表达式 $F = A \cdot A’ = 0$,但由于门电路的延时,信号 $ A’ $ 相对于信号$A$ 会滞后些(时间由工艺决定)。两路信号的后级接入了与门,这个时间差就会在输出产生一个干扰脉冲,输出不恒为 0。

具体一些,我们关注一下与门:

若信号$A$ 已经变为高电平时,而信号$B$ 还处于从高电平准备变到低电平的过程,由于与运算的特性,就会产生一个脉冲。

上述产生一个高电平尖峰的现象可称为 “1”冒险(偏0冒险),它是由于原变量和反变量同时加到“与门”导致的;另一方面,还有一种 “0”冒险(偏1冒险),这是一种产生低电平尖峰的现象,是由于原变量和反变量同时加到“或门”导致。

检查方法

为了避免产生 “竞争-冒险” 现象,我们可以在设计电路时,常常采用下面几种方法来进行检查。

代数法

代数法是通过函数表达式的结构来判断是否具有产生竞争冒险的条件。

其具体方法是:

  1. 检查函数表达式中是否存在具备竞争条件的变量,即是否有某个变量X同时以原变量和反变量的形式出现在函数表达式中。
  2. 若有,则消去函数表达式中的其他变量,即将这些变量的各种取值组合依次代入函数式中,从而将它们从函数表达式中消去,只留下被研究的变量 $X$。
  3. 若表达式在一定条件下能简化成 $X \cdot X’$ 的形式,则电路可能存在“1”冒险;若能化简为 $X + X’$ 的形式,则可能存在“0”冒险。否则,不产生竞争冒险。

对于单输入变量的较大规模电路,最直观的方法就是逐级列出电路的真值表,并找出哪些门的输入信号会发生竞争。然后判断是否会在电路的输出端产生干扰脉冲。

这种方法虽然简单,但局限性太大,因为多数情况下都有两个以上输入变量同时改变状态的可能性。如果输入变量的数目很多,而且电路系统也很复杂,就更难从逻辑函数式上简单地找出所有产生竞争冒险现象的情况。

卡诺图法

卡诺图法判断更加直观,且更适合于多变量的逻辑函数。

  1. 画出卡诺图
  2. 作出卡诺圈
  3. 检查:如果卡诺圈相切,且在相切处没有重叠,则存在“竞争-冒险”现象。

例如,对于函数 $F=AB +B’C’$ ,卡诺图如下:

图中,列 00 和 列 10 处的卡诺圈相切,考虑切点处相邻的两个最小项,也就是说 $C=0,A=1$ 时,函数化为 $B+B’$ ,存在“竞争-冒险”现象。

仿真实验法

利用 modelsim、multisim 等仿真软件搭建实验电路,观察输出波形。在现代仿真软件的辅助下,一般很容易看出竞争冒险现象。

注:对于 Multisim 仿真,诸如与门、非门之类的元件应尽量选择实物模型而不是理想模型,否则可能仿真不出尖峰。

消除方案

对于“竞争-冒险”现象,通常有下面几种可选的解决方案。

增加冗余项

增加冗余项,是通过在函数表达式中“加”上多余的“与”项,或“乘”上多余的“或”项,使原函数不可能在某种条件下化成 $X + X’$ 或 $X \cdot X’$ 的形式,从而消除可能产生的竞争冒险,冗余项的选择可用代数法或卡诺图法。

用增加冗余项的方法修改逻辑设计,可以消除一些竞争冒险现象。但是,这种方法的适用范围是有限的。增加冗余项,需增加额外电路。如果运用得当,可以达到最理想的效果。

例如,对于上述卡诺圈相切的情况,我们只需要再作一个卡诺圈,把相切处包裹进去,这样就新增了一项冗余项,使得 $C=0,A=1$ 时,函数不能化为 $B+B’$,因此可以消除“竞争-冒险”。如图所示。

增加D触发器

利用 D 触发器对输入信号的毛刺不敏感的特点(需要 CLK 边沿触发),去除信号中的毛刺。在实际中,对于简单的逻辑电路,尤其是对信号中发生在非时钟跳变沿的毛刺信号,去除效果非常的明显。

但是如果毛刺信号发生在时钟信号的跳变沿,D 触发器的效果就没有那么明显了。

另外,D 触发器的使用还会给系统带来一定的延时,特别是在系统级数较多的情况下,延时也将变大。因此在使用 D 触发器去除毛刺的时候,一定要视情况而定,并不是所有的毛刺都可以用 D 触发器来消除。

使用可靠的码制

对于一般的二进制或十进制计数器,在计数时,将有多位信号同时跳变。

例如一个 4 bit 二进制计数器,由 ’0101’ 转换为 ’0110’ 时,将产生毛刺。此时,使用格雷码计数器将避免毛刺的出现,因为格雷码计数器的输出每次只有一位跳变(’0111’ -> ’0101’)。

输出端并联电容

竞争冒险所产生的干扰脉冲一般很窄,逻辑电路在较慢速度下工作时,可以在输出端并接一个不大的滤波电容,并用门电路的输出电阻和电容器构成低通滤波电路,对很窄的尖峰脉冲(其频率很高)起到了平波的作用。

接人滤波电容的方法简单易行,但输出电压波形会受到影响,响应速度变慢,故只适用于对输出波形前后沿无严格要求的场合。

引入封锁脉冲

封锁脉冲是在输入信号发生竞争的时间内,引入一个脉冲将可能产生尖峰干扰脉冲的门封锁住,从而消除竞争冒险。

下图是使用低电平脉冲封锁干扰脉冲的示意图。

封锁脉冲应在输入信号转换前到来,转换结束后消失。

增加选通脉冲

选通脉冲是当电路输出端达到新的稳定状态之后,再引入的脉冲,使电路在稳定后才导通,从而使输出信号是正确的逻辑信号而不包含干扰脉冲。

下图是用高电平作为通选脉冲,选择稳定后的数据。

脉冲的宽度和产生的时间同样有严格的要求。

信号同步法

采用同步电路,也可以大大减少毛刺。由于大多数毛刺都比较短(大概几个纳秒),只要毛刺不出现在时钟跳变沿,毛刺信号就不会对系统造成危害了。因此一般认为,只要在整个系统中使用同一个时钟就可以实现系统同步。

但是,时钟信号在 FPGA 器件中传递是有延时的,我们无法预知时钟跳变沿的精确位置。也就是说我们无法保证在某个时钟的跳变沿读取的数据是一个稳定的数据,尤其是在多级设计中,这个问题就更加突出。

因此,做到真正的"同步"就是去除毛刺信号的关键问题。而同步的关键就是保证在时钟的跳变沿读取的数据是稳定的,而不是毛刺数据。以下为两种具体的信号同步方法。

信号延迟同步法

这种方法的原理就是在两级信号传递的过程中加一个延时环节,从而保证在下一个模块中读取到的数据是稳定后的数据,即不包含毛刺信号。这里所指的信号延时可以是数据信号的延时,也可以是时钟信号的延时。

状态机控制

在数据传递比较复杂的多模块系统中,由状态机在特定的时刻分别发出控制特定模块的时钟信号或者模块使能信号,状态机的循环控制就可以使得整个系统协调运作,同时减少毛刺信号。

那么只要我们在状态机的触发时间上加以处理,就可以避免竞争冒险,从而抑制毛刺的产生。

其它的一个例子

下图是数电课本上的一个16进制计数器,在课本较早的印次中,T 触发器是上升沿触发的,即没有“小圈圈”(下图是已经修正的),会产生毛刺现象。

仿真波形如图,可以看到加了 clk1 产生尖刺(为什么是负脉冲尖刺呢,因为仿真软件里的 T触发器是下降沿触发的,只能在时钟信号后边加个反相器):

Multisim 仿真文件下载:十六进制计数器-尖峰.ms14

参考

[1] 数字电路中的竞争冒险以及解决

[2] 组合逻辑电路的竞争冒险现象及消除方法

[3] 数字IC设计八股——组合电路中的竞争与冒险现象、毛刺的出现与解决