help required for fixed point conversion
25 views (last 30 days)
I am modelling a encoder angle decoder control system in simulink. First I built a model with floating point and it works fine. When I am trying to convert it to fixed point, I am landing in trouble. After examining my model, I discovered that my model has subtractor that takes in set point as one input and other from feedback from the plant. The issue is that subtractor output has range (as captured by fixed point designer tool) from -0.00021679 to 0.01076. This translated to fixed point value of (1,32,37). Since this is out of range, the simulated result is erratic. How can I correct this error?
Andy Bartlett on 4 Apr 2023
Edited: Andy Bartlett on 4 Apr 2023
Mapping an A2D to a fixed-point data type
One way to map an A2D converter to a fixed-point data type is to use two real-world-value and stored-integer pairs.
You then solve a pair of affine equations
realWorldValue1 = Slope * storedIntegerValue1 + Bias
realWorldValue2 = Slope * storedIntegerValue2 + Bias
and enter those in the data type
fixdt( isSigned, WordLength, Slope, Bias)
realWorldValue1 = 10; % Volts
storedIntegerValue1 = 32767;
realWorldValue2 = -10; % Volts
storedIntegerValue2 = -32767; % Is this the correct value?
% Solve for data types Slope and Bias
% V = Slope * Q + Bias
% form as a Matrix Equation
% Vvec = [ Qvec ones ] * [Slope; Bias]
% Vvec = QOMat * slopeBiasVector
% then use backslash
% slopeBiasVector = QOMat \ Vvec
Vvec = [realWorldValue1; realWorldValue2];
SIvec = [storedIntegerValue1; storedIntegerValue2]
QOMat = [SIvec ones(numel(SIvec),1)];
slopeBiasVector = QOMat \ Vvec;
Slope = slopeBiasVector(1)
Bias = slopeBiasVector(2)
isSigned = any( SIvec < 0 )
wordLength = max( ceil( log2( abs( double(SIvec) ) ) ) )
a2dNumericType = numerictype( isSigned, wordLength,Slope,Bias)
% Sanity check
checkRealWorldValue1 = Slope * storedIntegerValue1 + Bias
checkRealWorldValue2 = Slope * storedIntegerValue2 + Bias
err1 = checkRealWorldValue1 - realWorldValue1
err2 = checkRealWorldValue2 - realWorldValue2
More Answers (2)
Andy Bartlett on 29 Mar 2023
That portion of your model will involve 4 data types.
- Digital measurement of output signal from analog plant
- Set point signal
- Accumulator type used to do the math inside the Subtraction block
- Output of that subtraction block feed to your controller logic
Normally, the fixed-point tool should be able to pick separate data types and scaling for each of those signals.
For the range values and data type for the subtractor output, everything looks pretty good.
errorSignalExample = fi([-0.00021679, 0.01076],1,32,37)
rangeErrorSignalDataType = range(errorSignalExample)
The issues are likely coming from else where in the model.
Try setting the model's diagnostics for Signals with Saturating and Wrapping overflows to Warning, then rerun the simulation. This should help isolate sources of overflow.
If overflows are occurring, then try rerunning the Fixed-Point Tool workflow but give a bigger Safety Margin before proposing data types. If there are fixed-point types in the model at the start of the workflow, then turn on Data Type Override double when Collecting Ranges.
If overflows are not the issue, turn on signal logging for several key signals in the model. Repeat the fixed-point tool workflow with Data Type Override double on during collect ranges. Then at the end of the workflow click Compare Signals and use Simulation Data Inspector to isolate where the doubles signal traces first start to diverge from the fixed-point traces. This will point you to a place in the model to look more carefully at the math and the data types.
Andy Bartlett on 30 Mar 2023
The number 395 is how many times that block in the model overflowed during the previous simulation. Suppose the element was a data type conversion block with input int16 and the output uint8. Suppose the input at one time step in the simulation was 260. Since 260 exceeds the maximum representable value, 255, of the output data type, an overflow will occur. The block could be configured to handle overflows with saturation in which case the output would be 255, and that would increase the count of "overflow saturations" for the block by 1. Alternately, the block could be configured to handle overflows with Modulo 2^Nbits wrapping in which case the output would be mod(260,2^8) = 4, and that would increase the count of "overflow wraps" for the block by 1.
So 395 overflow wraps means that during the previous instrumented simulation that block had 395 overflow events handled by Modulo 2^Nbits wrapping.
The count of overflows does NOT indicate what new data type is required to avoid overflows. Overflows due to values slightly too big for the output data type count as one overflow event, and overflows due to values 1000X to big for the output data type also count as just one overflow event.
Collecting the simulation minimum and maximum values is what helps pick a type that will avoid overflows. Calling fi with the simulation min and max will show the type thats big enough.
format long g
simulationMinMax = [-13.333333333333334, 12.666666666666666]; % Collected by Fixed-Point Tool or some other way
safetyMarginPercent = 25;
% Expanded range to cover
expandedMinMax = (1 + safetyMarginPercent/100) .* simulationMinMax
% Data type container attributes
isSigned = 1; % manually set
%isSigned = any( expandedMinMax < 0 ) % use range to see of negatives needed
wordLength = 8; % manually set
% Automatically determine scaling
% using fi's best precision mode (just don't specify scaling)
quantizedExpandedMinMax = fi( expandedMinMax, isSigned, wordLength)
bestPrecisionNumericType = numerictype(quantizedExpandedMinMax)
representableRangeOfBestPrecisionDataType = range(bestPrecisionNumericType)
Code Generation Fixed-Point Designer Fixed-Point and Floating-Point Basics Data Type Conversion and Casting