In that section, take a look at Gain Correction and Output Data Type subsections.
Those sections explain that the block will amplify the input signal by an effective gain value Gain.
In your example, the Gain is as follows.
R_decimation_factor = 20;
M_differential_delay = 1;
N_number_of_sections = 4;
Gain = (R_decimation_factor * M_differential_delay)^N_number_of_sections
A fixed-point representation of that gain would use 18 bits.
GainFi = fi( Gain, 0, ceil(log2(Gain)), 0)
GainFi =
160000
DataTypeMode: Fixed-point: binary point scaling
Signedness: Unsigned
WordLength: 18
FractionLength: 0
So given your 12 bit integer valued input, a full precision output would be 30 bits.
inExample = upperbound(numerictype(1,12,0));
yFullPrecisionExample = inExample * GainFi
yFullPrecisionExample =
327520000
DataTypeMode: Fixed-point: binary point scaling
Signedness: Signed
WordLength: 30
FractionLength: 0
You've requested that the output be only 12 bits. So the block must throw away 18 bits from the 30 bits that the full precision output would have. The block is design to throw those bits away from the least significant end which reduces precision, but avoids overflows.
nty = numerictype(1,12,-18 );
yExample = removefimath( fi( yFullPrecisionExample, nty, 'RoundingMethod','Floor') )
yExample =
327417856
DataTypeMode: Fixed-point: binary point scaling
Signedness: Signed
WordLength: 12
FractionLength: -18
For this specific example, dropping the least significant 18 bits
Dropping the least significant 18 bits produces a relatively modest error for this specific example.
absoluteError = abs( double( yExample ) - double( yFullPrecisionExample ) )
relativeErr = absoluteError / double( yFullPrecisionExample )
errorInParts = ceil(1/relativeErr)
The output is accurate to 1 part in 3207, which is in the vicinity of what would be expected for a signed 12 bits fixed point type if well scaled.
Compare using Stored Integer Value and/or Real-World Value
Fixed-point signals always have two values.
For binary-point types as being discussed here, the Fixed-Point Scaling Equation is
V = Q * 2^-FractionLength
where
V is the Real-World Value (RWV) in units prefered by the human engineers
Q is the Stored-Integer (SI) value
When modeling, it is usally far easier to work with Real-World Values (RWV). Fixed-Point Designer works with the real-world values by default. Designer automatically manages all the book keeping related to scaling and storage data types.
The actual embedded implementation produced by Coders will efficiently operate on the stored integers (SI) to produce the high level math desired by the engineers.
When using generic tools on the embedded device such as target debuggers, signals will typically be shown using the stored integer values.
When values for a signal being tested or examined are provided in both real-world value form and stored-integer value form, naturally, it is necessary convert in either direction, SI to RWV or RWV to SI.
Convert RWV to SI
Given a fixed-point fi object produce it's stored integer value.
si_approach_1 = yExample.storedInteger
si_approach_2 = yExample.storedIntegerToDouble
si_approach_3 = stripscaling(yExample)
si_approach_3 =
1249
DataTypeMode: Fixed-point: binary point scaling
Signedness: Signed
WordLength: 12
FractionLength: 0
Notice that si_approach_3 is a fi object with trivial scaling (FractionLength == 0). With trivial scaling, RWV == SI.
Convert SI to RWV
Given a stored integer value and knowledge of the scaling to be applied, it is straightforward to produce a scaled fixed-point fi object or a double holding the real-world value.
RWV in double
si_from_target = int16(1518)
rwv1_in_double = double(si_from_target) * yExample.Slope
rwv1_in_double = 397934592
Apply scaling knowledge to a raw SI to create a fixed-point fi object.
Reinterpcast is the key tool to use to apply the scaling information, but preserve the stored integer value.
si_in_raw_fi = fi( si_from_target, 1, 12, 0 )
si_in_raw_fi =
1518
DataTypeMode: Fixed-point: binary point scaling
Signedness: Signed
WordLength: 12
FractionLength: 0
nty = numerictype( yExample )
nty =
DataTypeMode: Fixed-point: binary point scaling
Signedness: Signed
WordLength: 12
FractionLength: -18
rwv2_in_fi = reinterpretcast( si_in_raw_fi, nty)
rwv2_in_fi =
397934592
DataTypeMode: Fixed-point: binary point scaling
Signedness: Signed
WordLength: 12
FractionLength: -18
check_si_still_same = rwv2_in_fi.storedIntegerToDouble
check_si_still_same = 1518