当前位置:   article > 正文

Verilog基础:表达式符号的确定_verilog强制有符号

verilog强制有符号
相关文章

Verilog基础专栏icon-default.png?t=N7T8https://blog.csdn.net/weixin_45791458/category_12263729.html


表达式符号

如果想要在计算表达式中获得一直和谐的结果,那么控制表达式中的符号就很重要。有两个系统函数就是为了调整表达式符号,分别是$signed和$unsigned,它们的返回值就是被转换符号后的数值。

例如:

  1. reg [7 : 0] regA, regB;
  2. reg signed [7 : 0] regS;
  3. regA = $unsigned(-4); //regA = 8'b11111100
  4. regB = $unsigned(-4'sd4); //regB = 8'b00001100
  5. regS = $signed(4'b1100); //regS = -4

表达式符号规则

表达式符号规则如下所示。

  1. RHS表达式的符号不依赖于LHS,即使最后符号与LHS不同,那也只是在赋值时进行符号转换。

  1. 没有基没有位宽的常数为十进制有符号数,如12。否则必须在基数前声明s标志才表示这个常数为有符号的,如3'd4是无符号数,3'sd4是有符号数。

  1. 位选的结果是无符号数,不管位选操作数是否有符号。

  1. 域选的结果是无符号数,不管域选操作数是否有符号,即使域选的结果是整个向量。

  1. 拼接操作符的结果是无符号的,不管操作数是否有符号,即使是只有一个有符号操作数也是如此。

  1. 比较操作符的结果是无符号的,不管操作数是否有符号。

  1. real强制转换integer的结果是有符号的。

  1. 任何自决定操作数的符号由自己决定,独立于表达式的其他部分。

  1. 对于非自决定(上下文环境决定)的操作数(子表达式),如果某操作数是real,那么结果是real;如果某操作数无符号,则结果无符号;如果所有操作数有符号,结果才是有符号的。符号的嵌套和《表达式位宽的确定》一文中的一致。

在这里我们解决《表达式位宽的确定》一文中最后留下的问题,上下文操作数如何拓展位宽?答案就是,如果上下文环境的操作数全是有符号数,则上下文操作数在需要时会符号拓展,否则在需要时会补零拓展。

我们通过一个例子来直观体会

例子:

  1. module incrementer_with_overflow(input clock,resetN,
  2. input signed [7 : 0] in,
  3. output signed [8 : 0] out);
  4. always@ (posedge clock or negedge resetN)
  5. if(!resetN)
  6. out <= 0;
  7. else
  8. out <= in + 1'b1;
  9. endmodule

这里存在一个问题,当in的值是5时,out的值是6,此时是正确的;但是当in的值是-5时,out的值却是252,为什么会这样呢?

因为+是上下文操作符,左右的加数都是上下文决定位宽,且右操作数1'b1是一个无符号数,所以结果是无符号的,1'b1和in会按照无符号数的规则(补零)拓展至9位(因为上下文环境最大位宽的信号是out),当in为5时运算过程是正常的5+1=6;但当in为-5时,8位二进制补码表示为11111011,此时仍然补零拓展为011111011,且与000000001作无符号数加法,结果为011111100即252。

所以如果你想让结果正确,你需要让+号的右操作数也为有符号数,这样in才能作符号拓展并进行有符号数加法(实际上有符号数加法和无符号数加法是一样的)。

  1. 你可以把1'b1改成1,这样表示32位有符号数1。

  1. 你可以把1'b1改成2'sb1,这样表示2位有符号数1。

为什么不能把1'b1改成1'sb1呢?这是因为1'sb1只有符号位,在Verilog里面,它表示-1。所以如果你这样修改了,最后得到的结果是-5。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/不正经/article/detail/529061
推荐阅读
相关标签
  

闽ICP备14008679号