В этом примере показано, как управлять генерацией многословных операций в сгенерированном коде.
В этом примере вы узнаете:
Как сгенерировать код для типов больших данных с помощью операций с несколькими словами
Как предотвратить многословный код, когда он не ожидается
Эта модель показывает, как операции с широким целым числом и фиксированной точкой становятся мультисловом в сгенерированном коде C. Многословный код обычно запускается при помощи параметров или сигналов с типами данных шире, чем C 'long'.
open_system('fxpdemo_multiword_example1'); set_param('fxpdemo_multiword_example1','SimulationCommand','Update');

Сгенерируйте код для модели:
evalc('slbuild(''fxpdemo_multiword_example1'');'); % Suppress output
В сгенерированном коде многословные операции реализуются с помощью функций. Эти функции будут иметь «MultiWord» в своем имени.
Проверьте одну из многословных функций, которая была сгенерирована: 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);
В приведенном ниже примере Relational Operator Block вы ожидаете получить функции с несколькими словами в сгенерированном коде. Два типа входных данных uint32 и ufix32_En3. Хороший тип для сравнения ufix35_En3, поскольку этот тип может представлять все значения реального мира обеих операндов.
Мы ожидаем тип данных ufix35_En3 для реализации с использованием 64-разрядного двухсловного типа данных.
open_system('fxpdemo_multiword_example2'); set_param('fxpdemo_multiword_example2','SimulationCommand','Update');

Эта модель сконфигурирована для центрального процессора с 32-разрядным типом C long. 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 = get_param('fxpdemo_multiword_example3/MATLAB Function','MATLABFunctionConfiguration'); mfb.FunctionScript
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' на 'Wrap'.
Определение локальных fimath в Блок MATLAB Function, которые адаптированы для конкретных вычислений, и не полагаясь на глобальное fimath.
load_system('fxpdemo_multiword_example4'); % No need to show this model. Only show the MATLAB code. mfb = get_param('fxpdemo_multiword_example4/MATLAB Function','MATLABFunctionConfiguration'); mfb.FunctionScript
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);
clear ctext fid match mfb clear ans