В этом примере показано, как установить математические атрибуты фиксированной точки в коде MATLAB®.
Можно управлять математическими атрибутами фиксированной точки для присвоения, сложения, вычитания и умножения с помощью fimath объект. Можно присоединить fimath возразите против fi объект с помощью setfimath. Можно удалить fimath объект от fi объект с помощью removefimath.
Можно сгенерировать код С из примеров, если у вас есть программное обеспечение MATLAB Coder™.
Можно изолировать операции фиксированной точки от глобального и локального fimath настройки при помощи setfimath и removefimath функции. Можно также возвратиться из функций без fimath присоединенный к выходным переменным. Это дает вам локальный контроль над математическими настройками фиксированной точки, не вмешиваясь в настройки в других функциях.
КОД MATLAB
function y = user_written_sum(u) % Setup F = fimath('RoundingMethod','Floor',... 'OverflowAction','Wrap',... 'SumMode','KeepLSB',... 'SumWordLength',32); u = setfimath(u,F); y = fi(0,true,32,get(u,'FractionLength'),F); % Algorithm for i=1:length(u) y(:) = y + u(i); end % Cleanup y = removefimath(y); end
Выведите имеет не Присоединенный FIMATH
Когда вы запускаете код, fimath управляет арифметикой в функции, но возвращаемое значение присоединило не fimath. Это происходит из-за использования setfimath и removefimath в функциональном user_written_sum.
>> u = fi(1:10,true,16,11); >> y = user_written_sum(u)
y =
55
DataTypeMode: Fixed-point: binary point scaling
Signedness: Signed
WordLength: 32
FractionLength: 11
Сгенерированный код C
Если у вас есть программное обеспечение MATLAB Coder, можно сгенерировать код С с помощью следующих команд.
>> u = fi(1:10,true,16,11); >> codegen user_written_sum -args {u} -config:lib -launchreport
Функции fimath, setfimath и removefimath управляйте математикой фиксированной точки, но базовые данные, содержавшиеся в переменных, не изменяются и таким образом, сгенерированный код C не производит копий данных.
int32_T user_written_sum(const int16_T u[10])
{
int32_T y;
int32_T i;
/* Setup */
y = 0;
/* Algorithm */
for (i = 0; i < 10; i++) {
y += u[i];
}
/* Cleanup */
return y;
}Когда вы работаете с fi объекты, их fimath свойства должны быть равными, или вы получаете ошибку.
>> A = fi(pi,'ProductMode','KeepLSB'); >> B = fi(2,'ProductMode','SpecifyPrecision'); >> C = A * B
Error using embedded.fi/mtimes The embedded.fimath of both operands must be equal.
Чтобы избежать этой ошибки, можно удалить fimath от одной из переменных в выражении. В этом примере, fimath удален из B в контексте выражения, не изменяя B самостоятельно, и продукт вычисляется с помощью fimath присоединенный к A.
>> C = A * removefimath(B)
C =
6.283203125
DataTypeMode: Fixed-point: binary point scaling
Signedness: Signed
WordLength: 32
FractionLength: 26 RoundingMethod: Nearest
OverflowAction: Saturate
ProductMode: KeepLSB
ProductWordLength: 32
SumMode: FullPrecisionЕсли у вас есть переменные без присоединенного fimath, но вы хотите управлять конкретной операцией, затем можно присоединить fimath в контексте выражения, не изменяя переменные.
Например, продукт вычисляется с fimath заданный F.
>> F = fimath('ProductMode','KeepLSB','OverflowAction','Wrap','RoundingMethod','Floor'); >> A = fi(pi); >> B = fi(2); >> C = A * setfimath(B,F)
C =
6.2832
DataTypeMode: Fixed-point: binary point scaling
Signedness: Signed
WordLength: 32
FractionLength: 26 RoundingMethod: Floor
OverflowAction: Wrap
ProductMode: KeepLSB
ProductWordLength: 32
SumMode: FullPrecision
MaxSumWordLength: 128Обратите внимание на то, что переменная B не изменяется.
>> B
B =
2
DataTypeMode: Fixed-point: binary point scaling
Signedness: Signed
WordLength: 16
FractionLength: 13Можно вычислить продукты и суммы, чтобы совпадать с аккумулятором DSP с округлением пола и перенести переполнение, и использовать самое близкое округление и насыщать переполнение на выходе. Избегать fimath, которому не соответствуют, ошибки, можно удалить fimath на выходной переменной, когда это используется в расчете с другими переменными.
КОД MATLAB
В этом примере продукты составляют 32 бита, и аккумулятор составляет 40 битов, сохраняя наименьшее-количество-значимые-биты с округлением пола, и перенесите переполнение как нативные целочисленные правила К. Выход использует самое близкое округление, и насыщайте переполнение.
function [y,z] = setfimath_removefimath_in_a_loop(b,a,x,z) % Setup F_floor = fimath('RoundingMethod','Floor',... 'OverflowAction','Wrap',... 'ProductMode','KeepLSB',... 'ProductWordLength',32,... 'SumMode','KeepLSB',... 'SumWordLength',40); F_nearest = fimath('RoundingMethod','Nearest',... 'OverflowAction','Wrap'); % Set fimaths that are local to this function b = setfimath(b,F_floor); a = setfimath(a,F_floor); x = setfimath(x,F_floor); z = setfimath(z,F_floor); % Create y with nearest rounding y = coder.nullcopy(fi(zeros(size(x)),true,16,14,F_nearest)); % Algorithm for j=1:length(x) % Nearest assignment into y y(j) = b(1)*x(j) + z(1); % Remove y's fimath conflict with other fimaths z(1) = (b(2)*x(j) + z(2)) - a(2) * removefimath(y(j)); z(2) = b(3)*x(j) - a(3) * removefimath(y(j)); end % Cleanup: Remove fimath from outputs y = removefimath(y); z = removefimath(z); end
Инструкции генерации кода
Если у вас есть программное обеспечение MATLAB Coder, можно сгенерировать код С с заданными характеристиками оборудования с помощью следующих команд.
N = 256; t = 1:N; xstep = [ones(N/2,1);-ones(N/2,1)]; num = [0.0299545822080925 0.0599091644161849 0.0299545822080925]; den = [1 -1.4542435862515900 0.5740619150839550];
b = fi(num,true,16); a = fi(den,true,16); x = fi(xstep,true,16,15); zi = fi(zeros(2,1),true,16,14);
B = coder.Constant(b); A = coder.Constant(a);
config_obj = coder.config('lib'); config_obj.GenerateReport = true; config_obj.LaunchReport = true; config_obj.TargetLang = 'C'; config_obj.GenerateComments = true; config_obj.GenCodeOnly = true; config_obj.HardwareImplementation.ProdBitPerChar=8; config_obj.HardwareImplementation.ProdBitPerShort=16; config_obj.HardwareImplementation.ProdBitPerInt=32; config_obj.HardwareImplementation.ProdBitPerLong=40;
codegen -config config_obj setfimath_removefimath_in_a_loop -args {B,A,x,zi} -launchreport
Сгенерированный код C
Функции fimath, setfimath и removefimath управляйте математикой фиксированной точки, но базовые данные, содержавшиеся в переменных, не изменяются и таким образом, сгенерированный код C не производит копий данных.
void setfimath_removefimath_in_a_loop(const int16_T x[256], int16_T z[2],
int16_T y[256])
{
int32_T j;
int40_T i0;
int16_T b_y; /* Setup */
/* Set fimaths that are local to this function */
/* Create y with nearest rounding */
/* Algorithm */
for (j = 0; j < 256; j++) {
/* Nearest assignment into y */
i0 = 15705 * x[j] + ((int40_T)z[0] << 20);
b_y = (int16_T)((int32_T)(i0 >> 20) + ((i0 & 524288L) != 0L)); /* Remove y's fimath conflict with other fimaths */
z[0] = (int16_T)(((31410 * x[j] + ((int40_T)z[1] << 20)) - ((int40_T)(-23826
* b_y) << 6)) >> 20);
z[1] = (int16_T)((15705 * x[j] - ((int40_T)(9405 * b_y) << 6)) >> 20);
y[j] = b_y;
}/* Cleanup: Remove fimath from outputs */ }
Можно записать код MATLAB, который может использоваться и для с плавающей точкой и для фиксированные точки с помощью setfimath и removefimath.
function y = user_written_function(u) % Setup F = fimath('RoundingMethod','Floor',... 'OverflowAction','Wrap',... 'SumMode','KeepLSB'); u = setfimath(u,F); % Algorithm y = u + u; % Cleanup y = removefimath(y); end
Входные параметры фиксированной точки
Когда функция вызвана с входными параметрами фиксированной точки, затем fimath F используется для арифметики, и выход присоединил не fimath.
>> u = fi(pi/8,true,16,15,'RoundingMethod','Convergent'); >> y = user_written_function(u)
y =
0.785400390625
DataTypeMode: Fixed-point: binary point scaling
Signedness: Signed
WordLength: 32
FractionLength: 15Сгенерированный код C для фиксированной точки
Если у вас есть программное обеспечение MATLAB Coder, можно сгенерировать код С с помощью следующих команд.
>> u = fi(pi/8,true,16,15,'RoundingMethod','Convergent'); >> codegen user_written_function -args {u} -config:lib -launchreport
Функции fimath, setfimath и removefimath управляйте математикой фиксированной точки, но базовые данные, содержавшиеся в переменных, не изменяются и таким образом, сгенерированный код C не производит копий данных.
int32_T user_written_function(int16_T u)
{
/* Setup */
/* Algorithm */
/* Cleanup */
return u + u;
}Двойные входные параметры
Начиная с setfimath и removefimath передача для типов с плавающей точкой, user_written_function пример работает с типами с плавающей точкой, также.
function y = user_written_function(u) % Setup F = fimath('RoundingMethod','Floor',... 'OverflowAction','Wrap',... 'SumMode','KeepLSB'); u = setfimath(u,F); % Algorithm y = u + u; % Cleanup y = removefimath(y); end
Сгенерированный код C для дважды
Когда скомпилировано с входом с плавающей точкой, вы получаете следующий сгенерированный код C.
>> codegen user_written_function -args {0} -config:lib -launchreport
real_T user_written_function(real_T u)
{
return u + u;
}Где real_T тип задан как double:
typedef double real_T;
Эта функция записана так, чтобы выход был создан, чтобы быть тем же типом как вход, таким образом, и и фиксированная точка с плавающей точкой может использоваться с ним.
function y = user_written_sum_polymorphic(u) % Setup F = fimath('RoundingMethod','Floor',... 'OverflowAction','Wrap',... 'SumMode','KeepLSB',... 'SumWordLength',32);
u = setfimath(u,F);
if isfi(u)
y = fi(0,true,32,get(u,'FractionLength'),F);
else
y = zeros(1,1,class(u));
end % Algorithm
for i=1:length(u)
y(:) = y + u(i);
end % Cleanup
y = removefimath(y);end
Сгенерированный код C фиксированной точки
Если у вас есть программное обеспечение MATLAB Coder, можно сгенерировать код С фиксированной точки с помощью следующих команд.
>> u = fi(1:10,true,16,11); >> codegen user_written_sum_polymorphic -args {u} -config:lib -launchreport
Функции fimath, setfimath и removefimath управляйте математикой фиксированной точки, но базовые данные, содержавшиеся в переменных, не изменяются и таким образом, сгенерированный код C не производит копий данных.
int32_T user_written_sum_polymorphic(const int16_T u[10])
{
int32_T y;
int32_T i;/* Setup */ y = 0;
/* Algorithm */
for (i = 0; i < 10; i++) {
y += u[i];
}/* Cleanup */ return y; }
Сгенерированный код C с плавающей точкой
Если у вас есть программное обеспечение MATLAB Coder, можно сгенерировать код С с плавающей точкой с помощью следующих команд.
>> u = 1:10; >> codegen user_written_sum_polymorphic -args {u} -config:lib -launchreport
real_T user_written_sum_polymorphic(const real_T u[10])
{
real_T y;
int32_T i;/* Setup */ y = 0.0;
/* Algorithm */
for (i = 0; i < 10; i++) {
y += u[i];
}/* Cleanup */ return y; }
Где real_T тип задан как double:
typedef double real_T;
После установленного шаблона обработки встроенных целых чисел как fi объекты, setfimath преобразует целочисленный вход в эквивалентный fi с присоединенным fimath.
>> u = int8(5); >> codegen user_written_u_plus_u -args {u} -config:lib -launchreport
function y = user_written_u_plus_u(u) % Setup F = fimath('RoundingMethod','Floor',... 'OverflowAction','Wrap',... 'SumMode','KeepLSB',... 'SumWordLength',32); u = setfimath(u,F); % Algorithm y = u + u; % Cleanup y = removefimath(y); end
Выходной тип был задан fimath быть 32-битным.
int32_T user_written_u_plus_u(int8_T u)
{
/* Setup */
/* Algorithm */
/* Cleanup */
return u + u;
}