以下示例,我尝试使用模拟器,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
答案 0 :(得分:1)
我认为差异的原因不在于每个表达式是有符号还是无符号,而是与Verilog用于计算的位数有关。
这是上下文确定的表达式:
d2 = 4'sd2 - i1;
这意味着Verilog使用所有宽度的最大值(d2
,4'sd2
和i1
的宽度,即8(d2
的宽度)。正如您所说,无符号算术已完成。2'b11
的值为i1
:
d2 = 00000010 - 00000011
是
11111111
用
d1 = $unsigned(4'sd2 - i1);
但是,由于调用d1
系统函数,因此不考虑$unsigned
的宽度。这使得表达式4'sd2 - i1
成为自定义表达式,因此用于计算的位宽为4 - 4'sd2
和i1
的宽度的最大值。所以
0010 - 0011
是
1111
然后将其填充为
00001111