Forum Discussion
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
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: