メインコンテンツ

HDL ワークフロー アドバイザーを使用した対称 FIR フィルター用の HDL コードの生成および合成

この例では、HDL Coder™ プロジェクトを作成し、MATLAB HDL ワークフロー アドバイザーを使用することで、MATLAB® 設計からコードを生成し、HDL テスト ベンチで MATLAB 設計を検証し、生成された HDL コードを合成する方法を示します。この例では、HDL シミュレーション ツールとして ModelSim® を使用し、サードパーティの合成ツールとして Xilinx® Vivado® を使用します。HDL コードを生成し、プログラムで FPGA 合成を実行する方法の詳細については、コマンド ライン インターフェイスを使用した MATLAB コードからの HDL コードの生成を参照してください。

MATLAB 設計の確認

MATLAB 設計の mlhdlc_sfir は、単純な対称 FIR フィルターです。MATLAB 設計を開きます。

design_name = "mlhdlc_sfir";
testbench_name = "mlhdlc_sfir_tb";
open(design_name);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% MATLAB design: Symmetric FIR Filter
% 
% Introduction:
%
% We can reduce the complexity of the FIR filter by leveraging its
% symmetry. Symmetry for an n-tap filter implies, coefficient h0 =
% coefficient hn-1, coefficient, h1 = coefficient hn-2, etc. In this case,
% the number of multipliers can be approximately halved. The key is to add
% the two data values that need to be multiplied with the same coefficient
% prior to performing the multiplication.
%
% Key Design pattern covered in this example: 
% (1) Filter states represented using the persistent variables
% (2) Filter coefficients passed in as parameters

%   Copyright 2011-2026 The MathWorks, Inc.

%#codegen
function [y_out, delayed_xout] = mlhdlc_sfir(x_in,h_in1,h_in2,h_in3,h_in4)   
% Symmetric FIR Filter

% declare and initialize the delay registers
persistent ud1 ud2 ud3 ud4 ud5 ud6 ud7 ud8;
if isempty(ud1)
    ud1 = 0; ud2 = 0; ud3 = 0; ud4 = 0; ud5 = 0; ud6 = 0; ud7 = 0; ud8 = 0;
end

% access the previous value of states/registers
a1 = ud1 + ud8; a2 = ud2 + ud7;
a3 = ud3 + ud6; a4 = ud4 + ud5;

% multiplier chain
m1 = h_in1 * a1; m2 = h_in2 * a2;
m3 = h_in3 * a3; m4 = h_in4 * a4;

% adder chain
a5 = m1 + m2; a6 = m3 + m4;

% filtered output
y_out = a5 + a6;

% delayout input signal
delayed_xout = ud8;

% update the delay line
ud8 = ud7; 
ud7 = ud6;
ud6 = ud5;
ud5 = ud4;
ud4 = ud3;
ud3 = ud2;
ud2 = ud1;
ud1 = x_in;
end

MATLAB テスト ベンチの確認

mlhdlc_sfir_tb テスト ベンチは、ローパス フィルター係数を定義し、典型的な入力範囲を適用します。テスト ベンチはこれらの入力を使用して設計を実行し、フィルター応答をテストします。MATLAB テスト ベンチの要件とベスト プラクティスの詳細については、MATLAB テスト ベンチの要件とコード生成のためのベスト プラクティスを参照してください。

テスト ベンチを開きます。

open(testbench_name);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% MATLAB test bench for the FIR filter
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%   Copyright 2011-2026 The MathWorks, Inc.
clear mlhdlc_sfir;
T = 2;
dt = 0.001;
N = T/dt+1;
sample_time = 0:dt:T;

df = 1/dt;
sample_freq = linspace(-1/2,1/2,N).*df;

% input signal with noise
x_in = cos(2.*pi.*(sample_time).*(1+(sample_time).*75)).';

% filter coefficients
h1 = -0.1339; h2 = -0.0838; h3 = 0.2026; h4 = 0.4064;

len = length(x_in);
y_out = zeros(1,len);
x_out = zeros(1,len);

for ii=1:len
    data = x_in(ii);
    % call to the design "mlhdlc_sfir" that is targeted for hardware
    [y_out(ii), x_out(ii)] = mlhdlc_sfir(data, h1, h2, h3, h4);
end

figure("Name", string(mfilename) + "_plot");
subplot(3,1,1);
plot(1:len,x_in,"-b");
xlabel("Time (ms)")

ylabel("Amplitude")
title("Input Signal (with noise)")
subplot(3,1,2); plot(1:len,y_out,"-b");
xlabel("Time (ms)")
ylabel("Amplitude")
title("Output Signal (filtered)")

freq_fft = @(x) abs(fftshift(fft(x)));

subplot(3,1,3); semilogy(sample_freq,freq_fft(x_in),"-b");
hold on
semilogy(sample_freq,freq_fft(y_out),"-r")
hold off
xlabel("Frequency (Hz)")
ylabel("Amplitude (dB)")
title("Input and Output Signals (Frequency domain)")
legend({"FilterIn", "FilterOut"},"Location","South")
axis([-500 500 1 100])

MATLAB 設計のテスト

HDL コードを生成する前に、mlhdlc_sfir がサンプル ストリームをエラーなしで処理し、フィルター処理要件を満たしていることを確認します。mlhdlc_sfir_tb を使用して設計を実行し、チャープ入力を生成してローパス フィルター係数を提供します。テスト ベンチはサンプルを mlhdlc_sfir にストリーミングしてから、入力信号と出力信号の時間領域および周波数領域の動作をプロットします。

比較プロットは、フィルター処理された出力が時間領域の入力よりも滑らかであることを示しています。周波数領域では、フィルター処理された出力の振幅が、高周波数で入力よりも小さくなっています。テスト ベンチの結果により、mlhdlc_sfir がフィルター係数に従って期待どおりにローパス フィルターを実装していることが確認されます。

mlhdlc_sfir_tb

サードパーティ製の合成ツールと HDL シミュレーターの設定

次に、サードパーティ製の合成ツールと HDL シミュレーターを設定します。サポートされているサードパーティ製ツールのバージョンのリストについては、HDL の言語サポートおよびサポートされるサードパーティ製ツールとハードウェアを参照してください。

この例では、Xilinx Vivado を使用します。サードパーティ製の合成ツールのパスを設定するには、hdlsetuptoolpath関数を使用します。MATLAB コマンド ウィンドウで次のコマンドを使用します。パスは実際のインストール パスに置き換えてください。

hdlsetuptoolpath("ToolName","Xilinx Vivado","ToolPath",...
               vivadopath);

Xilinx Vivado 合成ツールの設定を確認するには、次のコマンドを実行して Xilinx Vivado を起動します。

!vivado

生成された HDL コードを HDL テストベンチを使用してシミュレートするには、ModelSim® などの HDL シミュレーターを使用します。サードパーティ製の FPGA 合成ツールと HDL シミュレーターの設定の詳細については、ツールの設定を参照してください。

メモ

コード生成の失敗を防ぐために、ファイル名またはパスにスペースを使用しないでください。openExample 関数の名前と値の引数 workDir を使用すると、スペースや特殊文字が含まれていない短い名前のディレクトリでこの例を開くことができます。たとえば、次のコードは現在の作業ディレクトリをシステムの一時フォルダー ディレクトリとして設定し、例を開きます。

tempdir
openExample("hdlcoder/BasicHDLCodeGenAndFPGASynthesisFromMATLABExample",workDir=tempdir)

HDL Coder プロジェクトの作成

HDL Coder プロジェクトを作成するには、次を行います。

1. MATLAB コマンド ウィンドウで、次のコマンドを実行して HDL Coder プロジェクトを作成します。

coder -hdlcoder -new sfir_project

2. [MATLAB 関数の追加] をクリックします。ダイアログ ボックスで、MATLAB 設計 mlhdlc_sfir を選択します。最上位の MATLAB 関数のみを追加します。

3. [ファイルの追加] をクリックします。ダイアログ ボックスで、テスト ベンチ mlhdlc_sfir_tb を選択します。

4. [MATLAB 関数] セクションで [型の自動定義] をクリックして入力の型を定義します。ダイアログ ボックスで、[実行] をクリックします。[入力の型の自動定義] ウィンドウで、[これらの型を使用] をクリックします。HDL Coder はテスト ベンチを実行して、MATLAB 設計 mlhdlc_sfir の入力データ型を推定します。

5. [ワークフロー アドバイザー] をクリックして HDL ワークフロー アドバイザーを開きます。

MATLAB 設計の固定小数点バージョンの作成

次に、固定小数点小数部の長さを提案し、安全余裕を追加して、MATLAB 設計の浮動小数点データ型を固定小数点データ型に変換します。[固定小数点の変換] タスクでは、[既定の語長] プロパティを使用して、浮動小数点データ型の語長を指定できます。この例では、[既定の語長]14 に設定します。

シミュレーション派生範囲に安全余裕を追加し、拡張された範囲に基づいて固定小数点データ型を提案するには、[シミュレーションの最小/最大値に対する安全余裕] プロパティを使用します。この例では、[詳細設定] をクリックし、[シミュレーションの最小/最大値に対する安全余裕]10 に設定します。

[固定小数点の変換] タスクを右クリックして [このタスクを実行] を選択します。

浮動小数点から固定小数点への変換の詳細については、浮動小数点から固定小数点への変換を参照してください。

コード生成ターゲットとプラットフォームの定義

生成された HDL コードをターゲット プラットフォームに展開するには、HDL コードを生成する前に、ターゲットとサードパーティ製の合成ツールを指定します。

[コード生成ターゲットを選択] タスクで、次のパラメーターを設定します。

  • [ワークフロー]Generic ASIC/FPGA に設定します。

  • [合成ツール]Xilinx Vivado に設定します。合成ツールが表示されない場合は [リストの更新] をクリックします。

  • [ターゲット周波数 (MHz)]200 に設定します。

[合成ツール]Xilinx Vivado に設定すると、HDL ワークフロー アドバイザーによって次のプロパティが公開され、次のように設定されます。

  • [チップ ファミリ]Artix UltraScale+ に設定されます。

  • [デバイス]xaau7p-fcva289-1-i に設定されます。

[コード生成ターゲットを選択] タスクを右クリックして [このタスクを実行] を選択します。

コード生成オプションの設定と HDL コードの生成

次に、HDL コード生成オプションを設定し、コードを生成します。[HDL コード生成] タスクで、次のオプションを設定します。

Verilog コードを生成するには、[ターゲット] タブで [言語]Verilog に設定します。

コメントとトレーサビリティ リンクを含むコード生成レポートを生成するには、次のようにします。

  • [ターゲット] タブで [レポートの生成] を選択します。

  • [コーディング スタイル] タブで、[コメントとして MATLAB ソース コードを含める] を選択します。

分散型パイプラインを使用して設計を最適化するには、次のようにします。

  • [最適化] タブで、[入力パイプライン][出力パイプライン]1 に設定します。

  • [最適化] タブで [分散型パイプライン レジスタ] を選択します。

分散型パイプラインの最適化の詳細については、分散型パイプラインの設定の指定を参照してください。

[実行] をクリックします。

Verilog コードを生成した後、右側のペインの下部にある [レポートの表示] リンクをクリックして、HDL Coder レポート ビューアーで HDL コード生成レポートを開きます。HDL コード生成レポートの詳細については、コード生成レポートを参照してください。

HDL テスト ベンチの生成と生成されたコードのシミュレート

次に、HDL テスト ベンチを生成し、HDL シミュレーターを使用して HDL テスト ベンチを実行し、HDL シミュレーションが固定小数点 MATLAB シミュレーションの数値やレイテンシと一致するかどうかを検証します。生成された HDL コードを HDL テスト ベンチで検証する方法の詳細については、HDL テスト ベンチを使用したコードの検証を参照してください。

[検証]、[HDL テスト ベンチによる検証] タスクで次のようにします。

  1. [出力設定] タブで、[テスト ベンチを生成] を選択します。

  2. [生成されたテスト ベンチをシミュレート] を選択します。

  3. [シミュレーション ツール]ModelSim に設定します。

  4. HDL テスト ベンチ コードとテスト ベンチ データを個別のファイルに生成するには、[テスト ベンチ オプション] タブで、[複数ファイルのテスト ベンチ] を選択します。

  5. [実行] をクリックします。

生成された HDL コードの合成

次に、HDL Coder を使用して、ターゲット プラットフォーム上での生成された HDL コードの合成を容易にし、ターゲット デバイスに基づいて設計の面積およびタイミング レポートを生成します。

生成された HDL コードを合成するには、次を行います。

1. [合成と解析]、[プロジェクトを作成] タスクを右クリックし、[このタスクを実行] を選択します。

このタスクでは、HDL コードの Xilinx Vivado 合成プロジェクトが作成されます。Xilinx Vivado はこのプロジェクトを使用して設計を合成します。

2. [合成と解析]、[合成を実行] タスクを右クリックし、[このタスクを実行] を選択します。

このタスクは、バックグラウンドで合成ツールを起動し、合成プロジェクトを開き、HDL コードをコンパイルして、設計を合成し、ネットリストと面積およびタイミング レポートを生成します。

3. [合成と解析]、[実装を実行] タスクを右クリックし、[このタスクを実行] を選択します。

このタスクは、バックグラウンドで合成ツールを起動して、設計上で配置配線を実行し、ソース設計のクリティカル パス解析とバック アノテーションに使用する配線前または配線後のタイミング情報を生成します。

参考

トピック