Incorrect result from shift operation
Closed this issue · 2 comments
module top();
reg signed [1:0] shift;
reg [31:0] y;
initial begin
shift = 2'b10;
y = 32'd7 << shift[1:0];
$display("%b", y);
end
endmodule
When running this test code, Icarus Verilog returns:
00000000000000000000000000000000
However, when testing the same code with Jasper 2022.09, Jasper returns:
00000000000000000000000000011100
Our initial analysis suggests that the 'shift' variable was treated as signed and sign-extended, which resulted in a left shift amount that was too large, causing the final result to be zero.
According to the IEEE Standard for SystemVerilog 1800-2017:
The right operand is always treated as an unsigned number and has no effect on the signedness of the result.
Therefore, during the extension, 'shift' should be treated as unsigned, and the final shift amount should be 2'b10 (which is 2 in decimal). The correct result should be ’11100‘, not all zeros.
Thanks for reporting this. This seems to be a general issue when loading a vector slice into an index register (a implementation detail of the icarus runtime).
Fix is in #1166. Still need to write a few regression test cases before this is ready to be merged.
This should have been treated as an unsigned shift since a part select shift[1:0]
is always treated as unsigned.