Main Content

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

ブロック パラメーターのデータ型を指定した効率的なコードの生成

さらに効率的なコードを生成するには、ブロック パラメーターのデータ型 (Gain ブロックの [ゲイン] パラメーターなど) を信号のデータ型と一致させます。あるいは、パラメーターをさらにサイズが小さいデータ型で保存します。

データ型の一致による不要な型変換およびシフトの除去

以下の例では、ブロックが操作を行う信号と同じデータ型を使用するようにブロック パラメーターを設定することで、効率的なコードを生成する方法を説明します。

モデルへのデータ型情報の保存

モデル例 rtwdemo_configrpinterface を開き、生成されたブロック名を表示するよう設定します。

open_system('rtwdemo_configrpinterface')
set_param('rtwdemo_configrpinterface','HideAutomaticNames','off')

[モデル化] タブで [モデル データ エディター] をクリックします。

モデル データ エディターで、[パラメーター] タブを選択します。

モデルで Gain ブロックを選択します。モデル データ エディターで、[データ型] 列に、ブロックの [ゲイン] パラメーターのデータ型が [Inherit: Same as input] に設定されていることが示されます。この設定では、このブロックの [ゲイン] パラメーターは、入力信号と同じデータ型を使用します。

コード マッピング エディターの [パラメーター] で、K1 のストレージ クラスを ExportedGlobal に設定します。

モデル データ エディターで、[ビューの変更] を [Design] に設定します。

データ テーブルで K1 を表す行の [データ型] 列で、[Auto] を選択します。この設定を使用して、パラメーター オブジェクトはオブジェクトを使用するブロック パラメーターからそのデータ型を取得します (この場合、"Gain" ブロック パラメーター)。

または、オブジェクトを作成して構成するには、コマンド プロンプトで以下のコマンドを使用します。

cm = coder.mapping.api.get('rtwdemo_configrpinterface');
setModelParameter(cm,'K1','StorageClass','ExportedGlobal');
hws = get_param(bdroot, 'modelworkspace');
hws.setVariablePart('K1.DataType','Auto');

モデルからコードを生成します。

slbuild('rtwdemo_configrpinterface')
### Starting build procedure for: rtwdemo_configrpinterface
### Successful completion of code generation for: rtwdemo_configrpinterface

Build Summary

Top model targets built:

Model                      Action          Rebuild Reason                                    
=============================================================================================
rtwdemo_configrpinterface  Code generated  Code generation information file does not exist.  

1 of 1 models built (0 models already up to date)
Build duration: 0h 0m 15.863s

生成されたファイル rtwdemo_configrpinterface.c は、データ型 real_T. を使用してグローバル変数 K1 を定義します。

file = fullfile('rtwdemo_configrpinterface_grt_rtw','rtwdemo_configrpinterface.c');
rtwdemodbtype(file,'/* Exported block parameters */','real_T K1 = 2.0;',1,1)
/* Exported block parameters */
real_T K1 = 2.0;                       /* Variable: K1

モデルの関数 step の生成されたコードのアルゴリズムは、型変換を行わずに K1 を直接使用します。

rtwdemodbtype(file,'output =',...
    '10U',1,1)
    output = K1 * look1_binlc((*input2), rtCP_Table1_bp01Data,
      rtCP_Table1_tableData, 10U);

コード マッピング エディターの [パラメーター] で、K1 のストレージ クラスをオプションで Inherit: Inherit via internal rule (既定の設定) に設定できます。

この場合、ブロック パラメーターは入力信号 double と同じデータ型を選択します。ただし、その他の状況で [Inherit: Inherit via internal rule] を使用する場合 (たとえば、固定小数点データ型を使用する場合)、ブロック パラメーターは異なるデータ型を選択することがあります。

パラメーター オブジェクトへのデータ型情報の格納

Simulink.Parameter オブジェクトを使用して、生成されたコードからパラメーター データを外部のコードにエクスポートまたはインポートする場合、たとえばストレージ クラス ImportedExtern を適用することで、パラメーター オブジェクトにデータ型の情報を指定できます。パラメーター オブジェクトのデータ型と信号のデータ型を一致させるには、Simulink.NumericType オブジェクトまたは Simulink.AliasType オブジェクトを作成します。パラメーター オブジェクトが生成されたコードで使用するデータ型を厳密に制御して、モデルを変更する場合に Simulink が異なるデータ型を選択するリスクを削減できます。

コマンド プロンプトで、データ型 double を表す Simulink.NumericType オブジェクトを作成します。

myType = Simulink.NumericType;
myType.DataTypeMode = 'Double';

モデル データ エディターの [データ型] 列を使用して、以下のデータ型を [myType] に設定します。

  • パラメーター オブジェクト。[パラメーター] タブを使用します。

  • In2 という名前の Inport ブロック。[入力端子/出力端子] タブを使用します。データ型の伝播のために、Gain ブロックの入力信号も myType を使用します。

モデル データ エディターの [パラメーター] タブを使用して、Gain ブロック パラメーターのデータ型を Inherit: Inherit from 'Gain' に設定します。

このデータ型オブジェクトをパラメーター オブジェクトのデータ型として使用します。

または、オブジェクトとブロックを構成するために、次のコマンドをコマンド プロンプトで使用します。

K1.DataType = 'myType';
set_param('rtwdemo_configrpinterface/In2','OutDataTypeStr','myType')
set_param('rtwdemo_configrpinterface/Gain','ParamDataTypeStr','Inherit: Inherit from ''Gain''')

モデルからコードを生成します。

slbuild('rtwdemo_configrpinterface')
### Starting build procedure for: rtwdemo_configrpinterface
### Successful completion of code generation for: rtwdemo_configrpinterface

Build Summary

Top model targets built:

Model                      Action          Rebuild Reason                   
============================================================================
rtwdemo_configrpinterface  Code generated  Generated code was out of date.  

1 of 1 models built (0 models already up to date)
Build duration: 0h 0m 14.658s

グローバル変数 K1 は引き続き、データ型 real_T を使用します。

file = fullfile('rtwdemo_configrpinterface_grt_rtw','rtwdemo_configrpinterface.c');
rtwdemodbtype(file,'/* Exported block parameters */','real_T K1 = 2.0;',1,1)
/* Exported block parameters */
real_T K1 = 2.0;                       /* Variable: K1

コード生成レポートを閉じます。

rtwdemoclean;

パラメーター値のサイズが小さいデータ型での格納によるメモリ消費の削減

パラメーター オブジェクト (たとえば、Simulink.Parameter) を使用して、ブロック パラメーター値を設定する場合、オブジェクトを、生成されたコードに調整可能なグローバル変数として表示されるように設定できます。既定では、パラメーター オブジェクトおよび対応するグローバル変数は通常、信号またはブロックが操作する信号と同じデータ型を使用します。たとえば、Gain ブロックの入力信号がデータ型 int16 を使用する場合、パラメーター オブジェクトは通常同じデータ型を使用します。この変数が消費するメモリ量を削減するには、int8 などのサイズが小さい整数データ型を変数が使用するように指定します。

整数データ型でのパラメーター値の格納

モデル rtwdemo_configrpinterface を開き、そのモデルのプロパティを設定します。

open_system('rtwdemo_configrpinterface')
set_param('rtwdemo_configrpinterface','HideAutomaticNames','off')
set_param('rtwdemo_configrpinterface','ShowPortDataTypes','on')
set_param('rtwdemo_configrpinterface','SimulationCommand','Update')

モデル内の多くの信号が、データ型 double を使用します。

[モデル化] タブで [モデル データ エディター] をクリックします。

モデル データ エディターで、[パラメーター] タブを検査します。

[追加情報を表示/更新します] ボタンをクリックします。

[コンテンツのフィルター] ボックスの横にある [選択を使用してフィルター処理します] ボタンを有効にします。

モデルで、Gain ブロックをクリックします。モデル データ エディターでは、ブロックの [ゲイン] パラメーターに対応する行が 1 つ、パラメーター値を 2 に設定する MATLAB 変数 K1 に対応する行が 1 つ表示されます。K1 はモデル ワークスペース内に存在します。

[C コード] タブで、[コード インターフェイス]、[既定のコード マッピング] を選択します。コード マッピング エディターの [パラメーター] で、K1 のストレージ クラスを ExportedGlobal に設定します。

cm = coder.mapping.api.get('rtwdemo_configrpinterface');
setModelParameter(cm,'K1','StorageClass','ExportedGlobal');

[C コード] タブで、[コード インターフェイス]、[既定のコード マッピング] を選択します。モデル データ エディターで、[ビューの変更]Design に設定し、K1 列の [データ型]int8 であることを確認します。

hws = get_param(bdroot, 'modelworkspace');
hws.setVariablePart('K1.DataType','int8');

Gain ブロック パラメーターを表す行の [データ型] 列で、ドロップダウン リストを [Inherit: Inherit from 'Gain'] に設定します。この設定により、ブロックの [ゲイン] パラメーターはパラメーター オブジェクトから int8 データ型を継承します。

set_param('rtwdemo_configrpinterface/Gain','ParamDataTypeStr',...
    'Inherit: Inherit from ''Gain''')

モデルからコードを生成します。

rtwbuild('rtwdemo_configrpinterface')
### Starting build procedure for: rtwdemo_configrpinterface
### Successful completion of code generation for: rtwdemo_configrpinterface

Build Summary

Top model targets built:

Model                      Action          Rebuild Reason                                    
=============================================================================================
rtwdemo_configrpinterface  Code generated  Code generation information file does not exist.  

1 of 1 models built (0 models already up to date)
Build duration: 0h 0m 12.457s

生成されたファイル rtwdemo_configrpinterface.c は、データ型 int8_T (これは、Simulink でのデータ型 int8 に対応) を使用してグローバル変数 K1 を定義します。

file = fullfile('rtwdemo_configrpinterface_grt_rtw','rtwdemo_configrpinterface.c');
rtwdemodbtype(file,'/* Exported block parameters */','int8_T K1 = 2;',1,1)
/* Exported block parameters */
int8_T K1 = 2;                         /* Variable: K1

モデルの関数 step のコード アルゴリズムは、K1 を使用して、Gain ブロックの出力を計算します。計算に使用される信号がデータ型 real_T を使用するため、アルゴリズムでは、K1 をデータ型 real_T (double) にキャストします。

rtwdemodbtype(file,'output =',...
    '10U',1,1)
    output = (real_T)K1 * look1_binlc((*input2), rtCP_Table1_bp01Data,
      rtCP_Table1_tableData, 10U);

サイズが小さい整数データ型での固定小数点パラメーター値の格納

モデルの信号を固定小数点データ型を使用して設定するとします。ゲイン パラメーターが生成されたコードに調整可能なグローバル変数として表示されるようにします。パラメーターにとって想定される実際値 (たとえば、0 ~ 4 の間) の範囲がわかります。精度を低下させてもアプリケーション要件を満たす場合、パラメーターをブロックの入出力信号と異なるデータ型を使用するように設定することで、メモリ消費を削減します。

モデル例 fxpdemo_direct_form2 を開き、生成されたブロック名を表示するよう設定します。

load_system('fxpdemo_direct_form2')
set_param('fxpdemo_direct_form2','HideAutomaticNames','off')
open_system('fxpdemo_direct_form2')

ブロック線図を更新します。モデルの信号は、語長が 16 で 2 進小数点のみのスケーリングを行う符号付き固定小数点データ型を使用します。

[Gain5 ブロック] ダイアログ ボックスを開きます。[ゲイン] パラメーターが 1.85 に設定されています。このパラメーターを設定するとします。

[ゲイン]myGainParam に設定して [適用] をクリックします。

パラメーター値の横にあるアクション ボタン (3 つの縦向きのドット) をクリックします。[作成] を選択します。

[新規データの作成] ダイアログ ボックスで、[値]Simulink.Parameter(1.85) に設定して [作成] をクリックします。Simulink.Parameter オブジェクト myGainParam がベース ワークスペースに表示されます。

Simulink Coder アプリを開きます。[C コード] タブで、[コード インターフェイス]、[既定のコード マッピング] を選択します。コード マッピング エディターの [パラメーター] で、myGainParam のストレージ クラスを ExportedGlobal に設定します。この設定により、myGainParam はグローバル変数として生成されたコードに表示されます。

ブロック ダイアログ ボックスの [パラメーター属性] タブでは、[パラメーターの最小値]0 に、[パラメーターの最大値]4 に設定します。

[パラメーターのデータ型]fixdt(0,8) に設定して [適用] をクリックします。

[データ型アシスタントを表示] ボタンをクリックします。データ型アシスタントには、式 fixdt(0,8) が、語長が 8 で最高精度のスケーリングを行う符号なしの固定小数点データ型を指定していることが示されます。コードのシミュレーションまたは生成時には、ブロック パラメーターの選択する小数部の長さ (スケーリング) によって、データ型はパラメーターの最小値と最大値 (0 および 4) の間で可能な限り最高の精度の値を表すことができます。

データ型アシスタントで、[スケーリング]Binary point に設定します。[最高精度のスケーリングを計算][固定小数点の詳細] および [詳細の更新] をクリックします。[固定小数点の詳細] の情報は、小数部の長さ 5 が、精度 0.03125 のパラメーター値を表すことを示します。

[スケーリング]Best precision に戻して [OK] をクリックします。この例では、コードのシミュレーションおよび生成を行う際に、ブロック パラメーターが小数部の長さ 5 を選択します。

または、コマンド プロンプトでこれらのコマンドを使用して、次のようにオブジェクトを作成してブロックを設定できます。

myGainParam = Simulink.Parameter(1.85);
myGainParam.CoderInfo.StorageClass = 'ExportedGlobal';
set_param('fxpdemo_direct_form2/Gain5','Gain','myGainParam')
set_param('fxpdemo_direct_form2/Gain5','ParamMin','0','ParamMax','4')
set_param('fxpdemo_direct_form2/Gain5','ParamDataTypeStr','fixdt(0,8)')

コード生成レポートを作成するようにモデルを設定します。コマンド ウィンドウを見やすくするために、コンフィギュレーション パラメーター [詳細なビルド] をクリアします。

set_param('fxpdemo_direct_form2','GenerateReport','on',...
    'LaunchReport','on','RTWVerbose','off')

モデルからコードを生成します。

evalc('rtwbuild(''fxpdemo_direct_form2'')');

生成されたファイル fxpdemo_direct_form2.c は、データ型 uint8_T (指定された語長 8 に対応する) を使用することで、グローバル変数 myGainParam を定義します。このコードは、小数部の長さが 5 と指定され、実際のパラメーター値 1.85 を表す整数値を使用して変数を初期化します。

file = fullfile('fxpdemo_direct_form2_grt_rtw','fxpdemo_direct_form2.c');
rtwdemodbtype(file,'/* Exported block parameters */','uint8_T myGainParam = 59U;',1,1)
/* Exported block parameters */
uint8_T myGainParam = 59U;             /* Variable: myGainParam

コード アルゴリズムは myGainParam を使用して、Gain5 ブロックの出力を計算します。アルゴリズムは C シフトを使用して計算の結果をスケーリングします。

rtwdemodbtype(file,'/* Gain: ''<Root>/Gain5'' incorporates:',...
'/* Gain: ''<Root>/Gain'' incorporates:',1,0)
  /* Gain: '<Root>/Gain5' incorporates:
   *  UnitDelay: '<Root>/Unit Delay1'
   */
  fxpdemo_direct_form2_B.Gain5 = (int16_T)((myGainParam *
    fxpdemo_direct_form2_B.UnitDelay1) >> 5);
rtwdemoclean;

関連するトピック