Integer rounding mode set to Simplest in Simulink.
25 visualizzazioni (ultimi 30 giorni)
Mostra commenti meno recenti
Hello, I have a Matlab model where all the conversion,divide, etc blocks are having the Integer rounding mode set to simplest.
The scope is to verify the component (using Simulink test). My plan was to build a formula for the outputs, create test vectors and have a baseline for the outcomes.
The model implementation is mostly based on calculations. Because of this SIMPLEST option, it is challeging since the intermediate results are unpredictable.
Ex: a divide block (integer rounding mode set to simplest) with 2 inputs -40 and 1 => the output will be -41.
Is there any way to predict this kind of results?!
Thank you very much!
Diana.
0 Commenti
Risposte (1)
Andy Bartlett
il 18 Mar 2024
Modificato: Andy Bartlett
il 18 Mar 2024
Hi,
The Divide Blocks output should be predictable. The behavior of Simplest Rounding is documented here. If you are using fixed-point data types with Slope-and-Bias scaling, then that is a little more difficult to analyze. If all the inputs and outputs are integer or fixed-point with binary-point scaling, then division with simplest rounding should behave exactly the same as round to zero.
Not clear how you got -40 divided by 1 equals -41.
I suggest you configure your Simulink model's Debug-Overlays to show Base Data types. Write down the data types for the inputs and output of the divide block in question. You could also log the input and output signal values for the Simulink simulation to MATLAB. Then display those values in high precision, say using mat2str( val, 22, 'class' ).
If you have Simulink Coder, you could also generate C code for the block. The C code will show you exactly what happens in what order. If the inputs and outputs to the division are all integer, then for simplest rounding the expected C code would be something like.
int32_t u1;
int32_5 u2;
int32_5 y;
...
y = u1 / u2;
The C standard from 1999 specifies that the integer divide / must provide round to zero behavior.
As a side note, for creating the test values fixed.DataGenerator could be helpful. It will create pairs of numerically rich value combinations that you can use to test the division and other operations.
Andy
2 Commenti
Will Walker
il 18 Mar 2024
Hi Diana,
If using division to represent non-power of 2 scaling is agreeable, you can use this parameter in your model (set to 'on'): https://www.mathworks.com/help/simulink/gui/use-division-for-fixed-point-net-slope-computation.html
For this multiplciation, it will produce the expected results (so long as "simplest" rounding is used and the target defines "signed integer divisions rounds to" as "zero").
As to the results observed with the above mentioned parameter 'off', what is happening is a two step process:
- Peform a binary point multiplication
- Apply non-power of 2 scaling
We can represent the multiplication as follows:
Q0 * Q1 * 0.01 = Qout
Where "Q0" represents the int16 operand and "Q1 * 0.01" represents the second operand and "Qout" is the resulting product.
We can normalize the non-power of 2 scaling as follows:
Q0 * Q1 * 1.28 * 2^-7 = Qout
In order to perform step 1 from above (binary point multiplication) we move things around a bit to get this:
(Q0 * Q1 * 2^-7) * 1.28 = Qout
Since "1.28" is not an integer value, we need to quantize it as follows:
((Q0 * Q1 * 2^-7) * 5423) * 2^-12 = Qout
This is somewhat similar to the generated code you will see, only we need to change the multiplications by negative powers of 2 into right shifts:
(((Q0 * Q1) >> 7) * 5423) >> 12 = Qout
The problem is, three points where "errors" get introduced due to the need to represent the operations as integer operations.
(Q0 * Q1) >> 7 will round the result down (floor)
5423 * 2^-12 is an approximation to 1.28 (it is 1.280029296875 in "double")
>> 12 (the final shift) will round the result down (floor)
The end result is a value that is below what may be expected, but is done in favor of generated code efficiency.
If the above mentioned parameter is used, we get something a little different:
(Q0 * Q1) / 100 = Qout
Which will provide more accurate results (but come at the cost of a division compared to multiplications and shifts).
Regards,
Will
Vedere anche
Categorie
Scopri di più su Inputs in Help Center e File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!