[FPGA 学习记录] 避免latch的产生

避免 latch 的产生

那么在前面几小节当中,我们使用诸多实例,对简单组合逻辑的相关知识做了一个系统性的讲解。我们使用了我们的多路选择器、3-8译码器和半加器,后来我们又通过全加器这个实验工程,为大家讲解了层次化的设计思想。

在前面几小节当中,我们经常会提到一个词就是 latch。那么本小节就是有关 latch 的讲解。

在这一小节我们将会为大家讲解一下:如何避免 latch 的产生。

本小节的主要内容可以分为两个部分:第一部分就是 latch 的简介。在这一部分,我们会对 latch 的相关知识做一个系统性的讲解;在第二部分,我们会讲解几种产生 latch 情况。了解了这几种产生 latch 的情况之后,我们在后面的设计过程中,就可以避免 latch 的产生。


首先,是 latch 的简介

1 latch 的简介

latch 其实就是锁存器。它是一种在异步电路系统中对输入信号电平敏感的单元,可以用来存储信息。那么锁存器在数据未锁存时,输出端的信号随输入信号变化,就像信号通过一个缓冲器一样。但是一旦我们的锁存信号有效时,数据就被锁存,输入信号是不起作用的。因此,锁存器也被称为透明锁存器,它指的是:不锁存时输出对于输入是透明的。

那么以上就是 latch 的概念解析。在这个概念解析当中,我们提到了一个词叫做异步电路。既然提到了异步电路,与它对应的就是同步电路。这两种电路有什么区别呢?我们来比较一下

异步电路与同步电路

异步电路主要是组合逻辑电路,它用于产生 FIFO 或者 RAM 的读写控制信号脉冲。那么FIFO 和 RAM 的相关知识,我们在后面会提到。异步电路同时也可用在时序电路之中,当它使用在时序电路当中时,它是没有统一的时钟的,状态变化的时刻是不稳定的。通常我们的输入信号,只在电路处于稳定状态时才会发生变化。

与异步电路对应的是同步电路,同步电路是由时序电路和组合逻辑电路构成的电路。其中,时序电路它包括寄存器和各种触发器。那么同步电路所有的操作都在严格的时钟控制下完成的,这些时钟电路共享同一个 CLK 就是同一个时钟,所有的状态变化都是在时钟的上升沿或者下降沿完成的。

我们后面所有的设计,都是基于同步电路进行设计的,我们使用的都是触发器。而在异步电路中广泛使用的是我们的 latch,它可以在没有时钟的情况下进行数据的存储,在异步电路中 latch 可以替代寄存器的角色,我们的 latch 只有在组合逻辑中才会产生,它在异步电路中是非常有用的,我们前面已经提到了,它可以替代寄存器进行数据的存储。但是我们在同步电路中,会尽量避免 latch 的产生,在同步电路中 latch 会产生一些不好的效果。

latch 的危害

  • 对毛刺特别敏感
  • 不能异步复位,上电后处于不定态
  • latch 会使我们的静态时序分析变得十分复杂
  • latch 的产生,会占用更多的逻辑资源(在我们 FPGA 的资源中,大部分器件是没有锁存器这个东西的
    所以说 我们需要使用寄存器来组成锁存器)
  • 在我们的 ASIC 设计当中,锁存器会带来额外的延时,这样不利于我们提高系统的工作效率

那么以上就是 latch 的一些危害,所以说我们要避免 latch 的产生。
那么这里,我们列举了几种产生 latch 的情况

2 几种产生 latch 的情况

  1. 第一种是在组合逻辑中 if-else 条件分支语句缺少 else 语句。这种情况下会产生latch

  2. 第二种就是组合逻辑中的 case 条件分支语句条件未完全列举,而且它缺少 default 语句。

    那么这里为什么是 case 条件分支语句条件未完全列举,而且是缺少 default 语句呢?
    如果说我们的 case 条件分支语句条件未完全列举时,我们使用 default 语句,那么未列举的条件就会执行 default 语句。也就是说 default 语句,就是为了解决条件未完全列举这种情况。只有在条件未完全列举时,而且没有 default 语句,才会产生 latch,大家注意下这种情况。

  3. 第三种情况就是:组合逻辑中输出变量赋值给了自己

这里,就列举了三种产生 latch 的情况。

只是理论部分的讲解,那么接下来我们结合实验工程,来具体看一下 latch 的产生。

我们这里,可以使用我们之前编写过的3-8译码器来进行 latch 的验证。

那么怎么打开之前已经建立过的工程呢?我们可以找到它的文件存放位置,然后找到我们的3-8译码器文件夹,找到我们实验工程存放的列表,就是我们的 quartus_prj 打开这个文件夹之后,我们找到后缀是 qpf 的文件,这个就是实验工程的打开文件。我们双击打开实验工程。

kkZsBvwcZH

那么工程打开之后,我们可以找到我们的 Files,在这个位置,就可以直接打开我们的 .v 文件。

因为在之前开发环境的搭建过程中,我们已经将我们的开发软件和我们的编辑器 Notepad++ 相关联了。所以说,在这儿直接双击打开 .v 文件,是通过 Notepad++ 软件打开的,在这儿就可以进行代码的编写和修改

20231027111335_NvE15E84V4

那么首先我们要实现第一种情况:组合逻辑中 if-else 条件分支语句缺少 else 语句。

我们回到我们的 .v 文件,进行代码的修改。首先,先要将 case 条件分支语句进行一个区块注释。选中它点击右键 进行区块注释;然后消除 if-else 条件分支语句的区块注释,在这儿选择清除区块注释

20231027111631_xZ69HPGqBM

在观察 latch 的产生之前,我们先观察一下正常的一个电路。我们首先保存我们的文件,然后回到我们的实验工程进行一下全编译。全编译通过之后,我们可以看到有 8 条警告信息;那么 8 条警告信息可以通过这儿查看。我们先来查看一下严重警告,那么这个位置就是提示我们引脚的问题,后面是提示我们未找到 SDC 文件。那么下面看一下 5 个警告,那么第一条还是引脚的问题;那么剩下 4 条提示我们的是:我们的设计当中没有定义时钟。那么这儿一共是 8 条警告信息

20231027111912_erLXqzVqoi

接下来,看一下 RTL 视图。

那么这儿显示的是一个3-8译码器的正确的一个 RTL 视图。那么这儿是 8 个比较器,因为我们的 .v 文件,括号里有 8 个判断,就是生成了 8 个比较器。那么后面就是产生了几个多路选择器。这个是没有产生 latch 的 RTL 视图

20231027112114_5PwnZlyesM

接下来进行代码的更改:我们将 if-else 条件分支语句当中的 else 语句进行一个注释,使用双斜线进行一个单行的注释。这儿大家也可以使用快捷方式进行代码的注释,可以直接选中需要注释的位置
然后点击右键 添加/删除单行注释 就可以添加单行的注释

20231027112407_OB1ThWuodr

如果说已经添加了注释之后,再次选中它们点击右键,点击 添加/删除单行注释 就会删除单行注释。我们这儿对 else 语句进行注释,注释完成之后一定要保存

20231027112527_4go5XHMcQN

代码修改完成之后回到我们的实验工程,再次进行一个全编译。编译完成之后,我们可以看到有 9 条警告信息,比原来的 8 条多了一条,我们点击 OK

20231027112719_mEFZNrMUxS

多的一条警告信息是普通的警告,我们来查看一下。那么多出的一条警告信息是这一条,警告信息告诉我们:输出的 out 信号,产生了一个 latch 锁存器,它会在一条或者多条路径下对先前的一个值,进行一个锁存

20231027112842_d41GQTfhjy

如果说 latch 是我们故意产生的,可以忽略。如果说 latch 是因为我们编写的代码不够严谨而产生的,就需要进行修改。

了解完报错信息之后,我们打开我们的 RTL 视图。

在这里我们可以看到,RTL 视图与原来的 RTL 视图有了很大的区别,而且它产生了好多 latch,产生了 8 个 latch。我们任选一个,选中它进行放大,可以看一下

20231027113009_IpvRkW9KOi

那么这儿就产生了一个 latch 的锁存器
在刚才的实验当中,我们重现了 latch 的第一种产生情况。

那么 latch 的第二种产生情况是:组合逻辑中 case 条件分支语句条件未完全列举,且缺少 default 语句。接下来我们通过实验,观察一下第二条 latch 的产生情况
回到我们的实验工程,打开我们的 .v 文件。首先是清除 else 语句中的单行注释,然后,将整个 if-else 语句进行一个区块注释;然后,清除 case 条件分支语句的区块注释,然后 保存

20231027113248_eMjewVY0X4

我们先来看一下,没有产生 latch 情况下的 case 条件分支语句它的 RTL 视图。保存之后回到实验工程,进行一个全编译,那么编译完成,同样是有 8 个警告信息,我们点击 OK

20231027113351_AlCYKf3nRM

查看一下 RTL 视图。case 条件分支语句,它的 RTL 视图就是一个译码器

image-20231027113508269

我们回到我们的 .v 文件,然后将 case 条件分支语句中的最后一个条件和 default 进行一个注释,然后 保存

20231027113559_tvR9aLTsVT

回到实验工程进行全编译。那么编译完成之后有 27 个警告,我们点击 OK

20231027113805_vL2J2mVMKw

查看我们的警告信息发现:很多的警告信息,都是因为产生了一个 latch

我们来看一下 RTL 视图。case 条件分支语句的 RTL 视图,发生了很明显的变化,而且增加了很多个 latch

20231027113923_Vg0yQJp6SI

在刚刚的实验当中,我们再现了第二条 latch 产生的情况。

接下来是 latch 的第三种产生情况:在组合逻辑中将输出变量赋值给自己。

我们回到我们的 .v 文件,这儿取消对 case 条件分支语句的注释,然后对最后一个条件的执行语句进行一个更改,将输出变量赋值给自己,然后保存

20231027125438_pYQt1XsRoK

回到实验工程,重新进行全编译。我们的代码在每次修改完成之后,都要进行重新的编译。那么编译完成有 26 个警告信息,我们来查看一下

20231027125537_duVQ6tewUj

那么大部分的警告,都是因为 latch 的产生
我们来看一下 RTL 视图。

在 RTL 视图当中,同样可以看到 latch

image-20231027130036328

再次回到我们的 .v 文件,撤销之前的修改,可以使用我们的快捷键 Ctrl+Z。然后对 case 条件分支语句进行一个区块注释,然后清除 if-else 语句的注释。同样的对代码进行一个修改,将 else 的赋值语句它的输出变量赋给自己,然后保存

20231027130213_l11emuWbDI

回到我们的实验工程,进行全编译。这儿有 9 个警告信息,我们来看一下

20231027130322_sqM95MQPxh

那么第一条警告信息,还是因为 latch 的产生。

我们接着查看 RTL 视图

image-20231027130550512

如果在 if-else 条件分支语句中,将输出变量赋值给自己,同样会产生 latch。

刚刚我们再现了第三种 latch 产生的情况。

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


参考资料:

8. 避免Latch的产生

11-第十讲-避免latch的产生

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值