Main Content

MATLAB からの基本の HDL コード生成と FPGA 合成

この例では、HDL Coder™ プロジェクトの作成、MATLAB® 設計のコードの生成、および HDL コードの合成方法について説明します。この例では次を行います。

  1. MATLAB HDL Coder プロジェクトを作成します。

  2. 設計およびテスト ベンチ ファイルをプロジェクトに追加します。

  3. MATLAB 設計の HDL ワークフロー アドバイザーを起動します。

  4. 固定小数点変換と HDL コード生成を実行します。

  5. MATLAB テスト ベンチから HDL テスト ベンチを生成します。

  6. HDL シミュレーターを使用して、生成された HDL コードを検証します。この例ではツールとして ModelSim® を使用します。

  7. 合成ツールを使用して生成された HDL コードを合成します。この例では Xilinx® Vivado® をツールとして使用します。

FIR フィルター MATLAB 設計

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

design_name = 'mlhdlc_sfir';
testbench_name = 'mlhdlc_sfir_tb';

MATLAB 設計を確認します。

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-2019 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

FIR フィルター MATLAB テスト ベンチ

MATLAB テスト ベンチ mlhdlc_sfir_tb は、典型的な入力範囲を使用してフィルターの設計を実行します。MATLAB テスト ベンチ mlhdlc_sfir_tb を確認します。

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

%   Copyright 2011-2019 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', [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 アルゴリズムのテスト

実行時エラーを避けるために、テスト ベンチを使用して設計をシミュレートします。

mlhdlc_sfir_tb

フォルダーの作成と関連ファイルのコピー

サンプル ファイルを一時フォルダーにコピーするには、次のコマンドを実行します。

design_name = 'mlhdlc_sfir';
testbench_name = 'mlhdlc_sfir_tb';

一時フォルダーを作成します。

mlhdlc_demo_dir = fullfile(matlabroot, 'toolbox', 'hdlcoder', 'hdlcoderdemos', 'matlabhdlcoderdemos');
mlhdlc_temp_dir = [tempdir 'mlhdlc_sfir'];
cd(tempdir);
[~, ~, ~] = rmdir(mlhdlc_temp_dir, 's');
mkdir(mlhdlc_temp_dir);
cd(mlhdlc_temp_dir);

MATLAB ファイルをコピーします。

copyfile(fullfile(mlhdlc_demo_dir, [design_name,'.m*']), mlhdlc_temp_dir);
copyfile(fullfile(mlhdlc_demo_dir, [testbench_name,'.m*']), mlhdlc_temp_dir);

HDL シミュレーターと合成ツールのパスの設定

生成された HDL コードを合成する場合は、HDL Coder を使用してコードを生成する前に、合成ツールのパスを設定します。合成ツールへのパスを設定するには、関数 hdlsetuptoolpath を使用します。たとえば、合成ツールが Xilinx Vivado である場合は次のようになります。

hdlsetuptoolpath('ToolName','Xilinx Vivado','ToolPath',...
               'C:\Xilinx\Vivado\2018.3\bin\vivado.bat');

Xilinx Vivado がインストール済みでなければなりません。Xilinx Vivado 合成ツールの設定を確認するには、次のコマンドを実行してツールを起動します。

!vivado

HDL テスト ベンチを使用して生成された HDL コードをシミュレートする場合は、ModelSim® などの HDL シミュレーターを使用できます。HDL シミュレーターがインストールされていないければなりません。

HDL Coder プロジェクトの作成

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

1. 次のコマンドを実行してプロジェクトを作成します。

coder -hdlcoder -new sfir_project

2.MATLAB 関数で、MATLAB 設計 mlhdlc_sfir を追加します。mlhdlc_sfir_tb.m を MATLAB テスト ベンチとして追加します。

3.[型の自動定義] をクリックして、MATLAB 設計の推奨タイプを使用します。コード ジェネレーターは、テスト ベンチを実行してデータ型を推定します。

アルゴリズムとテスト ベンチの固定小数点バージョンの作成

  1. [ワークフロー アドバイザー] ボタンをクリックして、ワークフロー アドバイザーを開きます。[入力の型を定義] タスクが成功したことがわかります。

  2. [固定小数点の変換] タスクを実行します。右側のペインに、[固定小数点の変換] ツールが表示されます。

固定小数点の変換を実行する際に、浮動小数点データ型の小数部の長さを推奨するために、HDL Coder は [既定の語長] を使用します。このチュートリアルでは、[既定の語長] は、14 です。アドバイザーで使用される [シミュレーションの最小/最大値に対する安定余裕] の既定値は 0% です。この安全余裕係数によってデータの範囲が調整されます。たとえば値が 4 の場合は、少なくとも 4 % 大きい範囲を指定することになります。浮動小数点から固定小数点への変換も参照してください。

コード生成オプションの選択と HDL コードの生成

HDL コードを生成する前に、コードをターゲット プラットフォームに展開する場合は、合成ツールを指定します。[コード生成ターゲット] タスクで、[ワークフロー] を [Generic ASIC/FPGA] のままにし、[合成ツール] として [Xilinx Vivado] を指定します。合成ツールが表示されない場合は [リストの更新] をクリックします。このタスクを実行します。

[HDL コード生成] タスクで、このタスクの右側にあるタブを使用して、追加のコード生成オプションを指定できます。

  1. 既定では、HDL Coder で VHDL® コードが生成されます。Verilog コードを生成するには、[ターゲット] タブで、[言語] として [Verilog] を選択します。

  2. コメントとトレーサビリティのリンクが含まれるコード生成レポートを生成するには、[コーディング スタイル] タブで [コメントとして MATLAB ソース コードを含める] および [レポートの生成] を選択します。

  3. 設計を最適化するには、分散型パイプライン方式の最適化を使用できます。[最適化] タブで、[入力パイプライン][出力パイプライン]1 を指定してから、[分散型パイプライン レジスタ] を選択します。詳細については、分散型パイプライン方式を参照してください。

  4. Verilog コードを生成するには [実行] をクリックします。

ログ ウィンドウを確認し、リンクをクリックして生成されたコードとレポートを調べます。

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

HDL Coder は、HDL テスト ベンチを生成し、HDL シミュレーターを使用して HDL テスト ベンチを実行し、HDL シミュレーションが固定小数点 MATLAB シミュレーションの数値やレイテンシと一致するかどうかを検証します。

HDL テスト ベンチを生成し、生成されたコードをシミュレートするには、[HDL の確認]、[HDL テスト ベンチによる検証] タスクで、次を行います。

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

  2. 生成されたテスト ベンチをシミュレートするには、[シミュレーション ツール] を [ModelSim] に設定します。ModelSim がインストール済みでなければなりません。

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

  4. [実行] ボタンをクリックします。

HDL テスト ベンチが生成され、選択したシミュレーション ツールを使用して固定小数点の設計がシミュレートされ、コンパイル レポートとシミュレーション レポートが生成されます。

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

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

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

1. [プロジェクトを作成] タスクを実行します。

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

2.[合成の実行] タスクを選択して実行します。

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

3.[実装を実行] タスクを選択して実行します。

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

生成ファイルのクリーンアップ

一時的なプロジェクト フォルダーをクリーンアップするには、次のコマンドを実行します。

mlhdlc_demo_dir = fullfile(matlabroot, 'toolbox', 'hdlcoder', 'hdlcoderdemos', 'matlabhdlcoderdemos');
mlhdlc_temp_dir = [tempdir 'mlhdlc_sfir'];
clear mex;
cd (mlhdlc_demo_dir);
rmdir(mlhdlc_temp_dir, 's');