Verilog 避免 Latch
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 @(*) begin
if (en) q = data ;
end
endmodule
避免此类 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 <= data ;
end
endmodule
在组合逻辑中,当条件语句中有很多条赋值语句时,每个分支条件下赋值语句的不完整也是会产生 latch。
其实对每个信号的逻辑拆分来看,这也相当于是 if-else 结构不完整,相关寄存器信号缺少在其他条件下的赋值行为。例如:
实例
module module1_latch11(
input data1,
input data2,
input en ,
output reg q1 ,
output reg q2) ;
always @(*) begin
if (en) q1 = data1 ;
else q2 = data2 ;
end
endmodule
这种情况也可以通过补充完整赋值语句或赋初值来避免 latch。例如:
实例
always @(*) begin
//q1 = 0; q2 = 0 ; //或在这里对 q1/q2 赋初值
if (en) begin
q1 = data1 ;
q2 = 1'b0 ;
end
else begin
q1 = 1'b0 ;
q2 = data2 ;
end
end
case 结构不完整
case 语句产生 Latch 的原理几乎和 if 语句一致。在组合逻辑中,当 case 选项列表不全且没有加 default 关键字,或有多个赋值语句不完整时,也会产生 Latch。例如:
实例
module module1_latch2(
input data1,
input data2,
input [1:0] sel ,
output reg q ) ;
always @(*) begin
case(sel)
2'b00: q = data1 ;
2'b01: q = data2 ;
endcase
end
endmodule
当然,消除此种 latch 的方法也是 2 种,将 case 选项列表补充完整,或对信号赋初值。
补充完整 case 选项列表时,可以罗列所有的选项结果,也可以用 default 关键字来代替其他选项结果。
例如,上述 always 语句有以下 2 种修改方式。
实例
always @(*) begin
case(sel)
2'b00: q = data1 ;
2'b01: q = data2 ;
default: q = 1'b0 ;
endcase
end
always @(*) begin
case(sel)
2'b00: q = data1 ;
2'b01: q = data2 ;
2'b10, 2'b11 :
q = 1'b0 ;
endcase
end
原信号赋值或判断
在组合逻辑中,如果一个信号的赋值源头有其信号本身,或者判断条件中有其信号本身的逻辑,则也会产生 latch。因为此时信号也需要具有存储功能,但是没有时钟驱动。此类问题在 if 语句、case 语句、问号表达式中都可能出现,例如:
实例
//signal itself as a part of condition
reg a, b ;
always @(*) begin
if (a & b) a = 1'b1 ; //a -> 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@(*)
Verilog 避免 Latch相关推荐
- Verilog如何避免Latch
锁存器(Latch)产生的原因: 目录 1.if结构不完整 2.case结构不完整 3.敏感信号列表不完整 Latch的危害: 输入状态可能多次变化,容易在输入信号产生毛刺,会增加电路的不稳定性: 使 ...
- Verilog十大基本功8 (flipflop和latch以及register的区别)
Verilog十大基本功8 (flipflop和latch以及register的区别) 来自1:https://www.cnblogs.com/LNAmp/p/3295441.html 第一次接触La ...
- 11.Verilog中如何避免Latch
FPGA教程目录 MATLAB教程目录 -------------------------------------------------------------------------------- ...
- 【Verilog基础】锁存器(Latch)知识点总结
文章目录 一.Latch 是什么 二.Latch 的危害 三.几种产生 Latch 的情况 情况一: 组合逻辑中 if 语句没有 else 情况二: 组合逻辑中 case 的条件不能够完全列举且不写 ...
- 【FPGA】Verilog:锁存器 Latch | RS Flip-Flop 与 D Flip-Flop 的实现
- HDLBits 系列(14) Latch and Dff and Edge detect
目录 D Latch DFF + GATE Mux + DFF MUX2 + DFF FSM JK 触发器 Edgedetect(边沿检测) 双边沿检测 D Latch Implement the f ...
- 【Verilog HDL 训练】第 05 天(序列检测)
1. dff和latch有什么区别. 锁存器是一种对脉冲电平(也就是0或者1)敏感的存储单元电路,而触发器是一种对脉冲边沿(即上升沿或者下降沿)敏感的存储电路. "触发器" 泛指一 ...
- Verilog 流水线加法器
<数字系统设计与Verilog HDL>上面有这么一段代码,用于实现8位4级流水线加法器. module adder8pip(cout,sum,cin,ina,inb,clk );inpu ...
- FPGA 中的latch 锁存器
一直都知道fpga中有latch这么一回事,但是一直都不太清楚到底什么是锁存器,它是怎么产生的,它到底和寄存器有多少区别,它怎么消除.为什么说他不好? 一,是什么 锁存器是一种在异步时序电路系统中,对 ...
- Verilog 中 wire 和 reg 数据类型区别
两者差别很大,完全不能取消. 在Verilog中,wire永远是wire,就是相当于一条连线,用来连接电路,不能存储数据,无驱动能力,是组合逻辑,只能在assign左侧赋值,不能在always @ 中 ...
最新文章
- 机器学习的9个基础概念和10种基本算法总结
- 2010年上半年计算机专业技术资格考试工作安排
- 2019 年,容器技术生态会发生些什么?
- 【我们都爱Paul Hegarty】斯坦福IOS8公开课个人笔记32 NSNotification
- table中tr使用toggle不好,选择换一张方式
- 《走遍中国》珍藏版(七)
- 计算机图形学笔记(第二周)
- 如何在 Ubuntu 上安装 MongoDB
- LeetCode 198. 打家劫舍
- java使用poi导出excel 包括多个工作簿
- 技术博客|第13期:Server Side Logging:Hulu推荐系统中的特征漂移问题解决方法
- 明日之后、“吃鸡”为何成为爆款手游?我们帮你分析了10000条快手广告
- iosetup mysql_InnoDB: Error: io_setup() failed with EAGAIN
- 手写数字识别--Android Studio 加载tensorflow模型
- 常用的图像特征提取方法
- 用u盘重装微软官方win10专业版--详细操作文档
- VSCode全配置(c++、unity、html...等配置和好用设置,持续更新)
- 解决p标签自动换行文字两端不对齐问题
- HTML+CSS写个人简历
- 基于STM32的电阻、电容测量(NE555芯片RC振荡法)