Main Content

最小/最大のインストルメンテーションを使用したデータ型の設定

この例では、最小/最大ログ作成の MATLAB® コードをインストルメント化し、データ型を推奨するツールを使用することによって、固定小数点データ型を設定します。関数 buildInstrumentedMex を使用してインストルメンテーションが有効な MEX 関数をビルドし、showInstrumentationResults を使用してインストルメンテーションの結果を表示し、関数 clearInstrumentationResults を使用してインストルメンテーションの結果をクリアします。

テスト対象ユニットの定義

この例で固定小数点に変換する関数は、2 次直接型 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のリファレンス ページを参照してください。関数 buildInstrumentedMex の使用には MATLAB Coder™ ライセンスは必要ありません。

関数 fi_2nd_order_df2t_filter では、変数 y および z は入力と出力の両方として使用されます。これは以下の理由から重要なパターンです。

  • 関数の外で y および z のデータ型を設定できるので、固定小数点と浮動小数点型の両方で関数を再利用できます。

  • 生成された C コードは、関数の引数リスト内の参照として y および z を作成します。

設計要件を使用したデータ型の決定

この例では、設計の要件によって入力 x のデータ型が決まります。これらの要件は符号付き 16 ビットの非整数です。

clearvars
N = 256;
x = fi(zeros(N,1),1,16,15);

また、設計の要件によって、40 ビットのアキュムレータをもつ DSP ターゲットの固定小数点演算も決まります。この例では、負方向の丸めとオーバーフロー時のラップを使用して、効率的なコードを生成します。

F = fimath('RoundingMethod','Floor',...
           'OverflowAction','Wrap',...
           'ProductMode','KeepLSB',...
           'ProductWordLength',40,...
           'SumMode','KeepLSB',...
           'SumWordLength',40);

以下の係数は、次によって作成された 2 次ローパス フィルターに対応します。

[num,den] = butter(2,0.125)

係数の値は、フィルターの出力および状態に割り当てられる値の範囲に影響します。

num = [0.0299545822080925  0.0599091644161849  0.0299545822080925];
den = [1                  -1.4542435862515900  0.5740619150839550];

設計の要件によって決まる係数のデータ型は、16 ビットの語長として指定され、最高精度にスケーリングされます。定数係数から fi オブジェクトを作成するには、次を行います。

1. 既定の最も近い正の整数方向への丸めとオーバーフローでの飽和設定を使用して、係数を fi オブジェクトにキャストします。これにより、係数の精度が高くなります。

b = fi(num,1,16);
a = fi(den,1,16);

2. fimath に負方向の丸めとオーバーフロー時のラップ設定を付加して演算を制御します。これにより、より効率的な C コードが生成されます。

b = setfimath(b,F);
a = setfimath(a,F);

係数および入力の値を使用したデータ型の決定

係数の値および入力の値によって、出力 y および状態ベクトル z のデータ型が決まります。値の最大範囲を保持して潜在的なオーバーフローを特定しデータ型を推奨できるように、スケーリングされた double データ型の値を作成します。

yisd = fi(zeros(N,1),1,16,15,'DataType','ScaledDouble','fimath',F);
zisd = fi(zeros(2,1),1,16,15,'DataType','ScaledDouble','fimath',F);

スケーリングされた double の MEX 関数として MATLAB 関数をインストルメント化

MATLAB コードをインストルメント化するには、関数 buildInstrumentedMex を使用して MATLAB 関数から MEX 関数を作成します。buildInstrumentedMex への入力はfiaccelへの入力と同じですが、buildInstrumentedMex には fi オブジェクトの制限がありません。buildInstrumentedMex の出力は、インストルメンテーションが挿入された MEX 関数です。この MEX 関数を実行すると、すべての名前付き変数および中間値について、シミュレーションされた最小値と最大値が記録されます。

'-o' オプションを使用して、生成される MEX 関数に名前を付けます。'-o' オプションを使用しない場合は、元の MATLAB 関数の名前の最後に '_mex' を付けた名前が MEX 関数に付けられます。MEX 関数に MATLAB 関数と同じ名前を付けることもできますが、MEX 関数の方が MATLAB 関数より優先されるため、同じ名前の MEX 関数が再生成されるか削除されてクリアされるまでは MATLAB 関数に対する変更が実行されない点に注意する必要があります。

フィルター係数を関数 buildInstrumentedMex に定数として渡すことで、フィルター係数をこのフィルターの実装にハードコードします。

buildInstrumentedMex fi_2nd_order_df2t_filter ...
    -o filter_scaled_double ...
    -args {coder.Constant(b),coder.Constant(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 関数の実行による最小値/最大値の記録

シミュレーション実行の最小値と最大値を記録するには、インストルメント化した MEX 関数を実行しなければなりません。その後の実行でインストルメンテーションの結果が集積されていき、その集積は clearInstrumentationResults によってインストルメンテーションの結果がクリアされるまで続きます。

分子と分母の係数が定数としてコンパイルされているため、生成された MEX 関数への入力として指定されないという点に注意してください。

ychirp = filter_scaled_double(b,a,x,yisd,zisd);

フィルター処理されたチャープ信号のプロットは、フィルターのローパス動作をこれらの特定の係数と共に表示します。低周波数は通過し、高周波数は減衰されます。

plot(t,x,'c',t,ychirp,'bo-')
title('Chirp')
legend('Input','Scaled-double output')

Figure contains an axes object. The axes object with title Chirp contains 2 objects of type line. These objects represent Input, Scaled-double output.

インストルメンテーションの結果と推奨されたチャープの小数部の長さの表示

関数 showInstrumentationResults は、インストルメント化された値を示すコード生成レポートを表示します。関数 showInstrumentationResults への入力は、結果表示の対象にするインストルメント化された MEX 関数の名前です。

オーバーフローの可能性は、スケーリングされた double データ型をもつ fi オブジェクトにのみ表示されます。

この特定の設計は語長が固定の DSP 用なので、-proposeFL フラグを使用して、小数部の長さを推奨します。

showInstrumentationResults filter_scaled_double -proposeFL

インストルメント化されたコード生成レポート内の式または変数にカーソルを合わせると、シミュレーションの最小値と最大値が表示されます。この設計では、入力の範囲は -1 ~ +1 であり、すべての変数の値や中間結果の範囲も -1 ~ +1 になります。つまり、データ型がすべて非整数 (小数部の長さは語長より 1 ビット短い) になる可能性を示します。ただし、この関数に対して他の種類の入力を使用した場合は、常にそうなるとは限りません。最終的な固定小数点データ型を設定する前に、多くの種類の入力をテストすることが重要です。

fi_instrumentation_fixed_point_filter_demo_code_generation_report_01.png

ステップ入力を使用したテスト ベンチ

次のテスト ベンチはステップ入力で実行されます。ステップ入力はシステムの動作を特徴付けるために使用されることがあるので、優れた代表的な入力となっています。

xstep = [ones(N/2,1);-ones(N/2,1)];
x(:) = xstep;

ステップ入力によるインストルメント化した MEX 関数の実行

インストルメンテーションの結果は集積され、その集積は clearInstrumentationResults によってインストルメンテーションの結果がクリアされるまで続きます。

ystep = filter_scaled_double(b,a,x,yisd,zisd);

plot(t,x,'c',t,ystep,'bo-')
title('Step')
legend('Input','Scaled-double output')

Figure contains an axes object. The axes object with title Step contains 2 objects of type line. These objects represent Input, Scaled-double output.

インストルメンテーションの累積結果の表示

インストルメント化されたコード生成レポートで現在の範囲の 100% の位置にある x が示すように、ステップの入力とチャープ入力が両方とも最大範囲である場合、ステップ入力ではオーバーフローが発生しますが、チャープ入力では発生しません。これは、テスト ベンチには多数のさまざまな入力をもつ必要があることを意味します。この例の目的上、入力は 2 つだけ使用しましたが、実際のテスト ベンチではさらに多くの入力を使用します。

showInstrumentationResults filter_scaled_double -proposeFL

fi_instrumentation_fixed_point_filter_demo_code_generation_report_02.png

推奨された固定小数点プロパティの適用

オーバーフローを避けるには、インストルメント化されたコード生成レポートに示されている y および z の推奨された小数部の長さである 14 ビットに基づいて、推奨された固定小数点プロパティを設定します。

ワークフローのこの時点では、実際の固定小数点型 (前述のデータ型を決定する手順で使用したスケーリングされた double 型とは異なる) を使用します。

yi = fi(zeros(N,1),1,16,14,'fimath',F);
zi = fi(zeros(2,1),1,16,14,'fimath',F);

固定小数点 MEX 関数として MATLAB 関数をインストルメント化

固定小数点入力と関数 buildInstrumentedMex を使って、インストルメント化した固定小数点 MEX 関数を作成します。

buildInstrumentedMex fi_2nd_order_df2t_filter ...
    -o filter_fixed_point ...
    -args {coder.Constant(b),coder.Constant(a),x,yi,zi}

固定小数点のアルゴリズムの検証

固定小数点に変換したら、固定小数点の入力を使用してテスト ベンチを再実行し、設計を検証します。

チャープ入力を使用した検証

チャープ入力を使用して固定小数点アルゴリズムを実行し、設計を検証します。

x(:) = xchirp;
[y,z] = filter_fixed_point(b,a,x,yi,zi);
[ysd,zsd] = filter_scaled_double(b,a,x,yisd,zisd);
err = double(y) - double(ysd);

固定小数点の出力とスケーリングされた double の出力を比較して、設計基準を満たしていることを確認します。

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 contains 2 axes objects. Axes object 1 with title Fixed-Point Chirp, xlabel Time (s), ylabel Amplitude contains 3 objects of type line. One or more of the lines displays its values using only markers These objects represent Input, Scaled-double output, Fixed-point output. Axes object 2 with title Error, xlabel t, ylabel err contains an object of type line.

変数と中間結果を調べて、最小値/最大値が範囲内であることを確認します。

showInstrumentationResults filter_fixed_point

fi_instrumentation_fixed_point_filter_demo_code_generation_report_03.png

ステップ入力を使用した検証

ステップ入力を使用して固定小数点アルゴリズムを実行し、設計を検証します。

ステップ入力の実行の効果のみを確認できるように、以下のコードを実行して前のインストルメンテーションの結果をクリアします。

clearInstrumentationResults filter_fixed_point

固定小数点フィルターを通過するステップ入力を実行し、スケーリングされた double フィルターの出力と比較します。

x(:) = xstep;
[y,z] = filter_fixed_point(b,a,x,yi,zi);
[ysd,zsd] = filter_scaled_double(b,a,x,yisd,zisd);
err = double(y) - double(ysd);

スケーリングされた double の出力に対して固定小数点の出力をプロットし、設計基準を満たしていることを確認します。

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 contains 2 axes objects. Axes object 1 with title Fixed-Point Step contains 3 objects of type line. One or more of the lines displays its values using only markers These objects represent Input, Scaled-double output, Fixed-point output. Axes object 2 with title Error, xlabel t, ylabel err contains an object of type line.

変数と中間結果を調べて、最小値/最大値が範囲内であることを確認します。

showInstrumentationResults filter_fixed_point

fi_instrumentation_fixed_point_filter_demo_code_generation_report_04.png

コード アナライザーの警告を非表示にします。

%#ok<*ASGLU>