Main Content

このページの翻訳は最新ではありません。ここをクリックして、英語の最新版を参照してください。

MATLAB Function ブロックからのコード生成

MATLAB Function ブロックを使用したカウンター モデル

このチュートリアルでは、単純なモデルの eml_hdl_incrementer_tut を作成および構成して、その後、モデルから VHDL® コードを生成します。eml_hdl_incrementer_tut には、単純な固定小数点カウンター関数 incrementer を実装する MATLAB Function ブロックが含まれます。関数 incrementer は、モデルのサンプリング周期ごとに 1 回だけ呼び出されます。この関数は、MATLAB Function ブロックの ctr_preset 入力に渡された値に応じてインクリメントされるか、または事前設定された値 (ctr_preset_val) に再初期化される永続変数 count を保持します。また、MATLAB Function ブロックの出力時に、カウンター値 (counter) を返します。

MATLAB Function ブロックはサブシステム DUT_eML_Block 内に存在します。サブシステムは、HDL コードの生成元となる DUT (テスト対象デバイス) として機能します。

ルートレベル モデルはサブシステムを駆動し、シミュレーションで使用する Display ブロックと To Workspace ブロックを内包しています (Display ブロックと To Workspace ブロックは HDL コードを生成しません)。

ヒント

モデルをステップ単位で作成する必要がない場合または時間がない場合は、コマンド プロンプロで名前を入力することで完成したモデルを開くことができます。

eml_hdl_incrementer

モデルを開いた後、そのコピーを使用しているローカル フォルダーに eml_hdl_incrementer_tut として保存します。

関数 incrementer のコード

次のコードは関数 incrementer の完全な定義を示します。

function counter = incrementer(ctr_preset, ctr_preset_val)
% The function incrementer implements a preset counter that counts
% how many times this block is called. 
%
% This example function shows how to model memory with persistent variables,
% using fimath settings suitable for HDL. It also demonstrates MATLAB
% operators and other language features that HDL Coder supports
% for code generation from Embedded MATLAB Function block.
%
% On the first call, the result 'counter' is initialized to zero.
% The result 'counter' saturates if called more than 2^14-1 times.
% If the input ctr_preset receives a nonzero value, the counter is 
% set to a preset value passed in to the ctr_preset_val input.


persistent current_count;
if isempty(current_count)
    % zero the counter on first call only
    current_count = uint32(0); 
end
           

counter = getfi(current_count);

if ctr_preset
    % set counter to preset value if input preset signal is nonzero
    counter = ctr_preset_val; 
else
    % otherwise count up
    inc = counter + getfi(1); 
    counter = getfi(inc);    
end

% store counter value for next iteration
current_count = uint32(counter);

function hdl_fi = getfi(val)

nt = numerictype(0,14,0);
fm = hdlfimath;
hdl_fi = fi(val, nt, fm);

設定

モデル例のビルドを開始する前に、モデルと生成されるコード用の作業フォルダーを設定します。

フォルダーの設定

  1. MATLAB® を起動します。

  2. eml_tut という名前のフォルダーを作成します。たとえば、次のようにします。

    mkdir D:\work\eml_tut

    eml_tut フォルダーには作成するモデルが格納され、さらにサブフォルダーと生成されたコードが含まれます。このフォルダーは MATLAB ツリーの内部以外であれば任意の場所に配置できます。

  3. eml_tut を作業フォルダーにします。たとえば、次のようにします。

    cd D:\work\eml_tut

モデルの作成と一般的なモデル設定の構成

この節では、モデルを作成し、いくつかのパラメーターを HDL コード生成の hdlsetup コマンドで推奨される値に設定します。hdlsetup コマンドは関数 set_param を使用して、迅速かつ一貫性のある HDL コード生成のためにモデルを設定します。hdlsetup の詳細については、ターゲット アプリケーションに基づく関数 hdlsetup のカスタマイズを参照してください。

モデル パラメーターを設定するには、次の手順に従います。

  1. 新しいモデルを作成します。

  2. モデルを eml_hdl_incrementer_tut という名前で保存します。

  3. MATLAB コマンド プロンプトで、以下のように入力します。

    hdlsetup('eml_hdl_incrementer_tut');
    
  4. [コンフィギュレーション パラメーター] ダイアログ ボックスを開きます。

  5. 次の [ソルバー] オプションを設定します。これはこのモデルのシミュレーションに役立ちます。

    • 固定ステップ サイズ: 1

    • 終了時間: 5

  6. [OK] をクリックして変更を保存し、[コンフィギュレーション パラメーター] ダイアログ ボックスを閉じます。

  7. モデルを保存します。

MATLAB Function ブロックのモデルへの追加

  1. Simulink® ライブラリ ブラウザーを開きます。次に、Simulink/User-Defined Functions ライブラリを選択します。

  2. ライブラリ ウィンドウから MATLAB Function ブロックを選択し、モデルに追加します。

  3. ブロックのラベルを MATLAB Function から eml_inc_block に変更します。

  4. モデルを保存します。

  5. Simulink ライブラリ ブラウザーを閉じます。

MATLAB Function ブロックの固定小数点オプションの設定

この節では、MATLAB Function ブロックから効率的な HDL コードを生成するために推奨される fimath 仕様とその他の固定小数点オプションを設定する方法について説明します。推奨される設定は次のとおりです。

  • fimath 仕様の ProductMode プロパティ: 'FullPrecision'

  • fimath 仕様の SumMode プロパティ: 'FullPrecision'

  • [これらの継承される Simulink 信号タイプを fi オブジェクトとして扱う] オプション:[固定小数点] (既定の設定)

オプションは次の手順で設定します。

  1. MATLAB Function ブロックのモデルへの追加で作成した eml_hdl_incrementer_tut モデルを開きます。

  2. MATLAB Function ブロックをダブルクリックして、編集するために開きます。MATLAB Function ブロック エディターが表示されます。

  3. [データの編集] をクリックします。[端子とデータの管理] ダイアログ ボックスが開き、MATLAB Function ブロックの既定の fimath 仕様とその他のプロパティが表示されます。

  4. [それ以外を指定] を選択します。このオプションを選択すると、[MATLAB Function ブロックの fimath] テキスト入力フィールドが有効になります。

  5. 関数 hdlfimath は、HDL コード生成用に最適化された FIMATH 仕様を定義するユーティリティです。次のように hdlfimath を呼び出して、既定の [MATLAB Function ブロックの fimath] 仕様を置き換えます。

    hdlfimath;
  6. [適用] をクリックします。これで、MATLAB Function ブロックのプロパティは次の図のように表示されます。

  7. [端子とデータの管理] を終了します。

  8. モデルを保存します。

MATLAB Function ブロックのプログラミング

次の手順では、コードを MATLAB Function ブロックに追加して関数 incrementer を定義してから、診断を使用してエラーをチェックします。

  1. MATLAB Function ブロックのモデルへの追加で作成した eml_hdl_incrementer_tut モデルを開きます。

  2. MATLAB Function ブロックをダブルクリックして、編集するために開きます。

  3. MATLAB Function ブロック エディターで、既定のコードを削除します。

  4. 関数 incrementer のコードに記載されたリストから関数 incrementer の定義全体をコピーし、エディターに貼り付けます。

  5. モデルを保存します。これによりモデル ウィンドウが更新され、MATLAB Function ブロックが再描画されます。

    MATLAB Function ブロックの関数ヘッダーを変更すると、ブロック アイコンが次のように変更されます。

    • ブロック中央の関数名が incrementer に変更されます。

    • 引数 ctr_preset および ctr_preset_val がブロックへの入力端子として表示されます。

    • 戻り値 counter がブロックからの出力端子として表示されます。

  6. 端子ラベルが見やすくなるようにブロックのサイズを変更します。

  7. モデルを再び保存します。

DUT_eML_Block サブシステムの作成と接続

この節は、エラーが発生することなくMATLAB Function ブロックのプログラミングが完了されていることを前提としています。この節では、HDL コード生成元となる DUT (テスト対象デバイス) として使用される、incrementer 関数ブロックを含むサブシステムを作成します。その後、端子のデータ型を設定し、サブシステムの端子をモデルに接続します。

DUT_eML_Block サブシステムの作成

次の手順で incrementer 関数ブロックを含むサブシステムを作成します。

  1. incrementer 関数ブロックをクリックします。

  2. Simulink ツールストリップの [モデル化] タブで、[サブシステムの作成] を選択します。

    Subsystem とラベル付けされたサブシステムが、モデル ウィンドウに作成されます。

  3. ラベルを Subsystem から DUT_eML_Block に変更します。

MATLAB Function ブロックの端子のデータ型の設定

  1. サブシステムをダブルクリックして、その内部を表示します。次の図に示すように、サブシステムには入力端子と出力端子が接続された、incrementer 関数ブロックが含まれます。

  2. incrementer 関数ブロックをダブルクリックして MATLAB Function ブロック エディターを開きます。

  3. エディターで、[データの編集] を選択して [端子とデータの管理] を開きます。

  4. 左側の端子リストで ctr_preset エントリを選択します。[>>] とラベル付けされたボタンをクリックし、データ型アシスタントを表示します。この端子の [モード][組み込み] に設定します。[データ型][boolean] に設定します。[<<] とラベル付けされたボタンをクリックし、データ型アシスタントを閉じます。[適用] をクリックします。

  5. 左側の端子リストで ctr_preset_val エントリを選択します。[>>] とラベル付けされたボタンをクリックし、データ型アシスタントを表示します。この端子の [モード][固定小数点] に設定します。[符号属性][符号なし] に設定します。[語長] を 14 に設定します。[<<] とラベル付けされたボタンをクリックし、データ型アシスタントを閉じます。[適用] をクリックします。

  6. 左側の端子リストで counter エントリを選択します。[>>] とラベル付けされたボタンをクリックし、データ型アシスタントを表示します。この端子の [モード][継承:Simulink と同じ] に設定されていることを確認します。[<<] とラベル付けされたボタンをクリックし、データ型アシスタントを閉じます。[適用] をクリックします。

  7. [端子とデータの管理] ダイアログ ボックスと MATLAB Function ブロック エディターを閉じます。

  8. モデルを保存し、DUT_eML_Block サブシステムを閉じます。

サブシステムの端子のモデルへの接続

次に、DUT_eML_Block サブシステムの端子をモデルに次のようにして接続します。

  1. Sources ライブラリから、Constant ブロックをモデルに追加します。Constant ブロックの値を 1 に設定し、[出力データ型][boolean] に設定します。ブロックのラベルを Preset に変更します。

  2. Preset Constant ブロックのコピーを作成します。その値を 0 に設定し、ブロックのラベルを Increment に変更します。

  3. Signal Routing ライブラリから、Manual Switch ブロックをモデルに追加します。ラベルを Control に変更します。その出力を DUT_eML_Block サブシステムの In1 端子に接続します。

  4. Preset Constant ブロックを Control Switch ブロックの上部の入力に接続します。Increment Constant ブロックを Control Switch ブロックの下部の入力に接続します。

  5. 3 番目の Constant ブロックをモデルに追加します。Constant ブロックの値を 15 に設定し、[出力データ型][逆伝播による継承] に設定します。ブロックのラベルを Preset Value に変更します。

  6. Preset Value Constant ブロックを DUT_eML_Block サブシステムの In2 端子に接続します。

  7. Sinks ライブラリから、Display ブロックをモデルに追加します。それを DUT_eML_Block サブシステムの Out1 端子に接続します。

  8. Sinks ライブラリから、To Workspace ブロックをモデルに追加します。DUT_eML_Block サブシステムからの出力信号を To Workspace ブロックまで配線します。

  9. モデルを保存します。

関数のエラーのチェック

MATLAB Function ブロックの組み込みの診断機能を使用して、構文エラーがないかテストします。

  1. eml_hdl_incrementer_tut モデルを開きます。

  2. MATLAB Function ブロック incrementer をダブルクリックして、編集するために開きます。

  3. MATLAB Function ブロック エディターで、[モデルのビルド][ビルド] を選択し、MATLAB Function ブロック コードをコンパイルしてビルドします。

ビルド プロセスではいくつかの進行状況メッセージが表示されます。MATLAB Function ブロックの端子がまだ信号に接続されていないため、これらのメッセージにはいくつかの警告が含まれます。このような警告は無視してかまいません。

ビルド プロセスはシミュレーションで使用する S-Function をビルドします。ビルド プロセスには、S-Function の C コードの生成が含まれます。ビルド プロセス中に、HDL コード生成ではなく、C コードの生成に関するメッセージが表示されます。

ビルドがエラーを発生することなく終了すると、解析が正常に完了したことを示すメッセージ ウィンドウが表示されます。エラーが検出された場合は、Diagnostics Manager によってそれらがリストされます。MATLAB Function ブロックのビルド エラーのデバッグ方法の詳細については、MATLAB Function ブロックのドキュメンテーションを参照してください。

モデルのコンパイルと端子のデータ型の表示

この節では、端子のデータ型の表示を有効にし、その後、モデルをコンパイルします。モデルのコンパイルによって、モデルの構造と設定を検証し、モデルの表示を更新します。

  1. Simulink ツールストリップの [デバッグ] タブで、[情報のオーバーレイ][端子] セクションの [基本データ型] を選択します。

  2. Ctrl+D キーを押してモデルをコンパイルおよび更新します。これにより、コードのリビルドが開始されます。モデルのコンパイル後、ブロック線図が更新され、端子のデータ型が表示されます。

  3. モデルを保存します。

eml_hdl_incrementer_tut モデルのシミュレーション

シミュレーションを開始します。必要に応じて、シミュレーションを開始する前にコードをリビルドします。

シミュレーションの完了後、incrementer 関数ブロックによって返された最終出力が Display ブロックに表示されます。たとえば、[開始時間] を 0、[終了時間] を 5、ctr_preset 端子を 0 に指定すると、シミュレーションは値 6 を返します。

Control スイッチを切り替えたり、Preset Value 定数を変更したり、さらに総シミュレーション時間を変更したりして、その結果を比較してみてください。また、To Workspace ブロックにバインドされたワークスペース変数 simout も調べてみてください。

HDL コードの生成

この節では、HDL コード生成用の DUT_eML_Block サブシステムを選択し、基本的なコード生成オプションを設定し、その後、サブシステムの VHDL コードを生成します。

コード生成用のサブシステムの選択

コード生成用に DUT_eML_Block サブシステムを選択します。

  1. [コンフィギュレーション パラメーター] ダイアログ ボックスを開き、[HDL コード生成] ペインをクリックします。

  2. [HDL を生成] リストから [eml_hdl_incrementer_tut/DUT_eML_Block] を選択します。

  3. [適用] をクリックします。

VHDL コードの生成

[コンフィギュレーション パラメーター] ダイアログ ボックスで、この時点で [HDL コード生成] の最上位のオプションは次のように設定されています。

  • [HDL を生成] フィールドではコード生成に eml_hdl_incrementer_tut/DUT_eML_Block サブシステムが指定されています。

  • [言語] フィールドでは既定の [VHDL] コードの生成が指定されています。

  • [フォルダー] フィールドには、コード生成のターゲット フォルダーが hdlsrc という名前の作業フォルダーのサブフォルダーであることが示されます (既定の設定)。

コードを生成する前に、MATLAB コマンド ウィンドウで [レイアウト] メニューから [現在のフォルダー] を選択します。これで、現在のフォルダー ブラウザーが開き、作業フォルダーとその中で生成されるファイルへ簡単にアクセスできるようになります。

コードを生成するには、次の手順に従います。

  1. [生成] ボタンをクリックします。

    HDL Coder™ は、コードの生成前にモデルをコンパイルします。モデルの表示オプション (端子のデータ型など) によっては、コードの生成後にモデルの外観が変わることがあります。

  2. コードの生成が進むにつれて、進行状況に関するメッセージが表示されます。プロセスが終了すると次のメッセージが表示されます。

    ### HDL Code Generation Complete.
    

    進行状況のメッセージ内の生成された VHDL ファイルの名前はハイパーリンクになっています。コードの生成が完了したら、これらのハイパーリンクをクリックして MATLAB エディターでファイルを表示できます。

  3. hdlsrc フォルダーのアイコンが現在のフォルダー ブラウザーに表示されます。生成されたコードとスクリプト ファイルを表示するには、hdlsrc フォルダー アイコンをダブルクリックします。

  4. 2 つの VHDL ファイルが生成されたことがわかります。MATLAB Function ブロック用に生成された HDL コードの構造は、Stateflow® チャートおよび Digital Filter ブロック用に生成されたコードの構造に似ています。hdlsrc フォルダーに生成された VHDL ファイルは次のとおりです。

    • eml_inc_blk.vhd: VHDL コード。このファイルには、MATLAB Function ブロック用に生成された、実際の計算を実装するエンティティとアーキテクチャ コードが含まれます。

    • DUT_eML_Block.vhd: VHDL コード。このファイルには、eml_inc_blk.vhd で生成されたコードへのブラック ボックス インターフェイスを提供するエンティティ定義と RTL アーキテクチャが含まれています。

    これらのコード ファイルの構造はモデルの構造と同じで、DUT_eML_Block サブシステムはルート モデルと MATLAB Function ブロック内の関数 incrementer の間にインターフェイスを提供します。

    hdlsrc フォルダーに生成されるその他のファイルは次のとおりです。

    • DUT_eML_Block_compile.do: 2 つの .vhd ファイルの VHDL コードをコンパイルするための Mentor Graphics® ModelSim® コンパイル スクリプト (vcom コマンド)。

    • DUT_eML_Block_synplify.tcl: Synplify® 合成スクリプト。

    • DUT_eML_Block_map.txt: マッピング ファイル。このレポート ファイルは、生成されたエンティティ (またはモジュール) を生成元のサブシステムにマッピングします (マッピング ファイルを使用したコードのトレースを参照してください)。

  5. 生成された VHDL コードを MATLAB エディターで表示するには、現在のフォルダー ブラウザーで DUT_eML_Block.vhd または eml_inc_blk.vhd ファイル アイコンをダブルクリックします。

参考

関連するトピック