IC设计错误案例分析

电子说

1.3w人已加入

描述

IC设计错误案例:信号取反导致的错误

 

1、取反操作

 

如下所示,信号a取反赋值给信号b,底层逻辑是,如果a位宽少于b位宽,则a先高位补0,再进行取反,最后赋值给b。

 

  •  
  •  
  •  
  •  
  •  
  •  
  •  
wire [4:0] a;wire [5:0] b;assign b=~a ; 等价于 assign b= ~{1’b0,a[4:0]}; wire [4:0] a;wire [6:0] b;assign b=~a ; 等价于 assign b= ~{1’b0,1’b0,a[4:0]};

2、取反位宽不匹配错误案例

 

如果赋值语句或者条件判断中用到了取反操作,一定需要先将取反值赋值相同的位宽 或者 与取反值做运算的信号一定要与原值位宽相同。

 

  •  
  •  
  •  
  •  
  •  
  •  
  •  
wire [2:0] mty_in  ;//invalid byte  in total 8 bytewire [3:0] vld_byte ;//valid byte in total 8 byte if( (~mty_in) <= 4’d5 )        data_updata_vld =1else        data_updata_vld =0;

在上面的代码中,data_updata_vld永远为0,因为(~mty_in) <= 4’d5比较时,会默认(~mty_in) 是4bit信号,因此(~mty_in)本质上是~{1’b0,a[2:0]},[3]bit为1 永远大于4’d5.

 

3、如何检查

 

此类问题

采用vcs仿真可以看出仿真结果不符合预期

 

采用是spyglass,会报warning/err,说明运算符作为位宽不匹配

 

IC设计错误案例:加法溢出导致的错误

 

1、加法溢出导致的功能错误

 

如下图所示错误代码中,当byte_add+byte_save等于256的时候,我们期望的的信号more_than_64应该为1,而实际上在错误代码中(byte_add+byte_save)与8’d64比较,(byte_add+byte_save)可能会被理解为8’d0,即被理解成8bit信号,more_than_64等于0,功能错误。在芯片设计中,有可能因为EDA工具之间差异导致对(byte_add+byte_save)>8’d64的理解不一样,导致VCS等工具RTL级仿真正确,而DC综合后功能错误。例如:VCS将(byte_add+byte_save)理解为9bit的位宽,而综合理解为8bit位宽。一旦综合理解为8bit位宽,则会导致网表与我们预期功能不一致,而且网表仿真比较慢,一般很慢遍历所有RTL级仿真用例,因此此类问题不容易发现。

 

2、如何避免加法溢出导致的功能错误

 

如下图所示正确代码中,将赋值给9bit的add_byte_total,并且将add_byte_total与9’d64比较,而不是8’d64比较,这样就不会发生溢出截断比较的情况。

 

 

  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
//----------------------Error code begin-------------------------//wire         more_than_64 ;reg  [7:0]   byte_add  ;reg  [7:0]   byte_save ;reg  [7:0]  byte_update; assign more_than_64 = ( (byte_add+byte_save)  > 8'd64); always@(*)  if(more_than_64)    byte_update = (byte_add + byte_save ) - 8'd64 ;  else     byte_update = 8'd0;    //----------------------Error code end-------------------------//    //----------------------right and recommended code begin----------------------//wire         more_than_64 ;reg  [7:0]   byte_add  ;reg  [7:0]   byte_save ;reg  [7:0]   byte_update; wire [8:0]   add_byte_total ; assign     add_byte_total=(byte_add+byte_save); assign more_than_64 = ( add_byte_total  > 9'd64); always@(*)  if(more_than_64)    byte_update = (byte_add + byte_save ) - 8'd64 ;  else     byte_update = 8'd0;     //----------------------right and recommended code end----------------------//

 

 

 

 

  审核编辑:汤梓红
打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分