Intel® Quartus® Prime Software
Intel® Quartus® Prime Design Software, Design Entry, Synthesis, Simulation, Verification, Timing Analysis, System Design (Platform Designer, formerly Qsys)

Modelsim addition bug

Altera_Forum
Honored Contributor II
2,961 Views

It seems that Modelsim truncates additions inappropriately. It appears that it uses the left hand side of an assignment to truncate the result of an additiion, even if that is not the final value. In the code below, the addition gets truncated to the length of the left hand side of the assignment first, and then further right shifted. It should preserve a bit length of the longest term in the addition plus one bit (for the carry). The truncation should only happen at the actual assignment.  

 

module sandbox; 

reg [8:0] apple; 

reg [7:0] banana; 

 

initial beginbanana = 8'hff; 

apple = (banana + 1'b1)>>1; 

banana = (banana + 1'b1)>>1; 

$display("%x %x", apple, banana); 

 

end 

endmodule 

 

The output is 

080 00 

While I expected 

080 80
0 Kudos
8 Replies
Altera_Forum
Honored Contributor II
570 Views

 

--- Quote Start ---  

It seems that Modelsim truncates additions inappropriately. It appears that it uses the left hand side of an assignment to truncate the result of an additiion, even if that is not the final value. In the code below, the addition gets truncated to the length of the left hand side of the assignment first, and then further right shifted. It should preserve a bit length of the longest term in the addition plus one bit (for the carry). The truncation should only happen at the actual assignment.  

 

module sandbox; 

reg [8:0] apple; 

reg [7:0] banana; 

 

initial beginbanana = 8'hff; 

apple = (banana + 1'b1)>>1; 

banana = (banana + 1'b1)>>1; 

$display("%x %x", apple, banana); 

 

end 

endmodule 

 

The output is 

080 00 

While I expected 

080 80 

--- Quote End ---  

 

 

Though I sympathesise with ModelSim adding apples to bananas but the banana basket is only 8 bits so adding '1' causes overflow of basket and results in zeros which are then shifted to give zeros
0 Kudos
Altera_Forum
Honored Contributor II
570 Views

 

--- Quote Start ---  

Though I sympathesise with ModelSim adding apples to bananas but the banana basket is only 8 bits so adding '1' causes overflow of basket and results in zeros which are then shifted to give zeros 

--- Quote End ---  

 

 

But there is no overflow in the line apple = (banana + 1'b1)>>1; 

The right hand side is exactly the same.  

The weird thing is that the expression "banana + 1'b1" yields different results based on the size of the left hand side.
0 Kudos
Altera_Forum
Honored Contributor II
570 Views

 

--- Quote Start ---  

But there is no overflow in the line apple = (banana + 1'b1)>>1; 

The right hand side is exactly the same.  

The weird thing is that the expression "banana + 1'b1" yields different results based on the size of the left hand side. 

--- Quote End ---  

 

 

But the apple basket is 9 bits and so it does not overflow. The expression banana + 1 is evaluated correctly without overflow but then inserted into the basket and so result differs depending on basket size.
0 Kudos
Altera_Forum
Honored Contributor II
570 Views

This is a tool issue. I assume the shift occurs after result of addition is put into basket rather than add shift then insert. I am just explaining my assumption about your observation. 

 

Or put this way: modelsim does not do any bit extension and just uses your register sizes.
0 Kudos
Altera_Forum
Honored Contributor II
570 Views

So, you are saying that if the left hand side is 8 bits, then the default size for all calculations on the right hand side will also become eight bits, even for intermediate results and even if that leads to data loss. That's a pretty poor way to do calculations.

0 Kudos
Altera_Forum
Honored Contributor II
570 Views

I don't expect the tools to do all the work for me. So I have to observe its beheviour.  

In our mind we can add, shift...etc freely without space limitations. 

The tool in your case is told the container banana is 8 bits then you ask the tool to add 1 so it decides to throw away that extra bit (the carry bit). They could have done it the other way to include the carry bit and throw away the lsb but this is a matter of standards. 

 

I know if add in vhdl 1 to 8 bit register set to FF then I get zero.
0 Kudos
Altera_Forum
Honored Contributor II
570 Views

I would have expected it to keep the carry bit until it was discarded in the assignment, not to discard it right away. But a bit of experimentation shows me that you are right. But when I change the code to 

banana = (banana + 1)>>1; 

I do get the expected value of 8'h80. Presumably because 1 is 32 bits long. So the length it uses is the max of the operands and the LHS.
0 Kudos
Altera_Forum
Honored Contributor II
570 Views

 

--- Quote Start ---  

This is a tool issue. I assume the shift occurs after result of addition is put into basket rather than add shift then insert. I am just explaining my assumption about your observation. 

 

Or put this way: modelsim does not do any bit extension and just uses your register sizes. . 

--- Quote End ---  

 

 

Modelsim does what IEEE 1364 requires. Before blaming the tool, take a look at the Verilog specification which discusses an example similar to the present one. 

 

--- Quote Start ---  

5.4.2 Example of expression bit-length problem 

During the evaluation of an expression, interim results shall take the size of the largest operand (in case of an assignment, this also includes the left-hand side). Care has to be taken to prevent loss of a significant bit during expression evaluation. The example below describes how the bit lengths of the operands could result in the loss of a significant bit. 

 

Given the following declarations: 

 

reg [15:0] a, b, answer; // 16-bit regs 

 

the intent is to evaluate the expression 

 

answer = (a + b) >> 1; //will not work properly 

 

where a and b are to be added, which can result in an overflow, and then shifted right by 1 bit to preserve the carry bit in the 16-bit answer. 

A problem arises, however, because all operands in the expression are of a 16-bit width. Therefore, the expression (a + b) produces an interim result that is only 16 bits wide, thus losing the carry bit before the evaluation performs the 1-bit right shift operation. 

--- Quote End ---  

0 Kudos
Reply