mips cache verilog实现_实例解析Verilog综合出锁存器的问题

fec87a8d-9c1a-eb11-8da9-e4434bdf6706.jpeg

八月の

00c97a8d-9c1a-eb11-8da9-e4434bdf6706.gif 01c97a8d-9c1a-eb11-8da9-e4434bdf6706.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

02c97a8d-9c1a-eb11-8da9-e4434bdf6706.png

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

04c97a8d-9c1a-eb11-8da9-e4434bdf6706.png

05c97a8d-9c1a-eb11-8da9-e4434bdf6706.png

代码B:

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

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

08c97a8d-9c1a-eb11-8da9-e4434bdf6706.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的赋值;

0ac97a8d-9c1a-eb11-8da9-e4434bdf6706.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进行了默认赋值。

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

0dc97a8d-9c1a-eb11-8da9-e4434bdf6706.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会造成工具之间的移植性问题,改代码依然综合出了锁存器

10c97a8d-9c1a-eb11-8da9-e4434bdf6706.png

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

12c97a8d-9c1a-eb11-8da9-e4434bdf6706.jpeg

14c97a8d-9c1a-eb11-8da9-e4434bdf6706.jpeg

往期精彩

数字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校招笔试

15c97a8d-9c1a-eb11-8da9-e4434bdf6706.png 16c97a8d-9c1a-eb11-8da9-e4434bdf6706.gif

前瞻性的眼光,

和持之以恒地学习~

17c97a8d-9c1a-eb11-8da9-e4434bdf6706.jpeg 18c97a8d-9c1a-eb11-8da9-e4434bdf6706.png
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值