- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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 80Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- 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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- 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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- 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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- 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 ---
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page