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 ; 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) begin if (en) q 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@(*)
越南永新电厂一期工程1号机组并网成功,项目开始转入运营期
华为消费者业务调整:CMO朱勇刚接替张晓云
行星齿轮减速机轴承位磨损如何修复
分享15个运算放大器基础知识
小米MIUI实力更新?人工智能算法系统能否赶上华为
设计Verilog时为什么要避免Latch的产生呢?
Pro/E自动分模方法与技巧
微软Win10预览版发布:修复潜在数据丢失Bug
査勇:华为云在视频AI转码领域的技术实践
牡丹江联通LTE共享基站与大网基站为何无法互相切换
【Milk-V Duo 开发板免费体验】系统体验
如何正确识别电池的容量和功率?
关于英特尔开通的零售快车道分析和介绍
电机负荷大是什么原因 电机负荷过大会出现什么情况 怎么处理?
半导体区别于导体的重要特征
如何选择分流器501W/BP扼流圈?使用分流器后如何计算电流表的倍数?
北京打造集成电路龙头进入3.0时代
小米5手机评测 一部实用性挺高的手机
采用+12V至±5V电源的精密、16位双极性输出电压源
小巧轻薄高速大容量,台电S20 1TB固态移动硬盘评测