Main Content

Simulink Subsystem のセマンティクス

この一連の例では、さまざまなタイプの Simulink® Subsystem と、これらのサブシステムのシミュレーション実行時にどのようなセマンティクスが使用されるかという例を示します。各例では、モデルと、そのモデルの実行方法に関する違いを説明しています。

各サブシステム タイプの例を示しています。

  • バーチャル サブシステムおよび非バーチャル サブシステム

  • Function-Call Subsystem

  • Triggered Subsystem

  • Enabled Subsystem

  • Enabled and Triggered Subsystem

  • If Action Subsystem と Switch Case Action Subsystem

  • While Iterator Subsystem

  • For Each Subsystem

  • For Iterator Subsystem

Subsystem Semantics Examples

モデルを開きます。

open('SimulinkSubsystemSemantics.prj');
open_system('sl_subsys_semantics');

バーチャル サブシステムおよび非バーチャル サブシステムの概要

Simulink ソフトウェアには 2 種類のサブシステムがあります。

  1. バーチャル サブシステムはモデルにグラフィカルな階層を提供します。バーチャル サブシステムはモデルの実行に影響しません。モデルの実行中、Simulink エンジンはすべてのバーチャル サブシステムをフラットにします。

  2. 非バーチャル サブシステムは、モデルに実行とグラフィカルな階層を提供します。非バーチャル サブシステムは、単一ユニットとして実行されます。これは、アトミック実行と呼ばれます。すべての非バーチャル サブシステムは、Simulink キャンバスで太字の枠線付きで表示されます。

Virtual and nonvirtual subsystems

open_system('sl_subsys_semantics');
open_system('sl_subsys_semantics/Virtual and nonvirtual subsystem overview');  

非バーチャル サブシステムを作成するには、Subsystem ブロックを右クリックし、[ブロック パラメーター (Subsystem)] を選択します。[ブロック パラメーター] ダイアログ ボックスで [Atomic サブシステムとして扱う] を選択し、[適用] をクリックします。

The block parameters dialog box for the Subsystem2 block

バーチャル サブシステムではフラットな実行リストが作成されます。一方、非バーチャル サブシステムには実行階層があります。実行順序を表示するには、Simulink エディターの [デバッグ] タブで [情報のオーバーレイ] を選択し、[実行順序] をクリックします。

Blocks in a virtual and a nonvirtual subsystem display numbers showing the execution order

Simulink キャンバスに表示された [実行順序ブロック リスト] に実行順序が示されます。

The execution order block list

実行順序ブロック リストでは、非バーチャル サブシステム Subsystem2 が単一ユニットとして実行されたことが示されています。

非バーチャル サブシステムでは、実行階層内で代数ループが生じます。ブロック線図を更新すると、代数ループの警告が出されます。

set_param(gcs,'SimulationCommand','Update')
Warning: Model 'sl_subsys_overview' contains 1 algebraic loops. 

Function-Call Subsystem

Function-Call Subsystem ブロックには、制御端子が関数呼び出しイベントを受信するたびに実行される条件付き実行サブシステムが含まれています。Function-Call Subsystem は、Simulink ブロックを使用して呼び出し可能な関数を実装します。Stateflow®Chart (Stateflow)Function-Call Generatorブロック、MATLAB Functionブロック、S-Functionブロック、またはHit Crossing ブロックでは関数呼び出しイベントを提供できます。

Function Call Subsystem

詳細については、Function-Call Subsystemを参照してください。

以下の例では、Function-Call Subsystem の有効な使用例と無効な使用例を示します。

close_system('sl_subsys_overview',0)
open_system('s_Function_call_subsystems')

Function-Call Subsystem examples

入れ子関数呼び出し

このモデルでは、Chart は関数 [d1,d2]=f() を実行する関数呼び出しイニシエーターです。次に、関数 f が関数 g を実行します。fg を呼び出した後に、Chart は、fg で計算された値 d1d2 を使用します。

open_system('sl_subsys_fcncall1')

Two function-call subsystems for a nested function-call event

close_system('sl_subsys_fcncall1')

データ共有を使用した入れ子関数呼び出し

Chart ブロックは関数 [d1,d2]=f() を実行します。次に、fg を実行します。f を呼び出した後に、Chart は、fg で計算された値 d1d2 を使用します。関数 fg は、信号 s(f/Out2 feeds g/In1) を介してデータを共有します。Simulink は、信号がデータストアであるかのように信号 s を扱います。

open_system ('sl_subsys_fcncall2')

Two function-call subsystems for nested function-call events with output from one subsystem being fed to another

一般に、Function-Call Subsystem への入力は、共通の関数呼び出しイニシエーターによって実行されるブロックから信号が取得される場合を除き、関数呼び出しイニシエーター (Chart) の前に実行する必要があります。この例では、f()g() の関数呼び出しイニシエーターです。ただし、Chart は f() の関数呼び出しイニシエーターであるため、Chart は f()g() の共通の関数呼び出しイニシエーターとなります。

その意味で、以下の信号 s は、f()g() が Chart によって定義された所定の順序で読み書きするデータストアとみなすことができます。

close_system('sl_subsys_fcncall2')

共通のイニシエーターを使用した 2 つの Function-Call Subsystem 間のデータ共有

このモデルでは、d1d2 の計算にそれぞれ g()f() が使用されます。Chart は d1d2 を入力として使用し、g()f() を呼び出します。関数 fg は信号 s を介してデータを共有しており、つまり (f/Out1)(g/In1) に送られます。モデルは、信号がデータ ストアであるかのように信号 s を扱います。

open_system ('sl_subsys_fcncall3')

Two function-call subsystems that use the same function-call event source

一般に、Function-Call Subsystem への入力は、共通の関数呼び出しイニシエーターによって実行されるブロックから信号が取得される場合を除き、関数呼び出しイニシエーター (Chart) の前に実行する必要があります。この例では、Chart は f()g() の共通の関数呼び出しイニシエーターです。したがって、信号 s はデータ ストアとみなすことができます。

close_system('sl_subsys_fcncall3')

データ共有を使用した関数呼び出しイニシエーターを含む Enabled Subsystem

この Enabled Subsystem には、関数 f()g() を呼び出す Stateflow チャートが含まれています。モデル sl_subsys_fcncall4 の Enabled Subsystem は、f()g() の共通の関数呼び出しイニシエーターです。したがって、信号 s はデータストアとして扱われます。

open_system ('sl_subsys_fcncall4')

Two function-call subsystems that use function-call events from the same enabled subsystem

close_system('sl_subsys_fcncall4')

Merge ブロックを含む Function-Call Subsystem

このモデルには、2 つの関数呼び出しを実行するチャートが含まれています。このモデルは Merge ブロックを使用して、複数の信号を単一のメモリ位置にマッピングしています。信号 f/d1_outg/d1_out が単一のメモリ位置にマージされ、Chart に d1 としてフィードバックされています。信号 f/k_outg/k_out が単一のメモリ位置にマージされ、f/k_in にフィードバックされています。信号を単一のメモリ位置にマージして Chart にフィードバックすることで、Chart は値の計算方法について複雑な決定を下すことができます。

open_system ('sl_subsys_fcncall5')

Function-call subsystems with Merge block

close_system('sl_subsys_fcncall5')

Function-Call Subsystem の複数のイニシエーター

この Function-Call Subsystem は、2 つの異なる関数呼び出しイニシエーター Chart1 および Chart2 から呼び出されます。Chart1/out1Chart2/d1 間のデータ接続により、Chart1Chart2 の前に実行されることが保証されます。複数の呼び出し元をもつ Function-Call Subsystem を作成する場合は注意が必要です。

たとえば、Chart1Chart2 間のデータ接続を削除した場合、優先順位を Chart1 Chart2 に追加して、これらのブロックの相対実行順序を指定する必要があります。そうしないと、実行順序があいまいになります。

ただし、この条件は特定のケースでは有効である可能性があるため、この条件に対してエラーは出されません。例として、f() からすべてのステートを削除し、Chart1/out1Chart2/d1 に接続しているラインを削除した場合、Chart1Chart2 が実行される順序は重要ではなくなります。

open_system ('sl_subsys_fcncall6')

Function-call events from two different sources are set up to execute one function-call subsystem

close_system('sl_subsys_fcncall6')

リセット動作を指定する Function-Call Subsystem を含む Enabled Subsystem

この Enabled Subsystem には 2 つの Function-Call Subsystem が含まれています。左側の Function-Call Subsystem は、イネーブル状態の場合はステートの値を保持し、ディセーブル状態の場合は出力の値を保持するように構成されています。右側の Function-Call Subsystem は、イネーブル状態の場合はステートの値をリセットし、ディセーブル状態の場合は出力の値をリセットするように構成されています。

open_system ('sl_subsys_fcncall7')

Function-call subsystems are inside enabled subsystem

close_system('sl_subsys_fcncall7')

Function-Call Subsystem での周期的な実行の指定

この Stateflow チャートは、モデル内の Function-Call Subsystem の実行順序をスケジュールします。ただし、Function-Call Subsystem はタイム ステップごとに 1 回だけ実行されます。関数呼び出しでは、条件付き実行を指定するのではなく、サブシステムの相対的な実行順序を制御します。この設定は、データストアを使用してサブシステム間でデータを転送する場合に、データストアに対する読み取りと書き込みの適切な順序を保証するのに役立ちます。Function-Call Subsystem は無条件で実行されることを目的としているため、サブシステムの Trigger ブロックの [サンプル時間] パラメーターを使用して周期的なサンプル時間をもつように指定する必要があります。その結果、シミュレーション中、Simulink エンジンは周期的な Function-Call Subsystem がタイム ステップごとに 1 回だけ実行されることを検証します。

さらに、コードが生成されるとき、Function-Call Subsystem 内の経過時間は、通常の Function-Call Subsystem のようにタイマーに基づいて保持および計算されるのではなく、リテラル値 (指定した定数のサンプル時間) で表されます。したがって、生成されたコードは大幅に効率化します。

サブシステムのサンプル時間を表示するには、[Simulink エディター][デバッグ] タブで、[情報のオーバーレイ] を選択し、[色] をクリックします。

open_system ('sl_subsys_fcncall8')

Sample time is displayed for function-call subsystems executed periodically

Function-Call Subsystem のサンプル時間の色はシアンではなく赤であり、トリガー サンプル時間ではなく周期的なサンプル時間を示しています。関数呼び出し接続が交換されると、サブシステム内の Data Store Read ブロックと Data Store Write ブロック間の交互作用が変更されるため、結果として 1 タイム ステップ遅延します。

close_system('sl_subsys_fcncall8')

関数呼び出しイニシエーターによるアクティブ イベントと非アクティブ イベントの発行

この Stateflow チャートでは、イベント activate がステート ON にバインドされることを指定しています。ステート ON がアクティブに遷移すると、そのイベントによって開始された Function-Call Subsystem Integrate がイネーブルになります。また、ステートが非アクティブに遷移すると、そのイベントによって開始された Function-Call Subsystem がディセーブルになります。Function-Call Subsystem がイネーブルになるとステートをリセットし、ディセーブルになると出力をリセットするように構成されている場合、該当するアクションが行われます。この例では、このサブシステムは、イネーブルになったときにステートをリセットし、ディセーブルになったときに出力をリセットします。

open_system ('sl_subsys_fcncall9')

Function-call subsystem using active and inactive function-call events, respectively

close_system('sl_subsys_fcncall9')

Function-Call Subsystem の出力の解釈

1) 関数呼び出しの戻り値は、Function-Call Subsystem の出力からその関数呼び出しイニシエーターへの直接接続です。たとえば、以下の Stateflow チャート Chart1 は、関数 d1=f1() を実行する関数呼び出しイニシエーターです。f1 を呼び出した後に、チャートは、同じタイム ステップ内に f1 によって計算された戻り値 d1 を使用します。

2) 2 番目の例では、Unit Delay ブロックの実行は Chart2 によってトリガーされません。したがって、Chart2 の実行中、信号 d2 は、Unit Delay が呼び出された時点に該当する、前のタイム ステップからの値を維持します。

open_system ('sl_subsys_fcncall10')

Observe function-call subsystem output by delaying and feeding the function-call subsystem output into the stateflow chart that initiates the function-call event

close_system('sl_subsys_fcncall10')

関数呼び出し信号の分岐

この Stateflow チャートは、入力信号 u が 1 である時間間隔中に周期 1 の周期的な関数呼び出し信号を開始します。関数呼び出しごとに、サブシステムは、f hg の順序で実行されます。この実行順序は、Function-Call Split ブロックで指定された順序の結果であり、ドットで注釈が付けられた端子が先に実行されます。

このモデルを R2015b より前のリリースにエクスポートすると、信号 b がデータ依存性違反として扱われるため、エラーが発生します。

open_system ('sl_subsys_fcncall11')

Function-call subsystems respond to branched function-call signals

この Stateflow チャートは、入力信号 u が 1 である時間間隔中に周期 1 の周期的な関数呼び出し信号を開始します。

関数呼び出しごとに、サブシステム f1 がサブシステム g1 よりも前に実行されます。この実行順序は、Function-Call Split ブロックで指定された順序の結果であり、ドットで注釈が付けられた端子が先に実行されます。

このモデルを R2015b より前のリリースにエクスポートすると、サブシステム f1 の Inport ブロックの [Function-Call Subsystem 出力のフィードバック信号の入力をラッチする] パラメーターがクリアされている場合、信号 b がデータ依存性違反として扱われるため、エラーが発生します。

Function-call subsystems for branched function-call signals

close_system('sl_subsys_fcncall11')

無効な Function-Call Subsystem

無効な Function-Call Subsystem のリストを以下に示します。修正方法は、対応するモデル サブシステムで説明されています。

open_system('s_Function_call_subsystems')
  1. あいまいな実行順序のエラー

  2. 関数呼び出しイニシエーターによって駆動されるブロックに関連するデータ依存性違反

  3. 2 つの Function-Call Subsystem 間のブロックに関連するデータ依存性違反

  4. 変更された関数呼び出し出力のフィードバックに起因するあいまいな実行順序のエラー

  5. 2 つのサブシステム間の変更された関数呼び出し出力のフィードバックに起因するあいまいな実行順序のエラー

  6. Merge ブロックと Stateflow チャートに関連するデータ依存性違反

  7. Atomic サブシステムと Gain ブロックに関連するデータ依存性違反

  8. Function-Call Subsystem のサイクル データ依存性違反

  9. 間接的なデータ依存性違反

  10. 入れ子データ依存性違反

  11. Function-Call Subsystem での周期的な実行の正しくない指定

  12. 呼び出されたコンテキスト内で計算される Function-Call Subsystem の入力

  13. 分岐した関数呼び出し信号と Function-Call Subsystem を接続するブロックに関連したデータ依存性違反

close_system('s_Function_call_subsystems',0)

If Action Subsystem と Switch Case Action Subsystem

If Action Subsystem は、論理条件が true のときに各タイム ステップで実行されます。Switch Case Action Subsystem は、信号が指定された一連の値のいずれかであるときに実行されます。

If Action Subsystem

Switch Case Action Subsystem

詳細については、If Action SubsystemおよびSwitch Case Action Subsystemを参照してください。

以下の例では、If Action Subsystem と Switch Case Action Subsystem を使用する方法について説明します。

open_system('sl_subsys_semantics')
open_system('sl_subsys_semantics/If Action and Switch Case Action subsystems')

If and Switch Case Action Subsystems examples

close_system('sl_subsys_semantics/If Action and Switch Case Action subsystems')

Triggered Subsystem

Triggered Subsystem を使用すれば、ソフトウェア トリガー、ハードウェア トリガー、またはその 2 つの組み合わせを実装できます。Triggered Subsystem ブロックは Simulink ライブラリ ブラウザーから追加できます。あるいは、Triggerブロックを Subsystem ブロック内に配置してこのサブシステムを作成することもできます。

Triggered Subsystems

詳細については、Triggered Subsystemを参照してください。

以下の例では、Triggered Subsystem の使用方法を示します。

open_system('sl_subsys_semantics');
open_system('sl_subsys_semantics/Triggered subsystems')

Triggered Subsystem examples

ソフトウェア トリガーは、次のコードで定義されます。

if (trigger_signal_edge_detected) {

out(t) = f(in(t));

}

ハードウェア トリガーは、次のコードで定義されます。

if (trigger_signal_edge_detected) {

out(t) = f(in(t-h)); // h == last step size

}

Triggered Subsystem の各入力端子は、入力をラッチする必要があるかどうかを構成します。ラッチされた入力は、その入力端子のハードウェア トリガー セマンティクスを提供します。ラッチされた入力端子には、シンボル <L> が付けられます。

close_system('sl_subsys_semantics/Triggered subsystems')

Enabled Subsystem

Enabled Subsystem を使用すれば、イネーブル信号が 0 より大きい場合にのみ実行される条件付き実行サブシステムを作成できます。Enabled Subsystem により、出力信号の初期値を制御したり、サブシステムがイネーブルになるたびにステートをリセットするかどうかを制御したりできます。

Enabled Subsystem ブロックは Simulink ライブラリ ブラウザーから追加できます。あるいは、Enableブロックを Subsystem ブロック内に配置してこのサブシステムを作成することもできます。

Enabled Subsystem

詳細については、Enabled Subsystemを参照してください。

次の例では、Enabled Subsystem の使用方法を示します。

open_system('sl_subsys_semantics');
open_system('sl_subsys_semantics/Enabled subsystems')      

Enabled Subsystem examples

close_system('sl_subsys_semantics/Enabled subsystems')

Enabled and Triggered Subsystem

以下のサブシステムは、ステートと出力端子をリセットするオプションを示したものです。Enabled and Triggered Subsystem は、イネーブル条件とトリガー条件の両方が発生すると実行されます。

Enabled and Triggered Subsystem ブロックは Simulink ライブラリ ブラウザーから追加できます。あるいは、EnableブロックとTriggerブロックの両方を Subsystem ブロック内に配置してこのサブシステムを作成することもできます。

詳細については、Enabled and Triggered Subsystemを参照してください。

以下の例では、Enabled and Triggered Subsystem の使用方法を示します。

open_system('sl_subsys_semantics')
open_system('sl_subsys_enabtrig1.slx')  

Enabled and Triggered Subsystems

close_system('sl_subsys_enabtrig1.slx')        

Resettable Subsystem

Resettable Subsystem を使用すれば、リセット信号に基づいてサブシステム内のブロックのステートをリセットできます。Resettable Subsystem ブロックは Simulink ライブラリ ブラウザーから追加できます。

Resettable Subsystem

詳細については、Resettable Subsystemを参照してください。

以下の例では、Resettable Subsystem の使用方法を示します。

open_system('sl_subsys_semantics')
open_system('sl_subsys_semantics/Resettable subsystems')

Resettable Subsystem examples

close_system('sl_subsys_semantics/Resettable subsystems')

For Each Subsystem

For Each Subsystem は、シミュレーション タイム ステップ中に、入力信号またはマスク パラメーター配列の各要素またはサブ配列に対して実行を繰り返します。For Each Subsystem ブロックは Simulink ライブラリ ブラウザーから追加できます。あるいは、For Eachブロックを Subsystem ブロック内に配置してこのブロックを作成することもできます。For Each Subsystem は、入力信号の個々の要素またはサブ配列に対してアルゴリズムを繰り返します。For Each Subsystem は、サブシステムが処理する要素またはサブ配列ごとにブロックの状態を個別に保持します。

For Each Subsystem

詳細については、For Each Subsystemを参照してください。

以下の例では、For Each Subsystem の使用方法を示します。

open_system('sl_subsys_semantics');
open_system('sl_subsys_semantics/For Each subsystems')

For Each Subsystem examples

close_system('sl_subsys_semantics/For Each subsystems')

While Iterator Subsystem

While Iterator Subsystem は、シミュレーション タイム ステップ中、論理条件が true である間、実行を繰り返します。While Iterator Subsystem ブロックは Simulink ライブラリ ブラウザーから追加できます。あるいは、While Iteratorブロックを Subsystem ブロック内に配置してこのサブシステムを作成することもできます。While Iterator Subsystem は、各モデル タイム ステップで複数回の反復を実行します。反復回数は while 反復条件によって制御されます。

While Iterator Subsystem は、任意のタイム ステップで任意の回数の反復を実行できるという点で、Function-Call Subsystem と似ています。

While Iterator Subsystem が Function-Call Subsystem と異なる点は、Stateflow Chart のような独立したイニシエーターが含まれていないことです。さらに、While Iterator Subsystem は、オプションで While Iterator ブロックによって生成された現在の反復回数にアクセスできます。

While Iterator Subsystem

詳細については、While Iterator Subsystemを参照してください。

以下の例では、While Iterator Subsystem の使用方法を示します。

open_system('sl_subsys_semantics');
open_system('sl_subsys_semantics/While Iterator subsystems')

While Iterator Subsystem example

close_system('sl_subsys_semantics/While Iterator subsystems')

For Iterator Subsystem

For Iterator Subsystem は、シミュレーション タイム ステップ中に、指定された反復回数だけ実行を繰り返します。For Iterator Subsystem ブロックは Simulink ライブラリ ブラウザーから追加できます。あるいは、For Iteratorブロックを Subsystem ブロック内に配置してこのサブシステムを作成することもできます。For Iterator Subsystem は、モデルの各タイム ステップで固定された回数の反復を実行します。この反復回数は、For サブシステムへの外部入力とすることも、For Iterator ブロックで内部的に指定することもできます。

For Iterator Subsystem は While Iterator Subsystem とよく似ていますが、所定のタイム ステップでの反復回数が固定されているという制限があります。

For Iterator Subsystem

詳細については、For Iterator Subsystemを参照してください。

以下の例では、For Iterator Subsystem の使用方法を示します。

open_system('sl_subsys_semantics');
open_system('sl_subsys_semantics/For Iterator subsystems')   

For Iterator Subsystem Example

close_system('sl_subsys_semantics/For Iterator subsystems')

参考

関連するトピック