佛山网站建设公司电话,宿迁房产网官方网站,企业官网网站建设,企业手机网站开发关键词#xff1a;触发器#xff0c;锁存器 Latch 的含义 锁存器#xff08;Latch#xff09;#xff0c;是电平触发的存储单元#xff0c;数据存储的动作取决于输入时钟#xff08;或者使能#xff09;信号的电平值。仅当锁存器处于使能状态时#xff0c;输出才会随着…关键词触发器锁存器 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 1b0 ;endelse beginq1 1b0 ;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)2b00: q data1 ;2b01: q data2 ;endcaseendendmodule当然消除此种 latch 的方法也是 2 种将 case 选项列表补充完整或对信号赋初值。
补充完整 case 选项列表时可以罗列所有的选项结果也可以用 default 关键字来代替其他选项结果。
例如上述 always 语句有以下 2 种修改方式。
实例 always (*) begincase(sel)2b00: q data1 ;2b01: q data2 ;default: q 1b0 ;endcaseendalways (*) begincase(sel)2b00: q data1 ;2b01: q data2 ;2b10, 2b11 : q 1b0 ;endcaseend原信号赋值或判断 在组合逻辑中如果一个信号的赋值源头有其信号本身或者判断条件中有其信号本身的逻辑则也会产生 latch。因为此时信号也需要具有存储功能但是没有时钟驱动。此类问题在 if 语句、case 语句、问号表达式中都可能出现例如
实例 //signal itself as a part of conditionreg a, b ;always (*) beginif (a b) a 1b1 ; //a - latchelse a 1b0 ;end//signal itself are the assigment sourcereg c;wire [1:0] sel ;always (*) begincase(sel)2b00: c c ; //c - latch2b01: c 1b1 ;default: c 1b0 ;endcaseend//signal itself as a part of condition in ? expressionwire d, sel2;assign d (sel2 d) ? 1b0 : 1b1 ; //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 的产生在组合逻辑中需要注意以下几点
1if-else 或 case 语句结构一定要完整 2不要将赋值信号放在赋值源头或条件判断中 3敏感信号列表建议多用 always(*)