assign和signed的联合背刺事件

电子说

1.3w人已加入

描述

没想到啊没想到啊,有一天会被浓眉大眼的assign背刺!想当年在always消失术里,在X态分析里,在xprop平替策略里,把assign捧的这么高,优点说了800多项,然后今天一仿真出bug了?!

还有有符号数和无符号数,我都吹出去了已经大成大成了,这还能出错?!

万事皆有可能,于是就出现了这个事。

事情的根源简化完就是下面这个语法,当sel为0时输出i_a高位补零的右移结果(相当于视i_a为无符号数),sel为1时输出i_a高位补符号位的输出结果相当于视i_a为有符号数):

//test
wire [31:0]i_a = 32'hff00_0000;
wire       sel = 1'b1;


wire [31:0]en0     = (sel == 1'b0) ? i_a > > > 8 : 
                                     $signed(i_a) > > > 8;

wire [31:0]en1_mid = $signed(i_a) > > > 8;
wire [31:0]en1     = (sel == 1'b0) ? i_a > > > 8 : en1_mid;

好,大家先看着这en0和en1的值。

en0和en1的值分别是啥呢?

仿真器

en0 = 32'h00ff_0000;

en1 = 32'hffff_0000;

问题出在哪呢?前面咱们总结过:有符号数和无符号数运算,结果为无符号数。这句话不太严谨,应该完善为:有符号数和无符号数运算,所有的运算数会被视为无符号数,结果为无符号数。

因为en0运算公式中,有符号数和无符号数混合运算了,有符号数和无符号数混合时会自动将所有的变量视为无符号数进行运算,而这个混合运算很难发现:

wire [31:0]en0     = (sel == 1'b0) ? i_a > > > 8 : $signed(i_a) > > > 8;

对,i_a >>> 8是个无符号数的运算!/(ㄒoㄒ)/~~所以带着signed(i_a) >>> 8也变成了无符号数的运算。所以说如果把signed(i_a) >>> 8单提出来先算好,再参与选择逻辑就是预期的结果了。

那么最后一个小问题,选择逻辑参与不参与这个有符号数和无符号数的争端呢?不参与,比如代码改成这样:

wire [31:0]en0     = (sel == 1'b0) ? $signed(i_a > > > 8) : $signed(i_a) > > > 8;

我把前面的运算结果通过$signed扩了一下,然后再仿真:

仿真器

这说明了两个问题:

1.选择逻辑没有参与到有符号数和无符号数的判定中;

2.判定时signed(i_a) >>> 8,看的是同一级别的其他运算项的符号属性,比如此时他看的是signed(...);

再改一下就又回去了:

wire [31:0]en0     = (sel == 1'b0) ? $signed(i_a > > > 8) + 1'b1 : $signed(i_a) > > > 8;

仿真器

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

全部0条评论

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

×
20
完善资料,
赚取积分