В этом примере показано, как управлять генерацией операций многословных в сгенерированном коде.
В этом примере вы будете учиться:
Как сгенерировать код для больших типов данных с помощью операций многословных
Как предотвратить код многословный, когда он не ожидается
Эта модель показывает, как широкие операции целочисленной и фиксированной точки становятся многословными в сгенерированном коде C. Код многословный обычно инициирован при помощи параметров или сигналов с типами данных шире, чем C 'долго'.
open_system('fxpdemo_multiword_example1'); set_param('fxpdemo_multiword_example1','SimulationCommand','Update');
Сгенерируйте код для модели:
evalc('slbuild(''fxpdemo_multiword_example1'');'); % Suppress output
В сгенерированном коде операции многословные реализованы с помощью функций. Эти функции будут иметь "Многословным" на их имя.
Рассмотрите одну из функций многословных, которая была сгенерирована: MultiWordAdd ()
fid = fopen('fxpdemo_multiword_example1_grt_rtw/fxpdemo_multiword_example1.c') ; ctext = fread(fid, '*char')'; fclose(fid); match = regexp(ctext, 'void MultiWordAdd.*?\n\}', 'match'); disp(match{1});
void MultiWordAdd(const uint32_T u1[], const uint32_T u2[], uint32_T y[], int32_T n) { int32_T i; uint32_T carry = 0U; uint32_T u1i; uint32_T yi; for (i = 0; i < n; i++) { u1i = u1[i]; yi = (u1i + u2[i]) + carry; y[i] = yi; carry = carry != 0U ? (uint32_T)(yi <= u1i) : (uint32_T)(yi < u1i); } }
Эта функция реализует сложение многословное в C. Эти два операнда и результат, у всех есть то же количество слов и сложение, выполняются одно слово за один раз.
close_system('fxpdemo_multiword_example1', 0);
В примере Блока Оператора отношения ниже, вы ожидали бы получать функции многословные в сгенерированном коде. Эти два типа входных данных являются uint32 и ufix32_En3. Хороший тип для сравнения является ufix35_En3, потому что этот тип может представлять все значения реального мира обоих операндов.
Мы ожидаем, что тип данных ufix35_En3 будет реализован с помощью 64-битного типа данных 2D слова.
open_system('fxpdemo_multiword_example2'); set_param('fxpdemo_multiword_example2','SimulationCommand','Update');
Эта модель конфигурируется для центрального процессора с 32-битным типом C долго. 64-битный тип данных будет типом многословным.
get_param(bdroot, 'ProdBitPerLong')
ans = 32
Сгенерируйте код для модели и анализа:
evalc('slbuild(''fxpdemo_multiword_example2'');'); % Suppress output fid = fopen('fxpdemo_multiword_example2_grt_rtw/fxpdemo_multiword_example2.c') ; ctext = fread(fid, '*char')'; fclose(fid); match = regexp(ctext, 'void fxpdemo_multiword_example2_step.*?\n\}', 'match'); disp(match{1});
void fxpdemo_multiword_example2_step(void) { /* RelationalOperator: '<Root>/LessThan' incorporates: * Inport: '<Root>/In1' * Inport: '<Root>/In2' */ Y = (U1 < ((U2 & 4U) != 0U) + (U2 >> 3)); }
Код многословный не был сгенерирован. Этот код является изолированным словом и использует тип данных сравнения uint32. В результате потеря точности в сравнении может произойти.
Simulink балансирует требования для внутреннего типа данных для сравнения. В этом случае, потому что все типы данных являются отдельным словом, оно реализует эффективный тип данных, который производит маленький, быстрый код, а не более точный, громоздкий расчет.
close_system('fxpdemo_multiword_example2', 0);
Чтобы улучшить точность этого вычисления, сделайте один из следующих шагов:
Выберите типы входных данных, которые могут быть по сравнению с полной точностью с помощью типа сравнения отдельного слова. Например, 16-битные типы или два идентичных типа.
Обеспечьте Simulink, чтобы использовать тип многословный (и во время симуляции и во время генерации кода) путем определения типа многословного для по крайней мере одних из входных параметров. Это сигнализирует о Simulink, что вы хотите использовать операции многословные для этого блока.
Сконфигурируйте модель для 64-битной системы
Пример блока MATLAB function ниже демонстрирует вычисление все-отдельного слова. Код многословный не ожидается.
open_system('fxpdemo_multiword_example3'); set_param('fxpdemo_multiword_example3','SimulationCommand','Update');
mfb = find(sfroot, '-isa', 'Stateflow.EMChart', 'Name', 'MATLAB Function'); mfb.Script %#ok
ans = 'function y = fcn(u1, u2) %#codegen y = fi(u1 * u2, 0, 32, 0);'
Сгенерируйте код для модели:
evalc('slbuild(''fxpdemo_multiword_example3'');'); % Suppress output fid = fopen('fxpdemo_multiword_example3_grt_rtw/fxpdemo_multiword_example3.c') ; ctext = fread(fid, '*char')'; fclose(fid); match = regexp(ctext, 'void fxpdemo_multiword_example3_step.*?\n\}', 'match'); disp(match{1});
void fxpdemo_multiword_example3_step(void) { uint64m_T tmp; uint64m_T tmp_0; /* MATLAB Function: '<Root>/MATLAB Function' incorporates: * Inport: '<Root>/In1' * Inport: '<Root>/In2' */ /* MATLAB Function 'MATLAB Function': '<S1>:1' */ /* '<S1>:1:4' */ uMultiWordMul(&U1, 1, &U2, 1, &tmp_0.chunks[0U], 2); uMultiWordShrNear(&tmp_0.chunks[0U], 2, 3U, &tmp.chunks[0U], 2); /* Outport: '<Root>/Out1' incorporates: * MATLAB Function: '<Root>/MATLAB Function' */ fxpdemo_multiword_example3_Y.Out1 = uMultiWord2uLongSat(&tmp.chunks[0U], 2); }
close_system('fxpdemo_multiword_example3', 0);
Даже при том, что все типы данных в модели были изолированным словом, вы все еще получили три вызова функций многословных и двух переменных многословных также.
Операциями фиксированной точки в блоке MATLAB function управляют настройки свойства fimath.
fimath
ans = RoundingMethod: Nearest OverflowAction: Saturate ProductMode: FullPrecision SumMode: FullPrecision
Этот fimath задает полную точность ProductMode. Поэтому умножение выполняется способом, который сохраняет как можно больше точности. Тип данных продукта, который является uint64_En3, реализован как тип многословный.
Можно управлять многословный в генерации кода для кода MATLAB путем управления fimath. Например:
Корректировка свойств fimath, чтобы удовлетворить эффективные требования кода. В этом примере, набор 'ProductMode' к 'KeepLSB' и 'OverflowAction', чтобы 'Перенестись'.
Определение локальных fimaths в блоке MATLAB function, которые адаптируются для определенных вычислений и не доверия глобальной переменной fimath.
load_system('fxpdemo_multiword_example4'); % No need to show this model. Only show the MATLAB code. mfb = find(sfroot, '-isa', 'Stateflow.EMChart', 'Name', 'MATLAB Function'); mfb.Script %#ok
ans = 'function y = fcn(u1, u2) %#codegen F = fimath('ProductMode','KeepLSB',... 'ProductWordLength',32,... 'OverflowAction','Wrap'); u1 = setfimath(u1,F); u2 = setfimath(u2,F); y = fi(u1 * u2,0,32,0); '
Этот fimath приведет к этому сгенерированному коду:
evalc('slbuild(''fxpdemo_multiword_example4'');'); % Suppress output fid = fopen('fxpdemo_multiword_example4_grt_rtw/fxpdemo_multiword_example4.c') ; ctext = fread(fid, '*char')'; fclose(fid); match = regexp(ctext, 'void fxpdemo_multiword_example4_step.*?\n\}', 'match'); disp(match{1});
void fxpdemo_multiword_example4_step(void) { uint32_T tmp; /* MATLAB Function: '<Root>/MATLAB Function' incorporates: * Inport: '<Root>/In1' * Inport: '<Root>/In2' */ /* MATLAB Function 'MATLAB Function': '<S1>:1' */ /* '<S1>:1:6' */ /* '<S1>:1:7' */ /* '<S1>:1:8' */ tmp = U1 * U2; Y1 = ((tmp & 4U) != 0U) + (tmp >> 3); }
close_system('fxpdemo_multiword_example4', 0);
Ссылки:
Свойства объектов fimath
helpview(fullfile(docroot,'toolbox', 'fixedpoint','fixedpoint.map'),'fimath_object_properties');
clear ctext fid match mfb clear ans