二、8【FPGA】Verilog中锁存器(Latch)原理、危害及避免
前言
学习说明此文档为本人的学习笔记,对一下资料进行总结,并添加了自己的理解。
一、基本概念
如果拿到了数字电路技术基础的书,翻开书本的目录你会发现,关于锁存器的章节与内容非常少,也就是在触发器前面有一小节进行了简单说明。但是真的就这么简单么?
答案是否定的。
在组合逻辑电路与时序逻辑电路中间夹了一章触发器,而触发器作为了时序逻辑电路的基本构成单元,而锁存器是构成触发器的基本结构(却不是时序逻辑电路的构成单元),但是锁存器又是通过组合电路得来的(锁存器严格来说属于组合逻辑电路)。
上面那个问题的答案解释呼之欲出,锁存器不就是组合逻辑电路与时序电路的桥梁么?人们发现了锁存器才进一步有了触发器(由于锁存器有触发器的储存特性,有的教材也将其归为触发器,我认为这样是不合理的),进而才有了时序逻辑电路。
1、组合逻辑电路与时序逻辑电路
数字电子技术基础主要分为组合逻辑电路与时序逻辑电路
组合逻辑电路:由门电路组成,其某一时刻的输出状态只与该时刻的输入状态有关,而与电路原来的状态无关,并没有记忆功能。
时序逻辑电路:由锁存器、触发器和寄存器等单元组成,其某一时刻的输出状态不仅与该时刻的输入状态有关,而且与电路原来的状态有关,具有记忆功能。
2、基本逻辑储存单元
(1)锁存器(latch)
锁存器(latch)是一种在异步电路系统中,对输入信号电平敏感的单元,用来存储信息。锁存器在数据未锁存时,输出端的信号随输入信号变化,此时信号通过锁存器就相当于通过了一个缓存器,一旦锁存信号有效,则数据被锁存,输入信号不起作用。因此锁存器也被称为透明锁存器,指的是不锁存时输出对于输入是透明的。
《数字电子技术基础》上的SR锁存器的定义:
SR锁存器实际上是一个组合逻辑电路,在时序分析时模型就等效为两个各组合电路互为反馈的反馈系统,因此,系统有可能会因为瞬态特性不稳定而产生振荡现象。
(2)触发器(flip-flop)
触发器分为电平触发、脉冲触发、边沿触发。触发器是构成时序逻辑电路的基本单元,能够存储1位二值信号的基本单元电路统称触发器(Flip-Flop)。为实现记忆1位二值信号功能,触发器具备以下两个基本特点:具有两个能自行保持的稳定状态,用来表示逻辑状态0和1。在触发信号的操作下,根据输入信号可以将触发器置为0或1。
可以清楚的看到相对于SR锁存器,SR触发器增加了CLK触发端,这样就能够在时序电路中通过控制CLK端来控制SR触发器,而在时序电路中SR锁存器只有在时钟平稳时才可以控制。
(3)寄存器(register)
寄存器(register)用来暂时存放参与运算的数据和运算结果。在实际的数字系统中,通常把能够用来存储一组二进制代码的同步时序逻辑电路称为寄存器。
区别与联系:由于触发器内有记忆功能,因此利用触发器可以方便地构成寄存器。由于一个触发器能够存储一位二进制码,所以把 n 个触发器的时钟端口连接起来就能构成一个存储 n 位二进制码的寄存器。
从寄存数据的角度来讲,寄存器和锁存器的功能是相同的;它们的区别在于寄存器是同步时钟控制,而锁存器是电位信号控制。 一般的设计规则是:在绝大多数设计中避免产生锁存器。它会让您设计的时序完蛋,并且它的隐蔽性很强,非老手不能查出。
3、异步电路与同步电路
异步电路:异步电路主要是组合逻辑电路,用于产生FIFO或RAM的读写控制信号脉冲,但它同时也用在时序电路中,此时它没有统一的时钟,状态变化的时刻是不稳定的,通常输入信号只在电路处于稳定状态时才发生变化。
同步电路:同步电路是由时序电路(寄存器和各种触发器)和组合逻辑电路构成的电路,其所有操作都是在严格的时钟控制下完成的。这些时序电路共享同一个CLK,而所有的状态变化都是在时钟的上升沿(或下降沿)完成的。
二、锁存器(Latch)
1、Latch
在进行FPGA开发的过程中,经常会在编译程序时发现有一些warning提示生成了一些latch,而且一般FPGA的设计规则也不建议有latch生成。在Verilog对FPGA开发时,有时语法正确的代码不一定电路就是合理的。
当你在FPGA开发时想组合出纯组合逻辑电路(没有时钟控制端),但有时候你的代码最后综合出的结果却是“组合逻辑电路+锁存器(触发器)”。这说明在你的Verilog代码中有保持不变的情况,这种“保持输出不变”的行为意味着需要记住当前的状态,由于组合逻辑中的门电路是无法储存状态的,此时代码综合后就会产生锁存器(Latch),来储存产生的状态。这就是组合逻辑中产生Latch的主要原因。
在组合逻辑电路中产生的Latch,在同步电路中尽量避免,但并不表示没用或者是错误的,Latch在异步电路中是非常有用的,只是我们设计的是同步电路,要尽量避免。
2、Latch的特点及危害
(1)对毛刺敏感
使能信号有效时,输出状态可能随输入多次变化,产生空翻,对下一级电路很危险,不能异步复位,因此在上电后处于不确定的状态。并且其隐蔽性很强,不易查出。因此,在设计中,应尽量避免latch的使用。
(2)不能异步复位
由于其能够储存上次状态的原因,上电后Latch处于不定态。
(3)复杂的静态时序电路分析
首先,锁存器没有时钟信号参与信号传递,无法做STA;其次,综合工具会将 latch 优化掉,造成前后仿真结果不一致。
(4)占用更多资源
在FPGA中基本的单元是由查找表和触发器组成的,大部分器件没有锁存器这个东西,若生成锁存器反而需要更多的资源。(不同的观点:当然,目前网上还有一种说法是FPGA中只有LUT和FF的资源,没有现成的Latch,所以如果要用Latch,需要更多的资源来搭出来。但这一观点,是错误的!!——因为每一个slice包含FF和latch通用的资源。)
(5)额外的延时
在ASIC设计中,锁存器也会带来额外的延时和DFT,并不利于提高系统的工作频率。
(6)锁存器的优点
如果锁存器和触发器两者都由与非门搭建的话,锁存器耗用的逻辑资源要比D触发器少(D触发器需要12个MOS管,锁存器只需6个MOS管),锁存器的集成度更高,所以在ASIC设计中会用到锁存器,且只有在CPU高速电路或者RAM这种面积很敏感的电路才使用锁存器。
综上所述
根据锁存器的特点可以看出,在电路设计中,要对锁存器特别谨慎,如果设计经过综合后产生出和设计意图不一致的锁存器,则将导致设计错误,包括仿真和综合。因此,在设计中需要避免产生意想不到的锁存器。如果组合逻辑的语句完全不使用 always 语句块,就可以保证综合器不会综合出锁存器。虽然在的ASIC设计中会用到锁存器。但锁存器对毛刺敏感,无异步复位端,不能让芯片在上电时 处在确定的状态;另外,锁存器会使静态时序分析变得很复杂,不利于设计的可重用。
3、Latch的产生情况及避免
Latch一般产生在组合逻辑电路的always中,主要有三种情况:
(1)组合逻辑中if语句中没有else
module decoder3_8(input wire in_1,input wire in_2,input wire in_3,output reg [7:0] out );//情况一:组合逻辑中if语句中没有elsealways@(*) if( {in_1, in_2, in_3} == 3'b000 )out = 8'b0000_0001; else if({in_1, in_2, in_3} == 3'b001)out = 8'b0000_0010;else if({in_1, in_2, in_3} == 3'b010) out = 8'b0000_0100;else if({in_1, in_2, in_3} == 3'b011) out = 8'b0000_1000;else if({in_1, in_2, in_3} == 3'b100) out = 8'b0001_0000;else if({in_1, in_2, in_3} == 3'b101) out = 8'b0010_0000;else if({in_1, in_2, in_3} == 3'b110) out = 8'b0100_0000;else if({in_1, in_2, in_3} == 3'b111) out = 8'b1000_0000;// else //去除esle产生latch(锁存器) // out = 8'b0000_0001;
endmodule
如图进行RTL代码逻辑综合后出现了latch
(2)组合逻辑中case的条件不能够完全列举且没有default
module decoder3_8(input wire in_1,input wire in_2,input wire in_3,output reg [7:0] out );always@(*)case ({in_1, in_2, in_3})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 = 8'b1000_0000; // default : out = 8'b0000_0001; //latch的产生endcaseendmodule
RTL代码逻辑综合后产生latch
(3)组合逻辑中输出变量赋值给自己
module decoder3_8(input wire in_1,input wire in_2,input wire in_3,output reg [7:0] out );
//情况三:组合逻辑中输出变量赋值给自己(一)always@(*) if( {in_1, in_2, in_3} == 3'b000 )out = 8'b0000_0001; else if({in_1, in_2, in_3} == 3'b001)out = 8'b0000_0010;else if({in_1, in_2, in_3} == 3'b010) out = 8'b0000_0100;else if({in_1, in_2, in_3} == 3'b011) out = 8'b0000_1000;else if({in_1, in_2, in_3} == 3'b100) out = 8'b0001_0000;else if({in_1, in_2, in_3} == 3'b101) out = 8'b0010_0000;else if({in_1, in_2, in_3} == 3'b110) out = 8'b0100_0000;else if({in_1, in_2, in_3} == 3'b111) out = 8'b1000_0000;else out = out; //产生latch(锁存器)
endmodule
module decoder3_8(input wire in_1,input wire in_2,input wire in_3,output reg [7:0] out );
//情况三:组合逻辑中输出变量赋值给自己(二) always@(*)case ({in_1, in_2, in_3})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; //latch的产生 default : out = 8'b0000_0001; endcase
endmodule
综上所述:
在组合逻辑电路的always中,if-else语句中不能缺少else;case语句中条件不能够完全列举或缺少default;在if-else和case中均不能出现变量自己将值赋给自己。
本文档参考资料
学习视频:是根据野火FPGA视频教程——第十讲
https://www.bilibili.com/video/BV1nQ4y1Z7zN?p=3
学习资料:《数字电子技术基础》清华大学出版社,请参考本人的学习笔记专栏:
https://blog.csdn.net/arm_qiao/category_11744079.htmlhttps://blog.csdn.net/arm_qiao/category_11744079.html《Verilog HDL数字设计与综合》第二版
参考文章:
http://t.csdn.cn/jyTNF、http://t.csdn.cn/MBORd、http://t.csdn.cn/k6HTQ
二、8【FPGA】Verilog中锁存器(Latch)原理、危害及避免相关推荐
- 【FPGA】Verilog:锁存器 Latch | RS Flip-Flop 与 D Flip-Flop 的实现
- Verilog中的二维数组及其初始化
Verilog中的二维数组 Verilog中提供了两维数组来帮助我们建立内存的行为模型.具体来说,就是可以将内存宣称为一个reg类型的数组,这个数组中的任何一个单元都可以通过一个下标去访问.这样的数组 ...
- 产品工作中的金字塔原理
本文有PMCAFF 原创作者 咸鱼 原创发布于pmcaff.com 金字塔原理是国外一个慈祥的老太太(巴巴拉·明托)提出的一个方法论,主要是帮助我们清晰的思考.表达和写作的思维方式. 一. 什么是金字 ...
- FPGA 中的latch 锁存器
一直都知道fpga中有latch这么一回事,但是一直都不太清楚到底什么是锁存器,它是怎么产生的,它到底和寄存器有多少区别,它怎么消除.为什么说他不好? 一,是什么 锁存器是一种在异步时序电路系统中,对 ...
- FPGA基础知识极简教程(5)什么是锁存器以及如何在FPGA开发中避免生成锁存器?
博文目录 写在前面 正文 什么是D锁存器? 锁存器是如何生成的? 如何避免生成锁存器? 参考资料 交个朋友 写在前面 个人微信公众号: FPGA LAB 个人博客首页 注:学习交流使用! 本文我们将讨 ...
- FPGA verilog HDL实现中值滤波
FPGA verilog HDL实现中值滤波 今天给大侠简单带来FPGA verilog HDL实现中值滤波,话不多说,上货. 一.实现步骤: 1.查看了中值滤波实现相关的网站和paper: 2.按照 ...
- FPGA的设计艺术(18)如何使用Verilog中的数组对存储器进行建模?
前言 Verilog中的二维数组很有用,可以使用for以及generate for配合二维数组进行使用,可以代替大量寄存器的场合,其实大量同类寄存器可以使用存储器进行代替,Verilog中可以使用二维 ...
- FPGA之道(37)Verilog中的编写注意事项
文章目录 前言 Verilog中的编写注意事项 大小写敏感 Verilog中的关键字 范围定义的正确使用 不要省略begin与end 注释中斜杠的方向 编译指令中的前导符号 混用阻塞和非阻塞赋值的危害 ...
- FPGA之道(36)Verilog中的编译指令
文章目录 前言 Verilog中的编译指令 define指令 timescale指令 inlcude指令 前言 本文摘自<FPGA之道>,一起来了解下Verilog中的编译指令. Veri ...
- FPGA之道(35)Verilog中的并行与串行语句
文章目录 前言 Verilog的并行语句 Verilog连续赋值语句 普通连续赋值语句 条件连续赋值语句 Verilog程序块语句 沿事件 纯组合always 纯时序always 具有同步复位的alw ...
最新文章
- iOS开发经验总结,我的2019进阶之路!
- Database之SQLSever:SQL命令实现的高级案例集合之单表/多表(筛选、统计个数)之详细攻略
- dcs服务器性能指标,第6章DCS的性能指标.PDF
- Hadoop 高可用集群(HA)
- 中国电子技术标准化研究院与Linux基金会战略合作签约仪式圆满落幕
- 一些忘记了的....
- OpenGL编程指南-光照
- STM8S103之独立看门狗和窗口看门狗
- SSL证书问题SSL certificate problem: self signed certificate
- Linux环境批量下载阿里云盘资源
- 基于GITHUB ACTION的定时任务,真香!
- 《今日简史》--意义:人生不是虚构的故事
- 支付平台--清算总的详解
- ORA-12569: TNS: 包校验和失败解决方法一例
- python win32处理Excel(基础篇)
- Dell6400拆卸与维护
- Python 爬取携程所有机票
- 使用SSH服务管理远程主机
- 比尔盖茨最新发文 | 人工智能时代已经开启(全文)
- 这可能是史上最全的 Python 算法集!| 技术头条
热门文章
- 经典网络-InceptionV1论文及实践
- The APR based Apache Tomcat Native library which allows optimal performance in production environme
- json解析天气预报java_Json解析-和风天气
- android SwipeMenuLayout实现控件侧滑删除
- 计算机报名照片没有重命名,电脑照片重命名怎么弄
- Unity新手开发VR项目
- 部分设计模式案例代码
- STM32 单片机字符串生成二维码显示
- Codeforces 106 Buns【多重背包】
- r5 3500u和r5 4500u的区别