iverilog/ivtest/ivltests/pr2922063.v

61 lines
1.9 KiB
Verilog

module top;
reg pass;
integer val;
initial begin
pass = 1'b1;
// Check ARS in a fully signed context.
// All operands are signed.
val = -1;
val = 7'sd10 + (val >>> 1);
if (val !== 9) begin
$display("Failed ARS in signed context, got %d", val);
pass = 1'b0;
end
// Check ARS in a cast signed context.
// This is fully signed as well because of the cast.
val = -1;
val = $signed(7'd10) + (val >>> 1);
if (val !== 9) begin
$display("Failed ARS in cast signed context, got %d", val);
pass = 1'b0;
end
// Check ARS in a self determined context.
// The system function is a primary and should create a self-determined
// context for the ARS. The addition is then done in an unsigned
// context, but this should still give the correct result.
//
// The bug is that Icarus is not sign padding the ARS since the
// addition is casting it to be unsigned. It should only be able to
// cast the sign of the result not the actual ARS! This casting is
// happening in suppress_binary_operand_sign_if_needed() defined in
// elab_expr.cc. It looks like $signed and $unsigned need some way
// to protect their argument self-determined context.
val = -1;
val = 7'd10 + $signed(val >>> 1);
if (val !== 9) begin
$display("Failed ARS in $signed context, got %d", val);
pass = 1'b0;
end
// Check ARS in a different self determined context.
// See comments above for $signed.
val = -1;
val = 7'd10 + $unsigned(val >>> 1);
if (val !== 9) begin
$display("Failed ARS in $unsigned context, got %d", val);
pass = 1'b0;
end
// Check ARS in a different self determined context.
val = -1;
val = 7'd10 + {val >>> 1};
if (val !== 9) begin
$display("Failed ARS in a concatenation context, got %d", val);
pass = 1'b0;
end
if (pass) $display("PASSED");
end
endmodule