Forum Discussion

bionukg's avatar
bionukg
Icon for New Contributor rankNew Contributor
2 years ago

Quartus 12.1 Verilog bug: $signed() with >>> operation is ineffective.

module test(
    input wire [31:0] in,
    input wire [4:0] shift_amount,
    input wire signext,
    output wire [31:0] out
);

assign out = signext ? ($signed(in) >>> shift_amount) : (in >> shift_amount);
endmodule

	Warning (15610): No output dependent on input pin "signext"

Version: Quartus 12.1 64-bit on Windows 10; 13.1.0 Build 162 10/23/2013 SJ Full Version

HDL: Verilog

7 Replies

  • sstrell's avatar
    sstrell
    Icon for Super Contributor rankSuper 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's avatar
      FvM
      Icon for Super Contributor rankSuper 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's avatar
    ShengN_altera
    Icon for Super Contributor rankSuper 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's avatar
    sstrell
    Icon for Super Contributor rankSuper 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's avatar
      FvM
      Icon for Super Contributor rankSuper Contributor
      There's no need for $signed(), neither in must be signed. Operation of arithmetic shift is solely determined by result signedness.
      • sstrell's avatar
        sstrell
        Icon for Super Contributor rankSuper 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's avatar
    ShengN_altera
    Icon for Super Contributor rankSuper 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