【Verilog 教程】6.5 Verilog避免Latch

这篇具有很好参考价值的文章主要介绍了【Verilog 教程】6.5 Verilog避免Latch。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

关键词:触发器,锁存器
Latch 的含义
锁存器(Latch),是电平触发的存储单元,数据存储的动作取决于输入时钟(或者使能)信号的电平值。仅当锁存器处于使能状态时,输出才会随着数据输入发生变化。

当电平信号无效时,输出信号随输入信号变化,就像通过了缓冲器;当电平有效时,输出信号被锁存。激励信号的任何变化,都将直接引起锁存器输出状态的改变,很有可能会因为瞬态特性不稳定而产生振荡现象。

锁存器示意图如下:
【Verilog 教程】6.5 Verilog避免Latch,Verilog教程,fpga开发,Verilog

触发器(flip-flop),是边沿敏感的存储单元,数据存储的动作(状态转换)由某一信号的上升沿或者下降沿进行同步的(限制存储单元状态转换在一个很短的时间内)。

触发器示意图如下:

【Verilog 教程】6.5 Verilog避免Latch,Verilog教程,fpga开发,Verilog

寄存器(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@(*)
文章来源地址https://www.toymoban.com/news/detail-729681.html

到了这里,关于【Verilog 教程】6.5 Verilog避免Latch的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • FPGA之锁存器(Latch)

    latch 是指锁存器,是一种对脉冲 电平 敏感的存储单元电路。锁存器和寄存器都是基本存储单元,锁存器是电平触发的存储器,寄存器是边沿触发的存储器。两者的基本功能是一样的,都可以存储数据。锁存器是组合逻辑产生的,而寄存器是在时序电路中使用,由时钟触发产

    2024年02月11日
    浏览(36)
  • Verilog 不完整if-else和case产生锁存latch

    写这篇文章是因为本小白在刷题过程中看到答主的代码总是不把if-else写全,而我又记得不写全是可能产生latch的,对此很迷惑,仔细看过之后发现只有组合逻辑(电平触发)电路中的不完整if-else和case才会产生锁存器latch。简单记录一下。 参考文章: 1、https://blog.csdn.net/ainu

    2024年02月13日
    浏览(70)
  • FPGA结构:LATCH(锁存器)和 FF(触发器)介绍

    如果你想学习有关FPGA的专业术语,可以参考这一篇:FPGA专业术语介绍 一句话概括,能够存储一个状态的数字电路叫做锁存器。 以下是最为基本的一个RS锁存器的具体结构: 以下是它的真值表,其中X表示不确定/无效: R {R} R (清零) S {S} S (置位) Q ( t ) {Q(t)} Q ( t ) (上一时刻的

    2024年01月25日
    浏览(56)
  • 【FPGA Verilog开发实战指南】初识Verilog HDL-基础语法

    就是用代码来描述硬件结构 语言有VHDL与Verilog HDL Verilog HDL 是从C语言来的,学的快 ###例子 也叫保留字,一般是小写 module 表示模块的开始 endmodule 模块的结束 模块名 一般与.v文件的名字一致 输入信号 input 输出信号 output 既做输入也做输出 inout 需要一些变量和参数对输

    2024年02月21日
    浏览(45)
  • 什么是好的FPGA编码风格?(3)--尽量不要使用锁存器Latch

    在FPGA设计中,几乎没人会主动使用 锁存器Latch ,但有时候不知不觉中你的设计莫名其妙地就生成了一堆Latch,而这些Latch可能会给你带来巨大的麻烦。 Latch,锁存器,一种可以存储电路状态信息的组合逻辑元件,和同样可以保存电路状态的时序逻辑元件–触发器(Flip-Flop,

    2024年02月05日
    浏览(36)
  • 【FPGA教程案例40】通信案例10——基于FPGA的简易OFDM系统verilog实现

    FPGA教程目录 MATLAB教程目录 --------------------------------------------------------------------------------------- 目录 1.软件版本 2.OFDM原理 3.OFDM系统的verilog实现

    2024年02月12日
    浏览(57)
  • 基于FPGA的QPSK调制系统verilog开发

    目录 一、理论基础 二、核心程序 三、测试结果         正交相移键控(Quadrature Phase Shift Keying,QPSK)是一种数字调制方式。它分为绝对相移和相对相移两种。由于绝对相移方式存在相位模糊问题,所以在实际中主要采用相对移相方式DQPSK。QPSK是一种四进制相位调制,具有良

    2024年02月01日
    浏览(47)
  • 基于Verilog 语言开发的FPGA密码锁工程

    基于Verilog 语言开发的FPGA密码锁工程。 通过矩阵键盘输入按键值。 输入12修改密码,13清除密码,可以修改原来默认的密码,修改时首先要输入当前密码进行验证,正确后才能更新当前密码,否则修改不成功。 修改结束后按键15,确认修改成功。 也直接使用默认密码作为最终

    2024年02月10日
    浏览(59)
  • 基于FPGA的FSK调制解调系统verilog开发

    目录 1.算法仿真效果 2.verilog核心程序 3.算法涉及理论知识概要 4.完整verilog VIVADO2019.2仿真结果如下:       频移键控是利用载波的频率变化来传递数字信息。数字频率调制是数据通信中使用较 早的一种通信方式,由于这种调制解调方式容易实现,抗噪声和抗衰减性能较强,

    2024年02月05日
    浏览(77)
  • FPGA开发] 使用Verilog实现一个简单的计数器

    计数器是数字电路中常见的元件之一,它能够按照一定的规律进行计数。在FPGA开发中,我们可以使用硬件描述语言Verilog来实现一个简单的计数器。本文将为您详细介绍如何使用Verilog编写一个基于FPGA的计数器,并提供相应的源代码。 首先,我们需要定义计数器的功能和规格

    2024年02月03日
    浏览(61)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包