オーバーフローの検出
この例では、関数 fiaccel
を使用したオーバーフローの検出方法について説明します。変換プロセスの数値テストの段階では、ツールはスケーリングされた double を使用して固定小数点コードのシミュレーションを実行します。その後、生成されたコード内で固定小数点データ型のオーバーフローを発生させる可能性のある値を生成する式をレポートします。
必要条件
この例を実行するには、次の製品をインストールしなければなりません。
MATLAB®
Fixed-Point Designer™
C コンパイラ
サポートされるコンパイラ を参照してください。
mex -setup
を使用して既定のコンパイラを変更できます。既定のコンパイラの変更を参照してください。
新規フォルダーの作成と関連ファイルのコピー
ローカルの書き込み可能なフォルダーに、関数
overflow.m
を作成します。function y = overflow(b,x,reset) if nargin<3, reset = true; end persistent z p if isempty(z) || reset p = 0; z = zeros(size(b)); end [y,z,p] = fir_filter(b,x,z,p); end function [y,z,p] = fir_filter(b,x,z,p) y = zeros(size(x)); nx = length(x); nb = length(b); for n = 1:nx p=p+1; if p>nb, p=1; end z(p) = x(n); acc = 0; k = p; for j=1:nb acc = acc + b(j)*z(k); k=k-1; if k<1, k=nb; end end y(n) = acc; end end
テスト ファイル
overflow_test.m
を作成してoverflow
アルゴリズムの演習を行います。function overflow_test % The filter coefficients were computed using % the FIR1 function from Signal Processing Toolbox. % b = fir1(11,0.25); b = [-0.004465461051254 -0.004324228005260 +0.012676739550326 +0.074351188907780 +0.172173206073645 +0.249588554524763 +0.249588554524763 +0.172173206073645 +0.074351188907780 +0.012676739550326 -0.004324228005260 -0.004465461051254]'; % Input signal nx = 256; t = linspace(0,10*pi,nx)'; % Impulse x_impulse = zeros(nx,1); x_impulse(1) = 1; % Max Gain % The maximum gain of a filter will occur % when the inputs line up with the % signs of the filter's impulse response. x_max_gain = sign(b)'; x_max_gain = repmat(x_max_gain,ceil(nx/length(b)),1); x_max_gain = x_max_gain(1:nx); % Sums of sines f0=0.1; f1=2; x_sines = sin(2*pi*t*f0) + 0.1*sin(2*pi*t*f1); % Chirp f_chirp = 1/16; % Target frequency x_chirp = sin(pi*f_chirp*t.^2); % Linear chirp x = [x_impulse,x_max_gain,x_sines,x_chirp]; titles = {'Impulse','Max gain','Sum of sines','Chirp'}; y = zeros(size(x)); for i=1:size(x,2) reset = true; y(:,i) = overflow(b,x(:,i),reset); end test_plot(1,titles,t,x,y) end function test_plot(fig,titles,t,x,y1) figure(fig) clf sub_plot = 1; font_size = 10; for i=1:size(x,2) subplot(4,1,sub_plot) sub_plot = sub_plot+1; plot(t,x(:,i),'c',t,y1(:,i),'k') axis('tight') xlabel('t','FontSize',font_size); title(titles{i},'FontSize',font_size); ax = gca; ax.FontSize = 10; end figure(gcf) end
入力の読み込みや、入力値の設定、テストする関数の呼び出し、テスト結果の出力など、すべての前処理と後処理を実行するための独立したテスト スクリプトを作成することをお勧めします。
タイプ | 名前 | 説明 |
---|---|---|
関数のコード | overflow.m | エントリポイントの MATLAB 関数 |
テスト ファイル | overflow_test.m | MATLAB スクリプト。次をテストします。 overflow.m |
構成オブジェクトの設定
coder.FixptConfig
オブジェクトfixptcfg
を既定の設定で作成します。fixptcfg = coder.config('fixpt');
テスト ベンチの名前を設定します。この例では、テスト ベンチ関数名は
overflow_test
です。fixptcfg.TestBenchName = 'overflow_test';
既定の語長を 16 に設定します。
fixptcfg.DefaultWordLength = 16;
オーバーフロー検出の有効化
fixptcfg.TestNumerics = true; fixptcfg.DetectFixptOverflows = true;
fimath オプションの設定
fimath
Product mode
および Sum mode
を KeepLSB
に設定します。これらの設定は C 言語の整数演算の動作をモデル化します。
fixptcfg.fimath = 'fimath( ''RoundingMethod'', ''Floor'', ''OverflowAction'', ''Wrap'', ''ProductMode'', ''KeepLSB'', ''SumMode'', ''KeepLSB'')';
固定小数点への変換
浮動小数点の MATLAB 関数 overflow
を固定小数点の MATLAB コードに変換します。テスト ファイルから型が推測されるので、fiaccel
コマンドの入力型を指定する必要はありません。
fiaccel -float2fixed fixptcfg overflow
数値テスト段階でオーバーフローがレポートされます。
Overflow error in expression 'acc + b( j )*z( k )'. Percentage of Current Range = 104%.
結果のレビュー
この式内の加算または乗算がオーバーフローしているか判断します。乗算がオーバーフローしないように fimath
ProductMode を FullPrecision
に設定し、fiaccel
コマンドを再度実行します。
fixptcfg.fimath = 'fimath( ''RoundingMethod'', ''Floor'', ''OverflowAction'', ''Wrap'', ''ProductMode'', ''FullPrecision'', ''SumMode'', ''KeepLSB'')'; fiaccel -float2fixed fixptcfg overflow
数値テスト段階で、継続してオーバーフローがレポートされ、式の加算でオーバーフローしていることが示されます。