Trouble using fixed point type conversion in Simulink
조회 수: 9 (최근 30일)
I have a fairly large system I am converting to fixed point. I have made some progress by setting the input data types accordingly, and Simulink ripples the fixed-point types through the system. If I was happy with the bit widths, I'd be finished because the fixed point output matches the reference output.
However, I am trying to reduce bit widths. In one part of the system, Simulink gives a signal the type sfix31_En3, also known as fixdt(1, 31, 3). I want to reduce this to 24 bits. The largest value is 9107852, and ceil(log2(9107852)) = 24, so I need 24 bits to the left of the binary point, plus sign bit. To get that into a 24-bit signed representation, I need fixdt(1, 24, -1), hence the LSB is 2^1 not 2^0.
I have a Data Type Conversion block set to use this data type. However, it does not work according to my expectations. What I expect to see as an output is the same as if I were to take the input signal and cast it like so:
new_sig = fi(old_sig, 1, 24, -1)
or, if instead I defined truncated = fixdt(1, 24, -1), I can do this
new_sig = fi(old_sig, truncated)
When I apply the above line to the sfix21_En3 signal logged in Simulink, the result is as I expect. But when I specify that the type conversion block use fixdt(1, 24, -1), I get a "Warning: Parameter precision loss" message:
The original value of the parameter, -1, cannot be represented exactly using the run-time data type sfix24_E1. The value
is quantized to 0. Quantization error occurred with an absolute difference of 1 and a relative difference of 100%.
Also, the signal definitely does not look right - every other sample is set to zero, where it should be between 10^5 and 10^6.
I feel like I'm missing something in the use of this type conversion block. What's the proper way to reduce the bit width of a signal and get the binary point in the right place?
Thanks for any help/advice.
Andy Bartlett 2023년 2월 27일
편집: Andy Bartlett 님. 2023년 2월 27일
Check rounding and overflow handling mode
By default, the Data Type Conversion block rounds to Floor and Wraps overflows.
In contrast, by default, fi rounds to Nearest and Saturates overflows.
You'll need to move away from default behavior of one or both to get full input-output agreement for all possible input values.
Parameter Underflowing to Zero Could have Huge Impact
The data type fixdt(1,21,-1) that you've set for a signal seems to also get used for some parameter associated with the signal. Since the spacing between representable values is Slope = 2^1 = 2, the representable values are
-2097152, -2097150, ... -2, 0, 2, 4, ... 2097148, 2097150
so -1 is not representable and gets rounded to representable value 0.
Depending on how that parameter is used the impact of the quantization could be minor or huge.
For example, if the parameter is used in multiplication, then multiplying by the ideal value -1 will be very different than multiplying by the quantized value 0.
Figure out how the parameter is used in your model to determine the expected impact of quantization.
See if you can separate the data type used for the parameter from that used for the signal. For example, suppose the -1 was the parameter value of a gain block. If the data type of the gain parameter was configured to be Same As Input, then it could be changed to Inherit via Internal Rule or fixdt(1,2,0) to accurately represent -1.