在线咨询
eetop公众号 创芯大讲堂 创芯人才网
切换到宽版

EETOP 创芯网论坛 (原名:电子顶级开发网)

手机号码,快捷登录

手机号码,快捷登录

找回密码

  登录   注册  

快捷导航
搜帖子
查看: 4734|回复: 4

[资料] Verilog中if,case语句造成锁存器的情况及assign语法优势

[复制链接]
发表于 2021-2-1 11:38:20 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?注册

x
本帖最后由 羽无芯 于 2021-3-9 20:43 编辑

verilog case,if语句情况不全包含会生成锁存器

数字电路中应避免产生不必要的锁存器 Latch
锁存器(Latch)是数字逻辑电路中很重要的一种基本电路,常见的锁存器包括三个端口:数据输入口、数据输出口、使能端。当使能端为高电平时,输入口的数据直接送到输出口,此时输入输出口可以看成是直接连通的;当使能端为低电平时,输出口的数据保持之前的数据不变,无论输入口的数据怎么变化,输出都保持不变,就是把原来的状态锁存下来了(所以才叫锁存器)。锁存器与触发器的区别在于:锁存器是电平触发,而触发器是边沿触发。锁存器在不锁存数据时,输出随输入变化;但一旦数据锁存时,输入对输出不产生任何影响。

在FPGA电路设计中,不规范的描述语言可能会产生意想不到的锁存器,而设计者往往并没有注意到自己的设计会被综合出锁存器,导致综合出的电路出现逻辑错误。

在数字电路中,产生意外的锁存器的情况一般有以下两种:

1.if……else……结构中缺少else

先看一个实际的例子:

image.png

用quartus综合一下这两个电路,看看产生的RTL图是怎样的:

左边的电路:

20190327204132763.png
右边的电路:
20190327204239572.png
由RTL视图可以直观的看出,左边的电路没有生成锁存器,而右边的电路生成了一个我们不想要的锁存器(q1$latch)。左边的电路是时序逻辑,生成触发器,而触发器是有使能端(en)的,使能端无效时就可以保存数据,无需锁存器。右边的电路是组合逻辑,在en为低电平时,输出q1要保持不变,而组合逻辑没有存储元件,只能生成锁存器来保持数据。所以在时序逻辑中,不完整的 if…else… 结构并不会生成锁存器,而组合逻辑中不完整的 if…else… 结构就会生成锁存器。为了避免我们设计的组合逻辑中出现不想要的锁存器,在使用 if…else… 结构时一定要写完整。把刚才例子中右边的电路写完整,并查看其RTL视图如下:
20190327204658404.png
写完整后,就没有生成锁存器,而是生成了一个二选一的选择器,这正是我们想要设计的。


2. case结构中的分支没有包含所有情况且没有default语句

case结构中一般要加上default语句,以保证出现意外情况也可以作出相应的反应。如果没有加default并且case分支不完整,当出现case分支中没有列出的情况时,电路状态保持原来的状态不变,于是就会生成锁存器来保存状态,如下图的电路所示:
20190327204802679.png
图中case分支中只写了(se=0)的情况,而(se=1)的情况未给出,且没有写default,于是当(se=1)时,q1保持原来的值不变,这样就产生了锁存器(q1$latch)。

如果将case分支补全,或者加上default语句,则如下图所示:
20190327204928729.png
补全case分支后,就不会生成锁存器了。

同样,只有在组合逻辑中的case结构才有可能产生锁存器,而在时序逻辑电路中,即使case结构中的分支不完整,也不会产生锁存器,如下图所示:
20190327205026279.png
因此,在设计组合逻辑电路时,要注意将 if…else… 结构中的else写完整,case结构中一定要加上default语句,这样可以减少综合出锁存器的可能性。

3.推荐使用assign语法替代if-else和case语法

verilog中的if-else和case语法存在两大缺点。

1)不能传播不定态。

2)会产生优先级的选择电路而非并行选择电路,从而不利于时序和面积

例子:if (sel1)

             out = in1[3:0];

         else if (sel2)

             out = in2[3:0];

        else if (sel3)

             out = in3[3:0];

        else

             out = 4'b0;

如果此处确实希望生成一种优先级选择的逻辑,则推荐使用assign语法等效编写成如下形式,以规避x不定状态传播的问题:

     assign out = sel1 ? in1[3:0] :

                           sel2 ? in2[3:0] :

                           sel3 ? in3[3:0] :

                           4'b0;

而如果此处本来是希望生成一种并行选择的逻辑,则推荐使用assign语法明确地使用“与”-“或”逻辑,编写如下:

    assign  out = ({4{sel1}} & in1[3:0])

                           | ({4{sel2}} & in2[3:0])

                           | ({4{sel3}} & in3[3:0]) ;


发表于 2021-2-2 14:24:58 | 显示全部楼层
写得好,case应该使用unique case。组合逻辑使用always_comb 来避免生成latch
发表于 2024-10-24 23:39:55 | 显示全部楼层
mark, 又开始学习verilog了
发表于 2024-10-27 21:55:34 | 显示全部楼层
赞一个!每次都被搞得脑壳疼……
发表于 2024-10-28 10:34:40 | 显示全部楼层


叨叨江湖 发表于 2024-10-27 21:55
赞一个!每次都被搞得脑壳疼……


如果这都头疼 那么不适合干这个
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

站长推荐 上一条 /2 下一条


小黑屋| 手机版| 关于我们| 联系我们| 隐私声明| EETOP 创芯网
( 京ICP备:10050787号 京公网安备:11010502037710 )

GMT+8, 2024-12-25 15:23 , Processed in 0.020428 second(s), 8 queries , Gzip On, Redis On.

eetop公众号 创芯大讲堂 创芯人才网
快速回复 返回顶部 返回列表