【Verilog 教程】6.5 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 @(*) beginif (en) q = data ;endendmodule

避免此类 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) beginif (en) q <= data ;endendmodule

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

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

实例

module module1_latch11(input       data1,input       data2,input       en ,output reg  q1 ,output reg  q2) ;always @(*) beginif (en)   q1 = data1 ;else      q2 = data2 ;endendmodule

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

实例

    always @(*) begin//q1 = 0; q2 = 0 ; //或在这里对 q1/q2 赋初值if (en)  beginq1 = data1 ;q2 = 1'b0 ;endelse beginq1 = 1'b0 ;q2 = data2 ;endend
case 结构不完整

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

实例

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

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

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

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

实例

   always @(*) begincase(sel)2'b00:    q = data1 ;2'b01:    q = data2 ;default:  q = 1'b0 ;endcaseendalways @(*) begincase(sel)2'b00:  q = data1 ;2'b01:  q = data2 ;2'b10, 2'b11 :  q = 1'b0 ;endcaseend

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

实例

   //signal itself as a part of conditionreg a, b ;always @(*) beginif (a & b)  a = 1'b1 ;   //a -> latchelse a = 1'b0 ;end//signal itself are the assigment sourcereg        c;wire [1:0] sel ;always @(*) begincase(sel)2'b00:    c = c ;    //c -> latch2'b01:    c = 1'b1 ;default:  c = 1'b0 ;endcaseend//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@(*)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/143585.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

HC32 IIC/I2C读写

IIC状态码 IIC 初始化 void iicInit(uint32_t speed) {stc_gpio_cfg_t stcGpioCfg;DDL_ZERO_STRUCT(stcGpioCfg);Sysctrl_SetPeripheralGate(SysctrlPeripheralGpio, TRUE); //开启GPIO时钟门控stcGpioCfg.enDir GpioDirOut; ///< 端口方向配置…

【2023最新版】超详细NMAP安装保姆级教程,Nmap的介绍、功能并进行网络扫描,收藏这一篇就够了

简介 从诞生之初&#xff0c;Nmap就一直是网络发现和攻击界面测绘的首选工具。从主机发现和端口扫描&#xff0c;到操作系统检测和IDS规避/欺骗&#xff0c;Nmap是大大小小黑客行动的基本工具。 为了绘制网络拓扑图&#xff0c;Nmap的发送特制的数据包到目标主机&#xff0c;…

【Amazon】AI 代码生成器—Amazon CodeWhisperer初体验 | 开启开挂编程之旅

使用 AI 编码配套应用程序更快、更安全地构建应用程序 文章目录 1.1 Amazon CodeWhisperper简介1.2 Amazon CodeWhisperer 定价2.1 打开VS Code2.2 安装AWS ToolKit插件 一、前言 1.1 Amazon CodeWhisperper简介 1️⃣更快地完成更多工作 CodeWhisperer 经过数十亿行代码的训…

目标检测如何演变:从区域提议和 Haar 级联到零样本技术

目录 一、说明 二、目标检测路线图 2.1 路线图&#xff08;一般&#xff09; 2.2 路线图&#xff08;更传统的方法&#xff09; 2.3 路线图&#xff08;深度学习方法&#xff09; 2.4 对象检测指标的改进 三、传统检测方法 3.1 维奥拉-琼斯探测器 (2001) 3.2 HOG探测器…

为什么u盘在mac上显示不出来

插入U盘是个看似简单的操作&#xff0c;但有时候在Mac电脑上却出现了无法显示U盘的情况。这样的问题是非常让人头疼的&#xff0c;特别是当你急需使用U盘中的文件时。那么&#xff0c;究竟为什么U盘在Mac上会显示不出来呢&#xff1f;今天就让我们一起来深入了解一下这个问题&a…

编程新时代:Amazon CodeWhisperer 助您轻松驾驭代码世界

文章目录 一、什么是 Amazon CodeWhisperer&#xff1f;二、个人无限免费使用三、安装配置3.1 手把手教你在pycharm配置3.2 同理在VSCODE安装 三、Pycharm上测试3.1 根据注释写代码3.2 检查修复代码错误3.3 构建一个简单爬虫 四、 VSCODE上测试4.1 个性化体验4.2 系统兼容性4.3…

【再识C进阶3(下)】详细地认识字符分类函数,字符转换函数和内存函数

前言 &#x1f493;作者简介&#xff1a; 加油&#xff0c;旭杏&#xff0c;目前大二&#xff0c;正在学习C&#xff0c;数据结构等&#x1f440; &#x1f493;作者主页&#xff1a;加油&#xff0c;旭杏的主页&#x1f440; ⏩本文收录在&#xff1a;再识C进阶的专栏&#x1…

vuereact质检工具(eslint)安装使用总结

1、ESLint ESLint工具主要类似java中的checkStyle和findbugs&#xff0c;是检查代码样式和逻辑规范的工具。 1.1、ESLint安装流程 打开VSCode软件&#xff0c;打开扩展中心&#xff0c;下载ESLint插件 图1.1 点击后面的install按进行安装&#xff0c;如图1.2所示&#xff1…

黑马VUE3视频笔记

目录 一、使用create-vue创建项目 二、setup选项 三、reactive和ref函数 1.reactive() 2.ref() 三、computed 四、watch ​五、生命周期函数 六、父传子、子传父 父传子defineProps 子传父defineEmits 七、模板引用 ref defineExpose 八、跨层传递普通数据 prov…

SpringBoot 学习(二)配置

2. SpringBoot 配置 2.1 配置文件类型 配置文件用于修改 SpringBoot 的默认配置。 2.1.1 properties 文件 **properties ** 是属性文件后缀。 文件名&#xff1a;application.properties 只能保存键值对。 基础语法&#xff1a;keyvalue namewhy注入配置类 Component //…

百度SEO优化不稳定的原因分析(提升网站排名的稳定性)

百度SEO优化不稳定介绍蘑菇号-www.mooogu.cn SEO不稳定是指网站在搜索引擎中的排名不稳定&#xff0c;随着时间的推移会发生变化。这种情况可能会出现在网站页面结构、内容质量、外链质量等方面存在缺陷或不合理之处。因此&#xff0c;优化SEO非常重要&#xff0c;可以提高网站…

Cruise 的界面和模型文件路径介绍

文章目录 打开 Cruise自带模型所在路径自带模型分类Cruise 中的模型路径解析打开用户手册建模界面介绍打开模型 打开 Cruise 最新的几个 Cruise 软件都是集成到一个平台上的&#xff0c;名为 AVL Advanced Simulation Desktop。 自带模型所在路径 User 选项卡下的模型&#x…

Spring实现简单的Bean容器

1.BeanDefinition&#xff0c;用于定义 Bean 实例化信息&#xff0c;现在的实现是以一个 Object 存放对象 public class BeanDefinition {/*** bean对象*/private Object bean;/*** 存放 &#xff08;定义&#xff09;Bean 对象*/public BeanDefinition(Object bean) {this.bea…

关于TUM数据集

2、验证回环检测算法&#xff0c;需要有人工标记回环的数据集。然而人工标记回环是很不方便的&#xff0c;我们会考虑根据标准轨迹计算回环。即&#xff0c;如果轨迹中有两个帧的位姿非常相近&#xff0c;就认为它们是回环。请根据TUM数据集给出的标准轨迹&#xff0c;计算出一…

怎么选择伪原创工具?伪原创工具推荐

什么是伪原创工具&#xff1f;伪原创工具是一种可以将已有文本进行修改、改写或重新组合&#xff0c;生成新的文本内容的工具。 伪原创工具的作用 节省时间和精力&#xff1a;手工创作内容需要耗费大量时间和精力&#xff0c;而伪原创工具可以在短时间内生成大量内容&#xf…

嵌入式中如何用C语言操作sqlite3(07)

sqlite3编程接口非常多&#xff0c;对于初学者来说&#xff0c;我们暂时只需要掌握常用的几个函数&#xff0c;其他函数自然就知道如何使用了。 数据库 本篇假设数据库为my.db,有数据表student。 nonamescore4嵌入式开发爱好者89.0 创建表格语句如下&#xff1a; CREATE T…

C++中实现雪花算法来在秒级以及毫秒及时间内生成唯一id

1、雪花算法原理 雪花算法&#xff08;Snowflake Algorithm&#xff09;是一种用于生成唯一ID的算法&#xff0c;通常用于分布式系统中&#xff0c;以确保生成的ID在整个分布式系统中具有唯一性。它的名称来源于雪花的形状&#xff0c;因为生成的ID通常是64位的整数&#xff0…

【数据结构】哈希表(详)

文章目录 前言正文一、基本概念二、基本原理1.哈希函数1.1直接定址法&#xff08;常用&#xff09;1.2除留余数法&#xff08;常用&#xff09;1.3 平方取中法&#xff08;了解&#xff09;1.4 折叠法(了解)1.5 随机数法(了解)1.6数学分析法(了解) 2.哈希冲突2.1 平均查找长度2…

QT配置MySQL数据库 ninja: build stopped: subcommand failed

QT配置MySQL数据库 我当前的软件版本&#xff1a;QT Creator 10.0.2 (community)&#xff0c;MingW 6.4.3 (QT6)&#xff0c;MySQL 8.0。 MySQL不配置支持的数据库有QList("QSQLITE", "QODBC", "QPSQL")&#xff0c;这个时候是不支持MYSQL数据…

No127.精选前端面试题,享受每天的挑战和学习

🤍 前端开发工程师(主业)、技术博主(副业)、已过CET6 🍨 阿珊和她的猫_CSDN个人主页 🕠 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 🍚 蓝桥云课签约作者、已在蓝桥云课上架的前后端实战课程《Vue.js 和 Egg.js 开发企业级健康管理项目》、《带你从入…