Forum Discussion

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

simple verilog question...

hi there!

im trying to determine the root cause of an error i keep getting.

Basically I'm trying to convert a 2's complement value, lets say binary X to

decimal Y (i do this by multiplying it with a constant [i.e. 625]).

1) so I do this, and it works perfectly.

assign X_n = ~X - 1;

always@(posedge CLK)

begin

Y = X_n * 625;

end

2)BUT I can't do this:

always@(posedge CLK)

begin

Y = (~X - 1) * 625;

end

I get a weird number with the second case. Does anyone know why??

Thanks in advance! This question has been bugging me for some time.

7 Replies

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

    thanks for the response Kaz!

    Let me break it down a bit more however. The two expressions are actually the same (logically). But the outcome is different. In other words,

    assign X_n = ~X;

    always@(posedge CLK)

    begin

    Y = X_n * 625;

    end

    DOES NOT equal the below equation

    always@(posedge CLK)

    begin

    Y = ~X * 625;

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

    Seriously, we can't know what's the expectable or correct result without knowing the involved data types. Bit width of signals is most likely the key to understand why the results are different. When assinging X_n = ~X - 1, the result is truncated to a specified width. In Y = (~X - 1) * 625, the intermediate result gets a default width of 32 bit.

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

    --- Quote Start ---

    thanks for the response Kaz!

    Let me break it down a bit more however. The two expressions are actually the same (logically). But the outcome is different. In other words,

    assign X_n = ~X;

    always@(posedge CLK)

    begin

    Y = X_n * 625;

    end

    DOES NOT equal the below equation

    always@(posedge CLK)

    begin

    Y = ~X * 625;

    end

    --- Quote End ---

    I deleted my initial post because it turned out unrelated !!

    you started presenting your problem as 2's complement conversion ...But the issue is actually about two apparently equivalent expressions having two results.

    What I supposed first was this:

    unsigned to signed: invert bits then add 1

    signed to unsigned :subtract 1 then invert bits = invert bits then add 1

    clearly irrelevant but the order of operations is important.

    Regarding your issue, I suggest you post your entire code.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Im also think there is somthing involved in your data types.

    Can you show a snipset of the code with the data types and width included?
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Here is the code in question...

    --- Quote Start ---

    input [11:0] input_temp;

    output [7:0] actual_temp; //actual temperature

    reg [21:0] temp;

    wire [10:0] input_temp_n;

    assign actual_temp = temp/10000;

    assign input_temp_n = (~input_temp[10:0]) + 1;

    always@(posedge iCLK)

    begin

    if(!input_temp[11])

    begin

    temp = (input_temp[10:0] * 625);

    end

    else

    begin

    temp = (input_temp_n * 625);

    //offending code

    //temp = ((~input_temp[10:0] + 1) * 625);

    end

    end

    --- Quote End ---

    BTW sorry for lack of indentation. i dont know why but these forums kill my indentation. anyone know how to fix?
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Hi,

    I had a quick go at your code and reproduced your finding.

    Your design is not constrained in the sense of data bitwidth into and out of operations.

    in the first expression, your multiplier gives correct output.

    in the second expression, your multiplier gives correct output for 11 bits only, other bits are set by compiler to wrong values, apparently considered as don't care.

    I also notice that you are keeping positive input values but forcing negative input values to positive. Is that what you really intend to do?

    I suggest you declare signed types for inputs and outputs and constrain the width of all your results at all stages.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    I already mentioned, that the intermediate result bitwidth causes a different result. Thus I had been asking for the definition of data types used in the original example, but we face considerably different Verilog text in each post. Consequently, the results are different for each example. I miss a clear question now.