Verilog编码中位宽不匹配的危害是什么?

电子说

1.3w人已加入

描述

1、位宽不匹配   

Verilog编码中,常见的位宽不匹配错误,有赋值左右位宽不匹配(<=,=),比较位宽(>,<,>=,<=)不匹配,计算位宽(+,-)不匹配

位宽不匹配会导致综合产生的网表与个人预期差异较大,导致功能不正确。VCS仿真能及时发现问题,但VCS仿真存在部分场景没有覆盖的问题,因此仅仅通过VCS仿真不容易发现问题。通过spyglass lint检测可以发现所有位宽不匹配的情况。

2、位宽不匹配的危害  

下文以比较位宽不匹配为例,讲解位宽不匹配的危害。

注意:

1)在条件判断中(if语句),不建议使用加减后结果直接进行比较,禁止进行加减运算后与位宽不匹配的数据/变量进行比较。

2)拼接符号中“{}”,不允许使用加减乘除等运算,综合类软件无法正确判断数据运算结果位宽。数字运算必须先通过wire指定位宽,然后通过assign得到运算结果

错误案例1

如下代码,代码本意是:当cnt0与cnt1之和大于8的时候,count加1。

错误代码中:

比较数据是4’h8,此时综合完成后的网表中,会将cnt0与cnt1之和截位成4bit,再与4’h8比较,如果cnt0与cnt1之和为5’h10000,在此会截位为4’h0000,反而小于4’h8,与预期功能不符

正确代码&推荐代码中:

先定义:wire [4:0] cnt_add ; 指定cnt_add位宽为5bit,然后assign  cnt_add  = (cnt0+cnt1) ;最后与5’h8比较,因为通过wire指定了位宽,所以对于各类综合软件而言都不会发生截位,不会发生错误。

正确代码&不推荐中

直接将4’h8修改为5’h8,也避免了cnt0+cnt1累加截位,但是spyglass lint会报warning,

不推荐。

reg  [3:0]   cnt0  ;
reg  [3:0]   cnt1  ;
reg  [4:0]   count ;
reg          ov_nc ;


//-------------case 1-----------------
//wrong code  错误代码
always @ (posedge clk or negedge rst_n) 
    if(!rst_n)begin
    count     <= 5'b0 ;
    end 
    else if((cnt0+cnt1)>4'h8) //should be 5'h8
    begin
       {ov_nc, count} <= count +1'b1;
    end 
    
//right  ,but not recommended
always @ (posedge clk or negedge rst_n) 
    if(!rst_n)begin
    count     <= 5'b0 ;
    end 
    else if((cnt0+cnt1)>5'h8) //should be 5'h8
    begin
       {ov_nc, count} <= count +1'b1;


//right code and recommended  正确且推荐
wire [4:0] cnt_add ;
assign  cnt_add  = (cnt0+cnt1) ;


always @ (posedge clk or negedge rst_n) 
    if(!rst_n)begin
    count     <= 5'b0 ;
    end 
    else if(cnt_add >5'h8) // (cnt0+cnt1) is 5 bits
    begin
         {ov_nc, count} <= count +1'b1;
    end 
    
 错误案例2  

NOTE: 拼接符号中“{}”,不允许使用加减乘除等运算,综合类软件无法正确判断数据运算结果位宽。数字运算必须先通过wire指定位宽,然后通过assign得到运算结果。

错误代码中:

{1'b0,(cnt0+cnt1)} ,在if语句()拼接符号中,综合软件无法识别 (cnt0+cnt1)应该是多少bit,(cnt0+cnt1)可能会是5bit,也可能是4bit。

正确代码&推荐代码中

通过 wire [4:0] cnt_add ;  assign  cnt_add  = (cnt0+cnt1) ; 指定了(cnt0+cnt1)之和为5bit,利用拼接符指定{1'b0,cnt_add}为6bit,然后与6bit的cnt2比较。

正确代码&不推荐中

通过 wire [4:0] cnt_add ;  assign  cnt_add  = (cnt0+cnt1) ; 指定了(cnt0+cnt1)之和为5bit,但是直接与6bit的cnt2比较,各类综合软件也会正确识别位宽,不会发生截位,但是spyglass lint会报warning,虽然功能正确,但是不推荐。

//-------------case 2-----------------//
 reg  [3:0]   cnt0  ;
 reg  [3:0]   cnt1  ;
 reg  [5:0]   cnt2  ;
 
 //wrong code
 always @ (posedge clk or negedge rst_n) 
    if(!rst_n)begin
    count     <= 5'b0 ;
    end 
    else if({1'b0,(cnt0+cnt1)}

编辑:黄飞

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

全部0条评论

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

×
20
完善资料,
赚取积分