В этом примере показано, как задать типы данных с фиксированной точкой путем инструментального применения кода MATLAB ® для регистрации min/max и использования инструментов для предложения типов данных.
Будут использоваться следующие функции:
buildInstrumentedMex - Создание функции MEX с включенным инструментарием
showInstrumentationResults - Показать результаты инструментирования
clearInstrumentationResults - Очистить результаты КИПиА
В этом примере функция, преобразованная в фиксированную точку, представляет собой транспонированный фильтр второго порядка с прямой формой 2. Вы можете заменить свою собственную функцию вместо этой, чтобы воспроизвести эти шаги в вашей собственной работе.
function [y,z] = fi_2nd_order_df2t_filter(b,a,x,y,z) for i=1:length(x) y(i) = b(1)*x(i) + z(1); z(1) = b(2)*x(i) + z(2) - a(2) * y(i); z(2) = b(3)*x(i) - a(3) * y(i); end end
Для инструментальной реализации функции MATLAB ® она должна быть пригодна для генерации кода. Для получения информации о создании кода см. справочную страницу дляbuildInstrumentedMex. Лицензия MATLAB ® Coder™ не требуется для использованияbuildInstrumentedMex.
В этой функции переменные y и z используются как в качестве входов, так и в качестве выходов. Это важная закономерность, поскольку:
Можно задать тип данных y и z вне функции, что позволяет повторно использовать функцию как для типов с фиксированной запятой, так и для типов с плавающей запятой.
Созданный код C будет создан y и z в качестве ссылок в списке аргументов функции. Дополнительные сведения об этом шаблоне см. в документации по пути Создание кода из MATLAB ® > Руководство пользователя > Создание эффективного и многократно используемого кода > Создание эффективного кода > Устранение избыточных копий функциональных входов.
Выполните следующий код, чтобы скопировать тестовую функцию во временный каталог, чтобы этот пример не мешал вашей работе.
tempdirObj = fidemo.fiTempdir('fi_instrumentation_fixed_point_filter_demo');
copyfile(fullfile(matlabroot,'toolbox','fixedpoint','fidemos','+fidemo',... 'fi_2nd_order_df2t_filter.m'),'.','f');
Выполните следующий код для фиксации текущих состояний и сброса глобальных состояний.
FIPREF_STATE = get(fipref); reset(fipref)
В этом примере требования проекта определяют тип данных ввода x. Эти требования являются подписанными, 16-разрядными и дробными.
N = 256; x = fi(zeros(N,1),1,16,15);
Требования конструкции также определяют математику с фиксированной точкой для ЦПС-мишени с 40-разрядным накопителем. В этом примере используется округление пола и переполнение обтекания для создания эффективного созданного кода.
F = fimath('RoundingMethod','Floor',... 'OverflowAction','Wrap',... 'ProductMode','KeepLSB',... 'ProductWordLength',40,... 'SumMode','KeepLSB',... 'SumWordLength',40);
Следующие коэффициенты соответствуют фильтру нижних частот второго порядка, созданному
[num,den] = butter(2,0.125)
Значения коэффициентов влияют на диапазон значений, которые будут назначены выходному сигналу фильтра и состояниям.
num = [0.0299545822080925 0.0599091644161849 0.0299545822080925]; den = [1 -1.4542435862515900 0.5740619150839550];
Тип данных коэффициентов, определяемый требованиями конструкции, задается как 16-битная длина слова и масштабируется до наилучшей точности. Образец для создания fi объекты из постоянных коэффициентов:
1. Приведите коэффициенты к fi объекты, использующие настройки округления до ближайшего и насыщения переполнения по умолчанию, что обеспечивает лучшую точность коэффициентов.
2. Быть свойственным fimath с округлением пола и настройками переполнения обертки для управления арифметикой, что приводит к повышению эффективности кода C.
b = fi(num,1,16); b.fimath = F; a = fi(den,1,16); a.fimath = F;
Жестко кодировать коэффициенты фильтра в реализацию этого фильтра, передавая их как константы в buildInstrumentedMex команда.
B = coder.Constant(b); A = coder.Constant(a);
Значения коэффициентов и значения входов определяют типы данных вывода y и вектор состояния z. Создайте их с масштабированным двойным типом данных, чтобы их значения достигали полного диапазона и можно было определить возможные переполнения и предложить типы данных.
yisd = fi(zeros(N,1),1,16,15,'DataType','ScaledDouble','fimath',F); zisd = fi(zeros(2,1),1,16,15,'DataType','ScaledDouble','fimath',F);
Для управления кодом MATLAB ® необходимо создать функцию MEX из функции MATLAB ® с помощью buildInstrumentedMex команда. Входные данные для buildInstrumentedMex те же, что и входные данные для fiaccel, но buildInstrumentedMex не имеет fi-объектные ограничения. Выходные данные buildInstrumentedMex является функцией MEX с вставленным инструментарием, поэтому при выполнении функции MEX моделируемые минимальное и максимальное значения записываются для всех именованных переменных и промежуточных значений.
Используйте '-o' для присвоения имени создаваемой функции MEX. Если вы не используете '-o' , то функция MEX является именем функции MATLAB ® с'_mex' прилагается. Можно также назвать функцию MEX той же самой, что и функцию MATLAB ®, но необходимо помнить, что функции MEX имеют приоритет над функциями MATLAB ® и поэтому изменения в функции MATLAB ® не будут выполняться до тех пор, пока функция MEX не будет повторно сгенерирована или функция MEX не будет удалена и очищена.
buildInstrumentedMex fi_2nd_order_df2t_filter ... -o filter_scaled_double ... -args {B,A,x,yisd,zisd}
Испытательный стенд для этой системы настроен на запуск сигналов чирпа и шага. Как правило, испытательные стенды для систем должны охватывать широкий диапазон входных сигналов.
На первом испытательном стенде используется вход чирпа. Чирп-сигнал является хорошим репрезентативным входом, поскольку он охватывает широкий диапазон частот.
t = linspace(0,1,N); % Time vector from 0 to 1 second f1 = N/2; % Target frequency of chirp set to Nyquist xchirp = sin(pi*f1*t.^2); % Linear chirp from 0 to Fs/2 Hz in 1 second x(:) = xchirp; % Cast the chirp to fixed-point
Для записи минимальных и максимальных значений для этого прогона моделирования необходимо выполнить инструментальную функцию MEX. Последующие прогоны накапливают результаты КИП до тех пор, пока они не будут очищены с помощью clearInstrumentationResults.
Следует отметить, что коэффициенты числителя и знаменателя были скомпилированы в виде констант, поэтому они не были введены в генерируемую функцию MEX.
ychirp = filter_scaled_double(x,yisd,zisd);
График отфильтрованного чирп-сигнала показывает поведение нижних частот фильтра с этими конкретными коэффициентами. Пропускают низкие частоты и ослабляют более высокие частоты.
clf plot(t,x,'c',t,ychirp,'bo-') title('Chirp') legend('Input','Scaled-double output') figure(gcf); drawnow;

showInstrumentationResults отображает отчет о создании кода с инструментальными значениями. Вход в showInstrumentationResults - имя инструментальной функции MEX, для которой требуется показать результаты.
Это список опций для showInstrumentationResults команда:
-defaultDT T Тип данных по умолчанию для двойных значений, где T является numerictype объект или одна из строк {remainFloat, double, single, int8, int16, int32, int64, uint8, uint16, uint32, uint64}. Значение по умолчанию: remainFloat.
-nocode Не показывать код MATLAB в распечатываемом отчете. Отображение только таблиц регистрируемых переменных. Эта опция действует только в сочетании с опцией -printable.
-optimizeWholeNumbers Оптимизируйте длину слова переменных, для которых журналы min/max моделирования указывают, что они всегда были целыми числами.
-percentSafetyMargin N Запас прочности для моделирования мин/макс, где N представляет собой процентное значение.
-printable Создайте отчет для печати и откройте его в обозревателе инженерных систем.
-proposeFL Предложить длины дробей для указанных длин слов.
-proposeWL Предложить длины слов для указанных длин дробей.
Потенциальные переполнения отображаются только для fi с масштабированным двойным типом данных.
Эта конкретная конструкция предназначена для DSP, где длины слов фиксированы, поэтому используйте proposeFL флаг для предложения длин дробей.
showInstrumentationResults filter_scaled_double -proposeFL
Наведите указатель мыши на выражения или переменные в отчете о создании инструментального кода, чтобы увидеть минимальное и максимальное значения моделирования. В этой конструкции входные данные находятся в диапазоне от -1 до + 1, а значения всех переменных и промежуточных результатов также находятся в диапазоне от -1 до + 1. Это говорит о том, что все типы данных могут быть дробными (длина дроби на один бит меньше длины слова). Однако это не всегда будет верно для этой функции для других типов входных данных, и важно протестировать многие типы входных данных перед установкой окончательных типов данных с фиксированной точкой.

Следующий испытательный стенд запускается с вводом шага. Ввод шага является хорошим репрезентативным вводом, поскольку часто используется для характеристики поведения системы.
xstep = [ones(N/2,1);-ones(N/2,1)]; x(:) = xstep;
Результаты КИПиА накапливаются до тех пор, пока они не будут очищены clearInstrumentationResults.
ystep = filter_scaled_double(x,yisd,zisd); clf plot(t,x,'c',t,ystep,'bo-') title('Step') legend('Input','Scaled-double output') figure(gcf); drawnow;

Несмотря на то, что входы для ступенчатых и чирповых входов оба являются полным диапазоном, как указано x При 100-процентном диапазоне тока в отчете о генерировании инструментального кода ввод шага вызывает переполнение, в то время как ввод частотно-частотного диапазона не соответствует действительности. Для целей этого примера использовались только два входных сигнала, но реальные испытательные стенды должны быть более тщательными.
showInstrumentationResults filter_scaled_double -proposeFL

Для предотвращения переполнения установите предлагаемые свойства фиксированной точки на основе предлагаемых длин дроби 14 бит для y и z из отчета о создании инструментального кода.
На этом этапе процесса используются истинные типы с фиксированной точкой (в отличие от масштабированных двойных типов, которые использовались на предыдущем этапе определения типов данных).
yi = fi(zeros(N,1),1,16,14,'fimath',F); zi = fi(zeros(2,1),1,16,14,'fimath',F);
Создайте инструментальную функцию MEX с фиксированной точкой, используя входные данные с фиксированной точкой и buildInstrumentedMex команда.
buildInstrumentedMex fi_2nd_order_df2t_filter ... -o filter_fixed_point ... -args {B,A,x,yi,zi}
После преобразования в фиксированную точку снова запустите тестовый стенд с вводами фиксированной точки для проверки проекта.
Для проверки конструкции запустите алгоритм с фиксированной точкой и вводом чирпа.
x(:) = xchirp; [y,z] = filter_fixed_point(x,yi,zi); [ysd,zsd] = filter_scaled_double(x,yisd,zisd); err = double(y) - double(ysd);
Сравните выходы с фиксированной точкой с выходами с двойным масштабированием, чтобы убедиться, что они соответствуют критериям проектирования.
clf subplot(211);plot(t,x,'c',t,ysd,'bo-',t,y,'mx') xlabel('Time (s)'); ylabel('Amplitude') legend('Input','Scaled-double output','Fixed-point output'); title('Fixed-Point Chirp') subplot(212);plot(t,err,'r');title('Error');xlabel('t'); ylabel('err'); figure(gcf); drawnow;

Проверьте переменные и промежуточные результаты, чтобы убедиться, что значения min/max находятся в пределах диапазона.
showInstrumentationResults filter_fixed_point

Запустите алгоритм с фиксированной точкой с вводом шага для проверки конструкции.
Выполните следующий код, чтобы очистить предыдущие результаты инструментирования, чтобы увидеть только эффекты выполнения ввода шага.
clearInstrumentationResults filter_fixed_point
Выполните пошаговый ввод через фильтр с фиксированной точкой и сравните его с выводом масштабированного двойного фильтра.
x(:) = xstep; [y,z] = filter_fixed_point(x,yi,zi); [ysd,zsd] = filter_scaled_double(x,yisd,zisd); err = double(y) - double(ysd);
Постройте график выходов с фиксированной точкой относительно выходов с двойным масштабированием, чтобы убедиться, что они соответствуют заданным критериям проектирования.
clf subplot(211);plot(t,x,'c',t,ysd,'bo-',t,y,'mx') title('Fixed-Point Step'); legend('Input','Scaled-double output','Fixed-point output') subplot(212);plot(t,err,'r');title('Error');xlabel('t'); ylabel('err'); figure(gcf); drawnow;

Проверьте переменные и промежуточные результаты, чтобы убедиться, что значения min/max находятся в пределах диапазона.
showInstrumentationResults filter_fixed_point

Выполните следующий код для восстановления глобальных состояний.
fipref(FIPREF_STATE); clearInstrumentationResults filter_fixed_point clearInstrumentationResults filter_scaled_double clear fi_2nd_order_df2t_filter_fixed_instrumented clear fi_2nd_order_df2t_filter_float_instrumented
Выполните следующий код для удаления временного каталога.
tempdirObj.cleanUp;
%#ok<*ASGLU>