签名与比特大小

时间:2017-07-01 07:17:11

标签: verilog system-verilog

以下示例,我尝试使用模拟器,d2的值由符号扩展4'sd2 - i1创建。从我对标准(1800-2012)的阅读中,我希望将4'sd2 - i1视为无符号,并以与d1相同的方式对其进行零扩展。

我错过了什么? i1的无符号性是否会因为从2位扩展到4位而发生变化?感谢。

module sign_test(input clk, input /*unsigned*/ [1:0] i1,
                 output reg [7:0] d1, output reg [7:0] d2);
  always @(posedge clk) begin
    d1 = $unsigned(4'sd2 - i1); // this gets zero extended; the only possible values for 'd1' are 0, 1, 2 and 0x0f
    d2 = 4'sd2 - i1; // this gets sign extended; the only possible values for 'd2' are 0, 1, 2 and 0xff
    // but 11.8.1 says "4'sd2 - i1" should be unsigned:
    //  "-- For non-self-determined operands, the following rules apply:
    //       [...]
    //       -- If any operand is unsigned, the result is unsigned,
    //          regardless of the operator."
    // and 'i1' is unsigned by default (adding "unsigned"
    // explicitly doesn't change the behaviour).
  end
endmodule

1 个答案:

答案 0 :(得分:1)

我认为差异的原因不在于每个表达式是有符号还是无符号,而是与Verilog用于计算的位数有关。

这是上下文确定的表达式

d2 = 4'sd2 - i1; 

这意味着Verilog使用所有宽度的最大值(d24'sd2i1的宽度,即8(d2的宽度)。正如您所说,无符号算术已完成。2'b11的值为i1

d2 = 00000010 - 00000011

11111111

  d1 = $unsigned(4'sd2 - i1); 

但是,由于调用d1系统函数,因此不考虑$unsigned的宽度。这使得表达式4'sd2 - i1成为自定义表达式,因此用于计算的位宽为4 - 4'sd2i1的宽度的最大值。所以

0010 - 0011

1111

然后将其填充为

00001111

https://www.edaplayground.com/x/duY