Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
9 years ago

Unsigned to signed conversion and its simulation in Modelsim

Hello dear friends,

I am having an unsigned number of the input and need to sign extend it and negate (2s representation) if in the specific condition occurs (say if sign=1, to simplify)

Here is my code in SystemVerilog:

module signed_unsigned (

sign,

clk,

data_in,

data_out);

input logic sign;

input logic clk;

input unsigned [7:0] data_in;

output signed [8:0] data_out;

always_ff @ (posedge clk) begin

if (sign)

data_out <= -data_in;

else

data_out <= data_in;

end

endmodule

It looks like it analyzed properly in Quartus (see RTL representation in the attachment). However, when I simulate in Modelsim it doesn't show the correct result.

In the testbench I have a clock generator and just assignments to the data_in. I expect to see 101 value for 0xFF, 156 for 0xAA, etc but nothing happens. the numbers are same

What can be wrong? I am very confused.

Cheers,

3 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    I will use signed(for unsigned addt one MSB at zero)

    e.g. assuming 8 bit signed:

    if...

    data <= input;

    else

    data <= -input

    end
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    This works for me after making one correction unrelated to the signed issue. data_out needs to be a variable in order to make procedural assignments to it. You have it declared as a wire. (you are also using Verilog-1995 style ports, which I updated)

    module signed_unsigned (
      input logic sign,
      input logic clk,
      input unsigned  data_in,
      output logic signed  data_out
    );
      always_ff @ (posedge clk) begin
      if (sign)
        data_out <= -data_in;
      else
        data_out <= data_in;
      end
    endmodule

    It would have helped to show the testbench you were using. Here is what I used.

    module top;
       bit clk, sign;
          logic unsigned  data_in;
       logic signed  data_out;
     
      always# 5 clk++;
       
      initial begin
          sign=1;
          data_in = 8'hff;
       @(negedge clk)
         $displayh(data_in,,data_out);
          data_in = 8'hAA;
       @(negedge clk)
          $displayh(data_in,,data_out);
         sign=0;
          data_in = 8'hff;
       @(negedge clk)
         $displayh(data_in,,data_out);
          data_in = 8'hAA;
       @(negedge clk)
          $displayh(data_in,,data_out);
         $finish;      
    end
       signed_unsigned su(.*);
       
    endmodule : top

    And the output I got

    # Loading work.top(fast)
    #  run -all
    #  ff 101
    #  aa 156
    #  ff 0ff
    #  aa 0aa
    #  ** Note: $finish    : signed.sv(25)
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Thank you, dave_59. It is working now! My testbench was a bit crooked too :)