- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I have implemented a divider in a custom VHDL module in order to replace the instances of the LPM_DIVIDE IPs in my project. I've then checked the functionality of my module against the LPM_DIVIDE and verified through a simulation that, with the exception of a different initial latency, my divider behaves exactly the same way of the LPM_DIVIDE IP, covering all the dynamic of the input operands. The problem is that when I test it on the hardware, I have some slightly different results. Debugging the problem with SignalTap, I verified that the problem was due to a different behavior of the LPM_DIVIDE IP on the hardware with respect to the simulation. I verified that the different behavior occurs when the result of the division has a negative sign. I have attached the results of the simulation and of the acquisition on SignalTap in case of a division between a negative numerator and a positive denominator. The correct result should be the one of the simulation (0xFF..FFF4FF), but for a reason that I still don't understand, in the hardware implementation the result is 0xFF..FFF4FE. Do you have any suggestion? Is there some kind of rounding in the implementation that is not present in the simulation model?
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
If you check the simulation, the 0xFF..FFF4FF is under 010139F1A9h.
However in signal tap, you're checking under 010131CEB9h.
May be use other trigger condition to trigger the 0xFF..FFF4FF under 010139F1A9h, may be use transitional.
Thanks,
Regards,
Sheng
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Sheng, thank you for the answer. The 0xFF..FFF4FF (quotient) output is under 010139F1A9h (denominator) and 7FFFFA7872h (numerator) in the simulation because I've simulated the divider standalone in order to check its behavior feeding the IP only with those operands. In HW the divider is part of a more complex design and it is fed in pipeline with a stream of operands. That's the reason why in SignalTap you also see the subsequent operands, but the 0xFF..FFF4FE is the result of the first two operands of the stream, that are the same of the simulation:
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
Pipeline will add latency. Could you simulate the whole complex design with pipeline instead of just divider standalone? What will be seen?
Thanks,
Regards,
Sheng
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Sheng.
The number of pipeline stages is a parameter of the divider and I use the same value both in the simulation and in the implementation. There are no differences. The entire complex design is impossibile to simulate due to its size. What can I do is to simulate and implement a simple one only with the divider and an operands generator inside, monitoring the outputs both in simulation and in signaltap. I think that I'll see the same behavior. Il post the results here in the next days.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
Understood that. Please let me know whether simple one only with the divider and an operands generator inside got same simulation and signal tap?
Thanks,
Regards,
Sheng
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Sheng,
I've implemented this simple selfchecking module, which instantiates only the LPM_DIVIDE, stimulated with 1000 couple of operands. I've simulated the module, synthesized and checked its behavior with SignalTap. As I though, the strange behaviour previously observed is present also in this version:
Considering the first operation:
Operands:
Numerator = FFFFFFEC82000000h = -83718307840d
Denominator = 000000000Bh = 11d.
The result is -83718307840/11 = -7610755258.181818 or -7610755258 with a remainder of -2, that are the outputs provided by the module during the simulation: Quotient: FFFFFFFE3A5D1746h and Remainder: 7FFFFFFFFEh
On the other side, the implemented divider publishes these results:
Quotient: FFFFFFFE3A5D1745h and remainder of 0000000009h, which are different from the one seen during simulation.
I've tested the module using Quartus Prime Version 20.1.1 Build 720 11/11/2020 Patches 1.02std SJ Standard Edition implementing it on a Arria 10 10AX066K4F35I3SG.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Sheng, I've implemented a simple module which instantiates the LPM_DIVIDER only and a process that feeds the divider with 1000 couples of operands. As I expected, I've seen the same strange behavior of the implemented module which is different from the simulation when the quotient is negative. The following figure show this difference:
I've taken into consideration only the first division of the sequence, since the problem is the same also in the subsequent divisions. Operands:
Numerator = FFFFFFEC82000000h = -83718307840d; Denominator = 000000000Bh = 11d.
Quotient (SignalTap) = FFFFFFFE3A5D1745h = -7610755259d; Remainder (SignalTap) = 0000000009h = 9d.
Quotient (Simulation) = FFFFFFFE3A5D1746h = -7610755258d; Remainder (Simulation) = 7FFFFFFFFEh = -2d.
If can be of some help, I've implemented the module on a ARRIA10 FPGA (10AX066K4F35I3SG) using the following version of Quartus Prime: Quartus Prime Version 20.1.1 Build 720 11/11/2020 Patches 1.02std SJ Standard Edition.
Thank you,
Marco
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
Could you provide the project file for taking a look?
Thanks,
Regards,
Sheng
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Sheng,
since the ARRIA10 board is a custom board, I've done another project using the Intel MAX10 FPGA Development kit and simply instantiated the lpm_divide_self_operands_gen.vhd in the top module. I've checked again the outputs of the divider with signal tap, confirming that also with that device I see the same behavior. I attached the whole project (I deleted the ./db subfolder otherwise the compressed file would have been more than 23MB allowed for the attachments). There is also the signal tap inside the project, which shows the following, triggering with operands_counter = 1:
Considering this, I don't think it's an issue of the device.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
Possible provide the testbench as well for simulation?
Thanks,
Regards,
Sheng
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Reduce the following constant:
constant INITIAL_WAIT : natural := 200000000; -- 2 seconds
to
constant INITIAL_WAIT : natural := 200000; -- 2 seconds
otherwise the simulation will wait 2 seconds before starting to generate the operands. Attached the updated code, with the initial_wait reduced.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
I observe that if change pipeline number, the signal tap results will be different.
I suspect is the timing issue. Could you add .sdc file to check is that the timing pass? Make sure the timing is pass.
Thanks,
Regards,
Sheng
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
Please ignore the previous post. I had found the root cause.
Please use the LPM_DIVIDE megafunction from IP Catalog instead of direct using the component because there're some parameters you set not properly. For example.
Denominator width can't be set to 39 if check the dropdown screenshot:
Pipeline can't be set more than numerator width screenshot:
After using the LPM_DIVIDE megafunction from IP Catalog, I get the correct simulation result screenshot:
Thanks,
Regards,
Sheng
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Sheng,
I think that the problem is not the number of pipeline stages nor the size of the denominator (even if both the limitations are not clear for me), but following your suggestion I've tried the IP catalog, instead of instantiating directly the IP in the code. I've noticed that at a certain point of the personalization GUI of the IP, there are two radio boxes which allows the user to select the sign of the remainder:
Depending on the selection, this changes the value of the generic parameter "LPM_HINT" of the LPM_DIVIDE:
lpm_hint => "LPM_REMAINDERPOSITIVE=FALSE", when No has been selected
lpm_hint => "LPM_REMAINDERPOSITIVE=TRUE", when Yes has been selected
Setting the generic LPM_HINT => "LPM_REMAINDERPOSITIVE=TRUE" in the code, even the lpm_divide_self_operands_gen.vhd returns the same result of signal_tap.
In the lpm_divide_self_operands_gen.vhd i posted previously, the parameter was set to "UNUSED". Checking here: https://www.intel.com/content/www/us/en/docs/programmable/683490/24-1/parameters-72926.html , the parameter was not required, and in any case I get the parameter value from the component declaration in LPM_PACK.vhd in the < Quartus® Prime installation directory>\libraries\vhdl\lpm directory, by default is set to "UNUSED".
I see 2 issues here:
- Leaving the parameter LPM_HINT => "UNUSED" causes a mismatch between the simulation and the implementation, because the behaviour of the IP in simulation is like the parameter is set to FALSE, while in implementation the remainder sign is always positive, therefore like the parameter is set to TRUE. Therefore the parameter shall be set to a value and not leaved "UNUSED", or somehow Quartus should alert the user for this mismatch!
- Even setting LPM_REMAINDERPOSITIVE = TRUE, the quotient is not correct, since, for example, if you try a simple division like -5/3, the result should be -1 with a remainder of -2, while the IP returns -2 with a remainder of 1. That's obviously not correct, and I didn't expect that changing that parameter changes also the values of quotient and remainder, but only the sign of the remainder, as the name of the parameter and the explanation provided in the guide states.
For confirmation, I attached a more simple version of the lpm_divide_self_operands_gen.vhd, where I instantiate 3 version of the LPM_DIVIDE function with only 1 stage of pipeline, as you suggested and with the parameter LPM_HINT set to "LPM_REMAINDERPOSITIVE=TRUE", "LPM_REMAINDERPOSITIVE=FALSE" and "UNUSED". I also update the lpm_divide_self_operands_gen_tb.vhd setting the denominator width to 32 (it is an allowed value). The operators are now simply -5 and 3. If you simulate the module you'll get that the outputs are the following:
So we get 2 different quotient and remainder values, not only the sign of the remainder changes setting the LPM_HINT parameter. The s_quotient_hint_rem_pos_true value is not correct and is the value that we have in HW leaving the parameter "UNUSED", that's different from the value that we have in simulation. On signaltap (I also attached the updated Quartus Project), we see:
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
Yes, when tick Yes the LPM_HINT will use "LPM_REMAINDERPOSITIVE=TRUE" while tick No the LPM_HINT will use "LPM_REMAINDERPOSITIVE=FALSE". If LPM_HINT uses either "LPM_REMAINDERPOSITIVE=TRUE" or "LPM_REMAINDERPOSITIVE=FALSE", the results between simulation and signal tap are same.
If LPM_HINT use "UNUSED", the results between simulation and signal tap are not same. Please don't use "UNUSED" because correct usage are "LPM_REMAINDERPOSITIVE=TRUE" or "LPM_REMAINDERPOSITIVE=FALSE" for LPM_HINT.
So we can conclude the LPM DIVIDE behaves same between simulation and signal tap right? which answer the title of this thread.
So there's another new question regarding functionality right?
Thanks,
Regards,
Sheng
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
For functionality in this post community.intel.com/t5/Intel-Quartus-Prime-Software/LPM-DIVIDE-behaves-differently-between-simulation-and/m-p/1672473#M85726, i think should be no problem check below:
For a numerator of −5 and a denominator of 3, using the LPM (Library of Parameterized Modules) IP division method where the remainder is always positive, we follow these rules:
Quotient Calculation: Perform integer division (truncate towards zero):
−5÷3=−1(integer division)
Remainder Calculation:
remainder=numerator−(quotient×denominator)
remainder=−5−(−1×3)=−5+3=−2
However, since LPM IP requires a positive remainder, we adjust by adding 3 to remainder and reducing quotient by 1:
new quotient=−1−1=−2
new remainder=−2+3=1
Final Result:
LPM_HINT => "LPM_REMAINDERPOSITIVE=TRUE":
quotient=-2
remander=1
LPM_HINT => "LPM_REMAINDERPOSITIVE=FALSE":
quotient=-1
remander=-2
The simulation and signal tap result for LPM_HINT => "LPM_REMAINDERPOSITIVE=TRUE" and LPM_HINT => "LPM_REMAINDERPOSITIVE=FALSE" are correct.
Only the result for LPM_HINT => "UNUSED" is incorrect, please don't use LPM_HINT => "UNUSED" (Incorrect Usage)
And for the numerator and denominator width you can use from 1 to 64 if check this document https://www.intel.com/content/www/us/en/docs/programmable/683490/20-3/parameters-72926.html. Sorry I was mislead by the dropnow menu.
Thanks,
Regards,
Sheng
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Sheng,
thank you very much for the detailed information about the IP’s functionality. However, in my opinion, the issue of the mismatch between simulation and implementation cannot be considered resolved, as I would like to understand:
- Where is it stated in Altera's documentation that using the parameter LPM_HINT => "UNUSED" is incorrect, as you mentioned?
- If LPM_HINT => "UNUSED" is incorrect, why is it assigned as the default value in the module declaration inside lpm_pack.vhd?
To truly resolve the issue and prevent it from occurring in the future for other users, I believe that the simulation model of LPM_DIVIDE should be updated so that the behavior in simulation matches the implemented behavior, regardless of the value of the LPM_HINT parameter.
Regards,
Marco.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Marco,
Please check this link http://www.pldworld.com/_altera/html/_sw/q2help/source/mega/mega_file_lpm_divide.htm
Altera also recommends instantiating this function as described in Using the MegaWizard® Plug-In Manager.
It's better to instantiate that function through MegaWizard Plug-In Manager.
Thanks,
Regards,
Sheng

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page