综合实例_实例解析Verilog综合出锁存器的问题

本文深入探讨了Verilog代码在综合时如何产生锁存器的问题,通过实例分析了各种代码形式,包括缺少else分支、使用case语句和//synopsys full_case选项的情况,指出组合逻辑中保持功能是生成锁存器的关键。
摘要由CSDN通过智能技术生成

61e6d4f224be549db12eb8717743215e.png

八月の

ed5fbbf138bf58d04d0fc50e3a1273dc.gif d38480e6c0c578791e047b56fbdc94f9.png

时间一晃,夏和秋开始交替

有的人准备迎接硕果

而我,在夏天的尾巴焦头烂额

望着窗外的天,享受吹来的风

仍不知心里愁绪是真,还是假

逃离秋招季的焦虑

缓缓心情,也好好努力

这篇文章通过实际的Design Compiler综合来精解Verilog代码生成latch的问题。

下面哪种写法会产生latch?为什么? 

代码如下:

A.

always  @(*)beginif(d)a = b;end

B

always  @(*)beginif(d)  a = b;else  a = a;end

C

always @ (b or d)  case(d)    2’b00: a=b>>1;    2’b11: c=b>>1;    default:      begin        a=b;        c=b;      endendcase

D

always @(b or d)begin  a=b;  c=b;  case(d)    2’b00: a=b>>1;    2’b11: c=b>>1;  endcaseend

E

always@(bor d)begin  case(d) //synopsys full_case    2’b00: a=b>>1;    2’b11: c=b>>1;  endcaseend

代码A:

是一个always语句块构成的组合逻辑,其中缺少else分支

当d=1'b0时,综合工具会默认保持a的值,即生成锁存器。

module code_a(        input d,        input b,        output reg a);        always@(*) begin                if(d) a =b ;        endendmodule

a2ac115f2024bb04a9f3f716d14ae213.png

综合出的电路图如上所示,TLATX1就是所使用的标准单元库的锁存器的名字。

5395e4c3762495028b5cb0f50974cf9e.png

bef0fbcdd8c92cd929b4dd265405c3e5.png

代码B:

module code_b(        input d,        input b,        output reg a);        always@(*) begin                if(d) a =b ;                else  a =a ;        endendmodule

代码B虽然补全了else分支语句。但是,其代码依然有保持功能,即会生成锁存器。

6ca7f8706b9dfae23cb264f7d05c60fd.png

也就是说,组合逻辑是否会生成锁存器,其根本原因是该组合逻辑存在保持功能!

代码C:

module code_c(        input [1:0] d,        input [1:0] b,        output reg [1:0] a,        output reg [1:0] c);        always@(b or d ) begin                case(d)                         2'b00:a = b >>1 ;                         2'b11:c = b >>1 ;                         default:begin                                 a = b ;                                 c = b ;                         end                endcase        endendmodule

代码C在always语句块内使用了case语句,并且case语句中含有default分支。但是,我们可以发现,

d=2’b00时,没有说明c的赋值;d=2’b01时,没有说明a的赋值;

76daeae5baf4757ccffba5d1cf9f6dff.png

从上面的综合结果可以看出,综合出来4 个锁存器。
d=2’b00时,保存c的值;d=2’b01时,保存a的值 

代码D

module code_d(        input [1:0]d,        input [1:0]b,        output reg [1:0]a,        output reg [1:0]c);        always@(b or d ) begin                       a = b ;                c = b ;                case(d)                         2'b00:a = b >>1 ;                         2'b11:c = b >>1 ;                endcase        endendmodule

代码D和代码C的不同是,它在always语句块的开始,对a和c进行了默认赋值。

这就类似于软件里面的初始化,当然只是类似而已。

cec1da5186d5977e9645e29b1f072592.png

从上面的综合结果,我们可以看出来,没有生成任何时序逻辑。

代码E

module code_e(  input [1:0] d,  input [1:0] b,  output reg [1:0] a,  output reg [1:0] c);  always@(b or d ) begin    case(d) //synopsys full_case      2'b00:a = b >>1 ;      2'b11:c = b >>1 ;    endcase  endendmodule

使用了//synopsys full_case 选项,

该选项:

      1、防止综合工具将case语句综合成不必要的优先级电路,增大硬件开销

2、和default语句类似,补全case语句没有列出的情况。

3、但是//synopsys full_case会造成工具之间的移植性问题,改代码依然综合出了锁存器

0f504d45bbcd733ff4a290b98fbb9444.png

由上图我们可以看出,对于2 比特的右移位“>> ” a[1]和c[1]恒等于1’b0  但是代码C 却使用了4 个锁存器,这是一个比较诡异的事情!

e10329a51d54c0ca4baf6f5deb377ef3.png

a95ce90b8e96df22a03552575eeaef53.png

往期精彩

数字IC笔试题(1) ——复旦微2017

数字IC笔试题(2) ——汇顶设计验证2018

数字IC笔试题(3) ——Cadence前端设计2018

数字IC笔试题(4) ——Nvidia前端设计2018

数字IC笔试题(5) ——全志科技数字前端

数字IC笔试题(6) ——乐鑫科技数字芯片2020

数字IC笔试题(7) ——乐鑫科技数字芯片2017

字IC笔试题(8) ——乐鑫科技数字芯片2020(续)

数字IC笔试题(9) ——汇顶设计验证2019(续)

数字IC笔试题(10) ——卓胜微电子2020

数字IC笔试题(11)——卓胜微电子2020(续)

数字IC笔试题(12)——上海南芯2019秋招笔试预测题

数字IC笔试题(13)——大疆2019 FPGA校招笔试

26e8edb114b8dc8d041517f427dc33f2.png 47970a1cb85e953e3e430c9edcb44a7e.gif

前瞻性的眼光,

和持之以恒地学习~

e971c37745c8fa56f0a9885275f7749d.png 813ed75c56828ea686443259076e07df.png
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值