避免 Latch 的产生

避免 Latch 的产生

一、前言

本文主要简单讲解Latch的概念、产生的原因、危害以及如何避免其产生。目的是帮初学者在设计数字电路时更加规范,避免因Latch导致的不可预测问题。

二、Latch是什么

Latch其实就是锁存器,是一种在异步电路中,对输入信号电平敏感的单元,用来存储信息。它的特点是当锁存信号无效时,输出信号会随输入信号变化,这时锁存器就像是一个缓冲器。当锁存信号有效时,输入信号被锁存,输出信号保持不变,输入信号的变化不再影响输出。因此Latch也被称为透明锁存器,因为当锁存信号无效时,输出对输入是“透明”的。

三、Latch的危害

需要注意的是,Latch的问题只会出现在组合逻辑中,在同步电路中应尽量避免产生Latch,但并不表示Latch是完全没有用的,Latch在异步电路中是非常有用的。

在同步电路中Latch会产生不好的效果,容易受到毛刺的影响,导致输出不稳定;不能进行异步复位,上电后初始状态不确定;会使静态时序分析变得复杂,增加设计难度和验证的难度;占用过多的FPGA资源,引入额外的时序问题,不利于提高系统的工作频率。

四、几种产生Latch的情况

同步电路设计中,以下几种情况会产生Latch,需要避免。

情况一:组合逻辑中if语句没有else

`timescale 1ns/1ns

module latch_one

(

input wire in1 , //输入信号in1

input wire in2 , //输入信号in2

input wire in3 , //输入信号in3

output reg [7:0] out //输出信号out

);

//out:根据3个输入信号选择输出对应的8bit out 信号

always@(*)

if({in1, in2, in3} == 3'b000)

out = 8'b0000_0001;

else if({in1, in2, in3} == 3'b001)

out = 8'b0000_0010;

else if({in1, in2, in3} == 3'b010)

out = 8'b0000_0100;

else if({in1, in2, in3} == 3'b011)

out = 8'b0000_1000;

else if({in1, in2, in3} == 3'b100)

out = 8'b0001_0000;

else if({in1, in2, in3} == 3'b101)

out = 8'b0010_0000;

else if({in1, in2, in3} == 3'b110)

out = 8'b0100_0000;

else if({in1, in2, in3} == 3'b111)

out = 8'b1000_0000;

// else 把最后一个if的else注释,观察综合后结果

// out = 8'b0000_0001;

endmodule

图1 RTL视图(一)

根据上边的代码综合出来的RTL视图如图1所示,我们可以看到红色框中的Latch锁存器。

情况二:组合逻辑中case的条件不能够完全列举且不写default

`timescale 1ns / 1ps

module latch_two

(

input wire in1 , //输入信号in1

input wire in2 , //输入信号in2

input wire in3 , //输入信号in2

output reg [7:0] out //输出信号out

);

//out:根据 3 个输入信号选择输出对应的 8bit out 信号

always@(*)

case({in1, in2, in3})

3'b000 : out = 8'b0000_0001;

3'b001 : out = 8'b0000_0010;

3'b010 : out = 8'b0000_0100;

3'b011 : out = 8'b0000_1000;

3'b100 : out = 8'b0001_0000;

3'b101 : out = 8'b0010_0000;

3'b110 : out = 8'b0100_0000;

//把最后一种情况和 default 都注释掉,使 case 的条件不能够完全列举

// 3'b111 : out = 8'b1000_0000;

// default: out = 8'b1000_0001;

endcase

endmodule

图2 RTL视图(二)

根据上边的代码综合出来的RTL视图如图2所示,我们可以看到红色框中的Latch锁存器。

情况三:组合逻辑中输出变量赋值给自己(一)

`timescale 1ns / 1ps

module latch_three(

input wire in1 , //输入信号 in1

input wire in2 , //输入信号 in2

input wire in3 , //输入信号 in3

output reg [7:0] out //输出信号 out

);

//out:根据 3 个输入信号选择输出对应的 8bit out 信号

always@(*)

if({in1, in2, in3} == 3'b000)

out = 8'b0000_0001;

else if({in1, in2, in3} == 3'b001)

out = 8'b0000_0010;

else if({in1, in2, in3} == 3'b010)

out = 8'b0000_0100;

else if({in1, in2, in3} == 3'b011)

out = 8'b0000_1000;

else if({in1, in2, in3} == 3'b100)

out = 8'b0001_0000;

else if({in1, in2, in3} == 3'b101)

out = 8'b0010_0000;

else if({in1, in2, in3} == 3'b110)

out = 8'b0100_0000;

else if({in1, in2, in3} == 3'b111)

out = 8'b1000_0000;

else

out = out; //在else中将输出变量赋值给自己

endmodule

图3 RTL视图(三)

根据上边的代码综合出来的RTL视图如图3所示,我们可以看到红色框中的Latch锁存器。

情况四:组合逻辑中输出变量赋值给自己(二)

`timescale 1ns / 1ps

module latch_three(

input wire in1 , ///输入信号 in1

input wire in2 , ///输入信号 in2

input wire in3 , ///输入信号 in3

output reg [7:0] out //输出信号 out

);

//out:根据 3 个输入信号选择输出对应的 8bit out 信号

always@(*)

case({in1, in2, in3})

3'b000 : out = 8'b0000_0001;

3'b001 : out = 8'b0000_0010;

3'b010 : out = 8'b0000_0100;

3'b011 : out = 8'b0000_1000;

3'b100 : out = 8'b0001_0000;

3'b101 : out = 8'b0010_0000;

3'b110 : out = 8'b0100_0000;

3'b111 : out = out; //输出变量赋值给自己

default: out = 8'b0000_0001;

endcase

endmodule

图4 RTL视图(四)

根据上边的代码综合出来的RTL视图如图4所示,我们可以看到红色框中的Latch锁存器。

五、总结

在组合逻辑中一定要避免输出信号处于不定的状态,一定要让输出无论在任何条件下都有一个已知的状态,就可以避免Latch的产生。

相关推荐

滴滴公司注册地在哪里
上海365彩票

滴滴公司注册地在哪里

📅 06-28 👁️ 9534
国服英雄联盟退款攻略,让你轻松解决退款问题!
阴阳师姑获鸟和白狼哪个好 哪个更强对比介绍
《守望先锋 2》玩家揭晓哪个“一招”英雄最难玩
汉语人称代词
上海365彩票

汉语人称代词

📅 07-13 👁️ 2881
小米平板2续航如何?(全天候电量支持,轻松满足你的需求)