Forum Discussion
7 Replies
- sstrell
Super Contributor
Why do you even need $signed here? If you're using arithmetic shift right (>>>) it would automatically shift in 1's to maintain the sign if the MSB is 1.
And also realize that Quartus 12.1 is now a 12 year old version of the tool. Have you tried anything more recent?
- FvM
Super Contributor
It's no bug.
IEEE 1800-2017, 11.4.10 Shift operators specifies:
The arithmetic right shift shall fill the vacated bit positions with zeros if the result type is unsigned. It shall fill the vacated bit positions with the value of the most significant (i.e., sign) bit of the left operand if the result type is signed. (...) The result signedness is determined by the left-hand operand and the remainder of the expression, as outlined in 11.8.1.
As the result type in example is unsigned, the observed behaviour is correct.
- ShengN_altera
Super Contributor
Hi,
Based on the statement provided by FvM, have to do modification to the code like below:
module test(
input wire signed [31:0] in,
input wire [4:0] shift_amount,
input wire signext,
output wire signed [31:0] out
);
assign out = signext ? ($signed(in) >>> shift_amount) : (in >> shift_amount);
endmodule
RTL viewer:
Thanks,
Best regards,
Sheng
- sstrell
Super Contributor
So why is $signed still needed if in is already signed in this code? I don't see the need for $signed at all.
- FvM
Super Contributor
There's no need for $signed(), neither in must be signed. Operation of arithmetic shift is solely determined by result signedness.- sstrell
Super Contributor
That's what I was thinking originally. Just the fact that >>> is used would preserve the sign bit by shifting in 1's if it's 1.
- ShengN_altera
Super Contributor
Thanks sstrell and FvM for mentioning. Ya, it can be either way like below.
First:
module test(
input wire signed [31:0] in,
input wire [4:0] shift_amount,
input wire signext,
output wire signed [31:0] out
);
assign out = signext ? (in >>> shift_amount) : (in >> shift_amount);
endmodule
Second:
module test(
input wire [31:0] in,
input wire [4:0] shift_amount,
input wire signext,
output wire signed [31:0] out
);
assign out = signext ? ($signed(in) >>> shift_amount) : ($signed(in) >> shift_amount);
endmodule