The "KeepMSB" setting you have on your fimath for the ProductMode is
going to give you a s16,14 by design because the ideal (full precision)
product needs s32,30 bits (i.e. 2 integer bits and 30 fraction bits)
without making any assumptions about the value of the input operands to
the multiply (*) operator. So in the "KeepMSB" case with only 16 bits
and a required 2 bits for integer the fraction length is automatically
going to be 14 bits - an output type of s16,14.
Now you could set your fimath's (F's) ProductMode to be
'SpecifyPrecision' and explicitly specify the FractionLength of the
Product to be 15 bits:
F = fimath('RoundMode', 'fix',...
'OverflowMode', 'wrap', 'ProductMode', 'SpecifyPrecision',...
aFI = fi(aFL, Signed, WordLen, FracLen, 'fimath',F);
dFi = 0.9 * aFI;
%DataTypeMode: Fixed-point: binary point scaling
% Signedness: Signed
% WordLength: 16
% FractionLength: 15
But if you do want a KeepMSb rule in the product you can always re-cast
the output to a s16,15:
% F is your original F with the KeepMSB product mode.
dFIQ15 = fi(zeros(size(aFI),Signed,WordLen,FracLen,'fimath',F);
dFIQ15(:) = 0.9*aFI;
Again, the key is that we do not make assumptions or take into account
the value of input operands while determining the type of the output.
On 9/16/10 1:33 AM, Fredx wrote:
> I like to convert floating-point algorithm into fixed-point. The idea is
> to calculate the numerical format (Q15, Q14, ...) via Matlab. The
> problem is, I do not know how to define a constant.
> The following shows a simplfied example:
> Input data of Q15 format shall be multiplied by 0.9. Because 0.9 is
> positive and smaller one, the result can be represented via Q15.
> When converting the result into fixed point via matlab, a normal
> multiplication of two Q15 values is performed which leads to a Q14
> result. For two Q15 variables, this is fine, but here 0.9 will never
> change so that Q14 is not necessary.
> Does anybody know how to solve this?
> clc WordLen = 16; FracLen = 15; Signed = 1;
> F = fimath('ProductMode', 'KeepMSB', ... 'ProductWordLength',
> WordLen,... 'SumMode', 'KeepMSB', ... 'SumWordLength', WordLen,...
> 'OverFlowMode', 'wrap',... 'Roundmode', 'fix');
> % create Floatin-Point values aFL = -0.9 : 0.1 : 0.9;
> % create Fixed-Point values aFI = fi(aFL, Signed, WordLen, FracLen,
> % Floating-Point operation cFL = 0.9 * aFL;
> % Convert Floating-Point result to Fixed-Point cFI = fi(cFL, Signed,
> WordLen, 'fimath',F);
> % Fixed-Point operation dFI = 0.9 * aFI;
> numerictype(cFI) % DataTypeMode: Fixed-point: binary point scaling %
> Signed: true % WordLength: 16 % FractionLength: 15
> numerictype(dFI) % DataTypeMode: Fixed-point: binary point scaling %
> Signed: true % WordLength: 16 % FractionLength: 14