Main Content

このページの内容は最新ではありません。最新版の英語を参照するには、ここをクリックします。

HDL Coder での ForEach Subsystem の使用

この例では、For Each Subsystem を使用して、同じ CORDIC 反復をカスケードしてストリーミング平方根アルゴリズムを実装する方法を示します。その後、HDL Coder™ を使用してアルゴリズムのコードを生成できます。

ハードウェア機能への CORDIC アルゴリズムの使用

CORDIC は、三角関数、平方根、除算などの固定小数点演算の近似に使用できる反復アルゴリズムです。反復のコアは簡単なシフト演算と加算演算で構成されるため、FPGA または ASIC ハードウェアにアルゴリズムを効率的に実装できます。データ レートが低いアプリケーションでは、単一のコアをすべての反復の実行に再利用し、面積のフットプリントを非常に小さく抑えることができます。新しいデータ サンプルを各クロック サイクルで処理する必要があるアプリケーションでは、次の図に示すように、カスケード チェーンの各反復の計算に個別のコアを使用できます。

コアのカスケードは Simulink® で手動で行っても簡単ですが、コアの数をパラメーター値に基づいて自動的に調整する機能が非常に便利です。それに使用できるのが For Each Subsystem です。

For Each Subsystem を使用した CORDIC 反復のカスケード

このモデルでは、反復のコアを For Each Subsystem に配置して N 回繰り返します。反復回数の N は、上位のブロック マスクで定義されます。For Each Subsystem の出力で N 個のコアの出力からベクトルが形成され、パイプライン化されて For Each Subsystem の入力にフィードバックされます。コア (1:N-1) の出力がコア (2:N) の入力に接続され、手動でカスケードしたモデルとまったく同じになります。

断続的な入力データを処理するために Valid 信号のパスが含まれていて、有効なデータ サンプル間にランダムなギャップを挿入してテストされます。

open_system('hdlcoder_foreach_cordic')
open_system('hdlcoder_foreach_cordic/For Each Cordic Sqrt','force')

CORDIC 平方根参照の出力の比較

この Simulink モデルの出力は、[0.5,2) の範囲の 14 ビットの符号付き入力を使用して参照関数 cordicsqrt と完全に一致させています。この例にはノーマライザーの段階がないため、[0.5,2) 以外の入力範囲は機能しないと想定されます。

さらに、モデルでの最終的なゲインの調整で、FPGA の DSP マッピングが最適になるように 18 ビットのゲイン パラメーターを使用しています。関数 cordicsqrt は、そのゲイン パラメーターの語長をゲイン入力と一致させます。その結果、他の入力データ型を使用した場合は、Simulink モデルの出力と関数 cordicsqrt の間にわずかな違いが生じます。

slout = sim('hdlcoder_foreach_cordic');
data_out = slout.logsout.getElement('data out').Values.Data;
valid_out = slout.logsout.getElement('valid out').Values.Data;
data_out = data_out(valid_out);

ref_cordic = double(cordicsqrt(v_fix, niter));
data_in = double(v_fix);
data_out = double(data_out');

figure;
subplot(211);
plot(data_in, data_out, 'r.', data_in, ref_cordic, 'b-');
legend('ForEach', 'MATLAB CORDICSQRT', 'Location', 'SouthEast');
title('ForEach Model and MATLAB CORDICSQRT Reference Results');
subplot(212);
absErr = abs(ref_cordic - data_out);
plot(data_in, absErr);
title('Absolute Differences (vs. MATLAB CORDICSQRT Reference)');

HDL コードの生成

makehdl('hdlcoder_foreach_cordic/For Each Cordic Sqrt');
### Working on the model <a href="matlab:open_system('hdlcoder_foreach_cordic')">hdlcoder_foreach_cordic</a>
### Generating HDL for <a href="matlab:open_system('hdlcoder_foreach_cordic/For Each Cordic Sqrt')">hdlcoder_foreach_cordic/For Each Cordic Sqrt</a>
### Using the config set for model <a href="matlab:configset.showParameterGroup('hdlcoder_foreach_cordic', { 'HDL Code Generation' } )">hdlcoder_foreach_cordic</a> for HDL code generation parameters.
### Running HDL checks on the model 'hdlcoder_foreach_cordic'.
### Begin compilation of the model 'hdlcoder_foreach_cordic'...
### Begin compilation of the model 'hdlcoder_foreach_cordic'...
### Working on the model 'hdlcoder_foreach_cordic'...
### Working on... <a href="matlab:configset.internal.open('hdlcoder_foreach_cordic', 'GenerateModel')">GenerateModel</a>
### Begin model generation 'gm_hdlcoder_foreach_cordic'...
### Copying DUT to the generated model....
### Model generation complete.
### Generated model saved at <a href="matlab:open_system('hdlsrc/hdlcoder_foreach_cordic/gm_hdlcoder_foreach_cordic.slx')">hdlsrc/hdlcoder_foreach_cordic/gm_hdlcoder_foreach_cordic.slx</a>
### Begin VHDL Code Generation for 'hdlcoder_foreach_cordic'.
### Unused logic removed during HDL code generation. To highlight the logic removed, click the following MATLAB script: hdlsrc/hdlcoder_foreach_cordic/highlightRemovedDeadBlocks.m
### To clear highlighting, click the following MATLAB script: hdlsrc/hdlcoder_foreach_cordic/clearHighlightingRemovedDeadBlocks.m
### Working on hdlcoder_foreach_cordic/For Each Cordic Sqrt/MATLAB Function2 as hdlsrc/hdlcoder_foreach_cordic/MATLAB_Function2.vhd.
### Working on hdlcoder_foreach_cordic/For Each Cordic Sqrt/For Each Subsystem/MATLAB Function1 as hdlsrc/hdlcoder_foreach_cordic/MATLAB_Function1.vhd.
### Working on hdlcoder_foreach_cordic/For Each Cordic Sqrt/For Each Subsystem as hdlsrc/hdlcoder_foreach_cordic/For_Each_Subsystem.vhd.
### Working on hdlcoder_foreach_cordic/For Each Cordic Sqrt as hdlsrc/hdlcoder_foreach_cordic/For_Each_Cordic_Sqrt.vhd.
### Generating package file hdlsrc/hdlcoder_foreach_cordic/For_Each_Cordic_Sqrt_pkg.vhd.
### Code Generation for 'hdlcoder_foreach_cordic' completed.
### Generating HTML files for code generation report at <a href="matlab:hdlcoder.report.openDdg('/tmp/Bdoc24a_2528353_2770150/tpfcb58fe5/hdlcoder-ex98135077/hdlsrc/hdlcoder_foreach_cordic/html/hdlcoder_foreach_cordic_codegen_rpt.html')">hdlcoder_foreach_cordic_codegen_rpt.html</a>
### Creating HDL Code Generation Check Report file:///tmp/Bdoc24a_2528353_2770150/tpfcb58fe5/hdlcoder-ex98135077/hdlsrc/hdlcoder_foreach_cordic/For_Each_Cordic_Sqrt_report.html
### HDL check for 'hdlcoder_foreach_cordic' complete with 0 errors, 0 warnings, and 1 messages.
### HDL code generation complete.

その他のモデリング ガイドライン

For Each Subsystem を使用してアルゴリズムのブロックをカスケードするときは、以下のガイドラインに注意してください。

  • For Each Subsystem は Atomic であるため、ブロック X の出力とブロック X+1 の入力の間の接続で疑似代数ループが作成されます。このループを中断するには、この例で示しているように、For Each Subsystem の外のカスケード ブロック間にパイプライン レジスタを配置します。

  • 外部入力とブロック (1:N-1) の出力を連結して For Each Subsystem の入力を形成するには、Mux ブロックを使用します。これには、カスケード ブロックで同じ入出力データ型を使用する必要があります。

関連するトピック