当前位置: 首页 > news >正文

【Verilog】竞争、冒险

在数字电路中,信号传输和状态变换会有一定的延时

  • 在组合逻辑电路中,不同路径的输入信号变化传输到同一点门极电路时,在时间上有先有后,这种先后所形成的时间差称为竞争(Competition)
  • 由于竞争的存在,输出信号需要经过一段时间才能达到期望状态,过度时间内可能产生瞬间的错误输出,例如尖峰脉冲,这种现象被称为冒险(Hazard)

竞争不一定有冒险,但冒险一定会有竞争

F=A&A'

由于反相器电路的存在,信号A'传递到与门输入端的时间相对于信号A会滞后,这就可能导致与门最后的输出结果F会出现脉冲干扰

如何判断?

代数法

在逻辑表达式,保持一个变量固定不动,将剩余其他变量用0或1代替,如果最后逻辑表达式能化简成Y=A+A'或Y=A · A'的形式,则可判定此逻辑存在竞争与冒险

卡诺图法

有两个相切的卡诺圈,并且相切处没有其他卡诺圈包围,可能会出现竞争与冒险现象。

例如左下图所存在竞争与冒险,右下图则没有。

    其实,卡诺图本质上还是对逻辑表达式的一个分析,只是可以进行直观的判断。

    例如,左上图逻辑表达式可以简化为 Y = A'B' + AC,当 B=0 且 C=1 时,此逻辑表达式又可以表示为 Y = A' + A。所以肯定会存在竞争与冒险。

    右上图逻辑表达式可以简化为 Y = A'B' + AB,显然 B 无论等于 1 还是 0,此式都不会化简成 Y = A' + A。所以此逻辑不存在竞争与冒险。

      需要注意的是,卡诺图是首尾相临的。如下图所示,虽然看起来两个卡诺圈并没有相切,但实际上,m6 与 m4 也是相邻的,所以下面卡诺图所代表的数字逻辑也会产生竞争与冒险。

      其他较为复杂的情况,可能需要采用 "计算机辅助分析 + 实验" 的方法

      如何消除?

      对数字电路来说,常见的避免竞争与冒险的方法主要有 4 种:

      • 增加滤波电容,滤除窄脉冲
      • 修改逻辑,增加冗余项
      • 使用时钟同步电路,利用触发器进行打拍延迟
      • 采用格雷码计数器

      增加滤波电容,滤除窄脉冲

      在输出端并联一个小电容,将尖峰脉冲的幅度削弱值门电路阈值以下

      此方法简单,但是会增加输出电压的翻转时间,易破坏波形

      修改逻辑,增加冗余项

      利用卡诺图,在两个相切的圆之间,增加一个卡诺图,并加在逻辑表达式之中

      如下图所示,对数字逻辑 Y = A'B' + AC 增加冗余项 B'C,则此电路逻辑可以表示为 Y = A'B' + AC + B'C。此时电路就不会再存在竞争与冒险

      使用时钟同步电路,利用触发器进行打拍延迟

      同步电路信号的变化都发生在时钟边沿。对于触发器的D输入端,只要毛刺不出现在时钟的上升沿并且不满足数据的建立和保持时间,就不会对系统造成危害,因此可认为D触发器的D输入端对毛刺不敏感。利用此特性,在时钟边沿驱动下,对一个组合逻辑信号进行延迟打拍,可消除竞争冒险

      延迟一拍时钟,会一定概率的减少竞争冒险的出现。最安全的打拍延迟周期是3拍。可有效减少竞争冒险的出现;根据自己的设计需求,对信号进行合理的打拍延迟

      module competition_hazard(input clk,input rstn,input en,input din_rvs,output reg flag);wire condition=din_rvs & en;always@(posedge clk or negedge !rstn) beginif(!rstn) beginflag<=1'b0;endelse beginflag<=condition;endend
      endmodule
      'timescale 1ns/1nsmodule test;reg clk,rstn;reg en;reg din_rvs;wire flag_safe,flag_dgs;//clock and rstn generatinginitial beginrstn=1'b0;clk=1'b0;#5 rstn=1'b1;forever begin#5 clk=~clk;endendinitial beginen=1'b0;din_rvs=1'b1;#19 en=1'b1;#1 din_rvs=1'b0;endcompetition_hazard u_dgs(.clk(clk),.rstn(rstn),.en(en),.din_rvs(din_rvs),.flag(flag_dgs));initial beginforever begin#100 if($time>=1000) $finish;endend
      endmodule

      增加打拍延时的逻辑

      module clap_delay(input clk,input rstn,input en,input din_rvs,output reg flag);reg din_rvs_r;reg en_r;always@(posedge clk or !rstn) beginif(!rstn) begindin_rvs_r<=1'b0;en_r<=1'b0;endelse begindin_rvs_r<=din_rvs;en_r<=en;endendwire condition=din_rvs_r & en_r;always@(posedge clk or negedge !rstn) beginif(!rstn) beginflag<=1'b0;endelse beginflag<=condition;endend
      endmodule

      采用格雷码计数器

      递加的多 bit 位计数器,计数值有时候会发生多个 bit 位的跳变。

      例如计数器变量 counter 从 5 计数到 6 时, 对应二进制数字为 4'b101 到 4'b110 的转换。因为各 bit 数据位的延时,counter 的变换过程可能是: 4'b101 -> 4'b111 -> 4'b110。如果有以下逻辑描述,则信号 cout 可能出现短暂的尖峰脉冲,这显然是与设计相悖的

        cout = counter[3:0] == 4'd7 ; 

          而格雷码计数器,计数时相邻的数之间只有一个数据 bit 发生了变化,所以能有效的避免竞争冒险。

          好在 Verilog 设计时,计数器大多都是同步设计。即便计数时存在多个 bit 同时翻转的可能性,但在时钟驱动的触发器作用下,只要信号间满足时序要求,就能消除掉 100% 的竞争与冒险。

          在编程时多注意以下几点,也可以避免大多数的竞争与冒险问题。

          1)时序电路建模时,用非阻塞赋值。

          2)组合逻辑建模时,用阻塞赋值。

          3)在同一个 always 块中建立时序和组合逻辑模型时,用非阻塞赋值。

          4)在同一个 always 块中不要既使用阻塞赋值又使用非阻塞赋值。

          5)不要在多个 always 块中为同一个变量赋值。

          6)避免 latch 产生。

          6.4 Verilog 竞争与冒险 | 菜鸟教程

          http://www.lryc.cn/news/596589.html

          相关文章:

        • 本地大模型VRAM需求计算器:原理与实现详解
        • Web3介绍(Web 3.0)(一种基于区块链技术的去中心化互联网范式,旨在通过技术手段实现用户对数据的自主权、隐私保护和价值共享)
        • 浙江大学PTA程序设计C语言基础编程练习题1-5
        • 高并发场景下的缓存问题与一致性解决方案(技术方案总结)
        • Redis 初识
        • Vue项目中的AJAX请求与跨域问题解析
        • Trae安装指定版本的插件
        • 网络编程---TCP协议
        • 浏览器解码顺序xss
        • Matlab学习笔记:界面使用
        • 基础算法思想(递归篇)
        • Linux Bridge Cost
        • Java常用API(1)
        • csp基础知识——递推
        • 激光雷达-自动驾驶的“三维感知中枢“
        • postgresql导入导出数据;pg_restore: error: did not find magic string in file header
        • 学习pwn需要的基本汇编语言知识
        • 快速了解pandas库
        • Unity之C# 脚本与Unity Visual Scripting 交互
        • 嵌入式开发学习(第三阶段 Linux系统开发)
        • Model Control Protocol 使用MCP进行各种任务适配,调用工具和资源进行客户端开发
        • 基于AD7147电容触摸芯片与STC12C5A60S2单片机方案
        • SQL基础④ | 多表查询篇
        • AG32 mcu+cpld 联合编程(概念及流程)
        • OpenMVG OpenMVS 安装全流程常见问题与解决方法总结
        • 学习软件测试的第十九天
        • imx6ull-系统移植篇18——linux顶层 Makefile(下)
        • API是什么,如何保障API安全?
        • Springboot和postman的使用
        • XSS内容分享