Verilog 避免 Latch

关键词:触发器,锁存器

Latch 的含义

锁存器(Latch),是电平触发的存储单元,数据存储的动作取决于输入时钟(或者使能)信号的电平值。仅当锁存器处于使能状态时,输出才会随着数据输入发生变化。

当电平信号无效时,输出信号随输入信号变化,就像通过了缓冲器;当电平有效时,输出信号被锁存。激励信号的任何变化,都将直接引起锁存器输出状态的改变,很有可能会因为瞬态特性不稳定而产生振荡现象。

锁存器示意图如下:

触发器(flip-flop),是边沿敏感的存储单元,数据存储的动作(状态转换)由某一信号的上升沿或者下降沿进行同步的(限制存储单元状态转换在一个很短的时间内)。

触发器示意图如下:

寄存器(register),在 Verilog 中用来暂时存放参与运算的数据和运算结果的变量。一个变量声明为寄存器时,它既可以被综合成触发器,也可能被综合成 Latch,甚至是 wire 型变量。但是大多数情况下我们希望它被综合成触发器,但是有时候由于代码书写问题,它会被综合成不期望的 Latch 结构。

Latch 的主要危害有:

  • 1)输入状态可能多次变化,容易产生毛刺,增加了下一级电路的不确定性;
  • 2)在大部分 FPGA 的资源中,可能需要比触发器更多的资源去实现 Latch 结构;
  • 3)锁存器的出现使得静态时序分析变得更加复杂。

Latch 多用于门控时钟(clock gating)的控制,一般设计时,我们应当避免 Latch 的产生。

if 结构不完整

组合逻辑中,不完整的 if - else 结构,会产生 latch。

例如下面的模型,if 语句中缺少 else 结构,系统默认 else 的分支下寄存器 q 的值保持不变,即具有存储数据的功能,所以寄存器 q 会被综合成 latch 结构。

实例

module module1_latch1(
    input       data,
    input       en ,
    output reg  q) ;
   
    always @(*) begin
        if (en) q = data ;
    end

endmodule

避免此类 latch 的方法主要有 2 种,一种是补全 if-else 结构,或者对信号赋初值。

例如,上面模型中的always语句,可以改为以下两种形式:

实例

// 补全条件分支结构    
    always @(*) begin
        if (en)  q = data ;
        else     q = 1'b0 ;
    end

//赋初值
    always @(*) begin
        q = 1'b0 ;
        if (en) q = data ; //如果en有效,改写q的值,否则q会保持为0
    end

但是在时序逻辑中,不完整的 if - else 结构,不会产生 latch,例如下面模型。

这是因为,q 寄存器具有存储功能,且其值在时钟的边沿下才会改变,这正是触发器的特性。

实例

module module1_ff(
    input       clk ,
    input       data,
    input       en ,
    output reg  q) ;
   
    always @(posedge clk) begin
        if (en) q <= data ;
    end

endmodule

在组合逻辑中,当条件语句中有很多条赋值语句时,每个分支条件下赋值语句的不完整也是会产生 latch。

其实对每个信号的逻辑拆分来看,这也相当于是 if-else 结构不完整,相关寄存器信号缺少在其他条件下的赋值行为。例如:

实例

module module1_latch11(
    input       data1,
    input       data2,
    input       en ,
    output reg  q1 ,
    output reg  q2) ;
   
    always @(*) begin
        if (en)   q1 = data1 ;
        else      q2 = data2 ;
    end

endmodule

这种情况也可以通过补充完整赋值语句或赋初值来避免 latch。例如:

实例

always @(*) begin
        //q1 = 0; q2 = 0 ; //或在这里对 q1/q2 赋初值
        if (en)  begin
            q1 = data1 ;
            q2 = 1'b0 ;
        end
        else begin
            q1 = 1'b0 ;
            q2 = data2 ;
        end
    end

case 结构不完整

case 语句产生 Latch 的原理几乎和 if 语句一致。在组合逻辑中,当 case 选项列表不全且没有加 default 关键字,或有多个赋值语句不完整时,也会产生 Latch。例如:

实例

module module1_latch2(
    input       data1,
    input       data2,
    input [1:0] sel ,
    output reg  q ) ;
   
    always @(*) begin
        case(sel)
            2'b00:  q = data1 ;
            2'b01:  q = data2 ;
        endcase
    end

endmodule

当然,消除此种 latch 的方法也是 2 种,将 case 选项列表补充完整,或对信号赋初值。

补充完整 case 选项列表时,可以罗列所有的选项结果,也可以用 default 关键字来代替其他选项结果。

例如,上述 always 语句有以下 2 种修改方式。

实例

always @(*) begin
        case(sel)
            2'b00:    q = data1 ;
            2'b01:    q = data2 ;
            default:  q = 1'b0 ;
        endcase
    end

always @(*) begin
        case(sel)
            2'b00:  q = data1 ;
            2'b01:  q = data2 ;
            2'b10, 2'b11 :  
                    q = 1'b0 ;
        endcase
    end

原信号赋值或判断

在组合逻辑中,如果一个信号的赋值源头有其信号本身,或者判断条件中有其信号本身的逻辑,则也会产生 latch。因为此时信号也需要具有存储功能,但是没有时钟驱动。此类问题在 if 语句、case 语句、问号表达式中都可能出现,例如:

实例

//signal itself as a part of condition
    reg a, b ;
    always @(*) begin
        if (a & b)  a = 1'b1 ;   //a -> latch
        else a = 1'b0 ;
    end
   
    //signal itself are the assigment source
    reg        c;
    wire [1:0] sel ;
    always @(*) begin
        case(sel)
            2'b00:    c = c ;    //c -> latch
            2'b01:    c = 1'b1 ;
            default:  c = 1'b0 ;
        endcase
    end

//signal itself as a part of condition in "? expression"
    wire      d, sel2;
    assign    d =  (sel2 && d) ? 1'b0 : 1'b1 ;  //d -> latch

避免此类 Latch 的方法,就只有一种,即在组合逻辑中避免这种写法,信号不要给信号自己赋值,且不要用赋值信号本身参与判断条件逻辑。

例如,如果不要求立刻输出,可以将信号进行一个时钟周期的延时再进行相关逻辑的组合。上述第一个产生 Latch 的代码可以描述为:

实例

reg   a, b ;
    reg   a_r ;
   
    always (@posedge clk)
        a_r  <= a ;
       
    always @(*) begin
        if (a_r & b)  a = 1'b1 ;   //there is no latch
        else a = 1'b0 ;
    end

敏感信号列表不完整

如果组合逻辑中 always@() 块内敏感列表没有列全,该触发的时候没有触发,那么相关寄存器还是会保存之前的输出结果,因而会生成锁存器。

这种情况,把敏感信号补全或者直接用 always@(*) 即可消除 latch。

小结

总之,为避免 latch 的产生,在组合逻辑中,需要注意以下几点:

  • 1)if-else 或 case 语句,结构一定要完整
  • 2)不要将赋值信号放在赋值源头,或条件判断中
  • 3)敏感信号列表建议多用 always@(*)

Verilog 避免 Latch相关推荐

  1. Verilog如何避免Latch

    锁存器(Latch)产生的原因: 目录 1.if结构不完整 2.case结构不完整 3.敏感信号列表不完整 Latch的危害: 输入状态可能多次变化,容易在输入信号产生毛刺,会增加电路的不稳定性: 使 ...

  2. Verilog十大基本功8 (flipflop和latch以及register的区别)

    Verilog十大基本功8 (flipflop和latch以及register的区别) 来自1:https://www.cnblogs.com/LNAmp/p/3295441.html 第一次接触La ...

  3. 11.Verilog中如何避免Latch

    FPGA教程目录 MATLAB教程目录 -------------------------------------------------------------------------------- ...

  4. 【Verilog基础】锁存器(Latch)知识点总结

    文章目录 一.Latch 是什么 二.Latch 的危害 三.几种产生 Latch 的情况 情况一: 组合逻辑中 if 语句没有 else 情况二: 组合逻辑中 case 的条件不能够完全列举且不写 ...

  5. 【FPGA】Verilog:锁存器 Latch | RS Flip-Flop 与 D Flip-Flop 的实现

  6. HDLBits 系列(14) Latch and Dff and Edge detect

    目录 D Latch DFF + GATE Mux + DFF MUX2 + DFF FSM JK 触发器 Edgedetect(边沿检测) 双边沿检测 D Latch Implement the f ...

  7. 【Verilog HDL 训练】第 05 天(序列检测)

    1. dff和latch有什么区别. 锁存器是一种对脉冲电平(也就是0或者1)敏感的存储单元电路,而触发器是一种对脉冲边沿(即上升沿或者下降沿)敏感的存储电路. "触发器" 泛指一 ...

  8. Verilog 流水线加法器

    <数字系统设计与Verilog HDL>上面有这么一段代码,用于实现8位4级流水线加法器. module adder8pip(cout,sum,cin,ina,inb,clk );inpu ...

  9. FPGA 中的latch 锁存器

    一直都知道fpga中有latch这么一回事,但是一直都不太清楚到底什么是锁存器,它是怎么产生的,它到底和寄存器有多少区别,它怎么消除.为什么说他不好? 一,是什么 锁存器是一种在异步时序电路系统中,对 ...

  10. Verilog 中 wire 和 reg 数据类型区别

    两者差别很大,完全不能取消. 在Verilog中,wire永远是wire,就是相当于一条连线,用来连接电路,不能存储数据,无驱动能力,是组合逻辑,只能在assign左侧赋值,不能在always @ 中 ...

最新文章

  1. 机器学习的9个基础概念和10种基本算法总结
  2. 2010年上半年计算机专业技术资格考试工作安排
  3. 2019 年,容器技术生态会发生些什么?
  4. 【我们都爱Paul Hegarty】斯坦福IOS8公开课个人笔记32 NSNotification
  5. table中tr使用toggle不好,选择换一张方式
  6. 《走遍中国》珍藏版(七)
  7. 计算机图形学笔记(第二周)
  8. 如何在 Ubuntu 上安装 MongoDB
  9. LeetCode 198. 打家劫舍
  10. java使用poi导出excel 包括多个工作簿
  11. 技术博客|第13期:Server Side Logging:Hulu推荐系统中的特征漂移问题解决方法
  12. 明日之后、“吃鸡”为何成为爆款手游?我们帮你分析了10000条快手广告
  13. iosetup mysql_InnoDB: Error: io_setup() failed with EAGAIN
  14. 手写数字识别--Android Studio 加载tensorflow模型
  15. 常用的图像特征提取方法
  16. 用u盘重装微软官方win10专业版--详细操作文档
  17. VSCode全配置(c++、unity、html...等配置和好用设置,持续更新)
  18. 解决p标签自动换行文字两端不对齐问题
  19. HTML+CSS写个人简历
  20. 基于STM32的电阻、电容测量(NE555芯片RC振荡法)

热门文章

  1. jQuery实现雪花飘落效果
  2. 中原银行校招笔试c语言,中原银行校招很难吗?笔试都考什么?
  3. 统计量 估计量 概念
  4. 【HMS core】【Ads Kit】华为广告——海外应用在国内测试正式广告无法展示
  5. 毛笔书法艺术作品,能不能写简化字?
  6. 洛谷 4238 【模板】多项式求逆
  7. ue4 vr连接_基于UE4的VR项目基础环境配置和Motion Controller控制配置
  8. F28335舵机控制器(3)——第三版PCB
  9. 实验二 数字类型及其操作(新)
  10. Android图片压缩——Luban鲁班压缩