Forum Discussion
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
Honored 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.
- Altera_Forum
Honored 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
Honored 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
Honored 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
Honored 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
Honored 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
Honored 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