高度なチャート機能を使用した設計パターン
時相論理
Stateflow® 時相論理演算子 (after
、before
、every
など) は、Stateflow イベントが繰り返されるたびに動作するブール演算子です。時相論理演算子は、ステートから派生する遷移の条件とステートのアクションのみで使用されます。時相論理は Stateflow モデルに新しいイベントを導入しませんが、時相論理条件の値の変化をイベントとして考えると便利です。時相論理演算子は、カウンターが必要な多くの場合に使用できます。一般的な使用例として、時相論理を使用したタイムアウト カウンターの実装があげられます。
詳細については、時相論理を使用したチャート実行の制御 (Stateflow)を参照してください。
次の図に示すチャートでは、デバウンサーの設計に時相論理が使用されています。オン ステートとオフ ステートを瞬時に切り替える代わりに、チャートは 2 つの中間ステートと時相論理を使用して遷移を無視しています。遷移はタイムアウトに基づいてコミットされます。
既定では、Stateflow Chart のステートはアルファベット順に並んでいます。HDL コード内のステートの並び順は、HDL コードでアクティブ ステート出力端子生成を有効にした場合、異なることがあります。この設定を有効にするには、Chart プロパティを開き、[監視する出力端子を作成する] チェック ボックスをオンにします。アクティブ ステート出力の組み込みによる Stateflow チャートの簡略化 (Stateflow)も参照してください。
VHDL® コードを生成すると、最近追加されたステートが、HDL コード内で OTHERS
ステートとして選択されます。次のコードの抜粋は、この Chart から生成された VHDL コードを示しています。
Chart_1_output : PROCESS (is_Chart, u, temporalCounter_i1, y_reg) VARIABLE temporalCounter_i1_temp : unsigned(7 DOWNTO 0); BEGIN temporalCounter_i1_temp := temporalCounter_i1; is_Chart_next <= is_Chart; y_reg_next <= y_reg; IF temporalCounter_i1 < 7 THEN temporalCounter_i1_temp := temporalCounter_i1 + 1; END IF; CASE is_Chart IS WHEN IN_tran1 => IF u = 1.0 THEN is_Chart_next <= IN_on; y_reg_next <= 1.0; ELSIF temporalCounter_i1_temp >= 3 THEN is_Chart_next <= IN_off; y_reg_next <= 0.0; END IF; WHEN IN_tran2 => IF temporalCounter_i1_temp >= 5 THEN is_Chart_next <= IN_on; y_reg_next <= 1.0; ELSIF u = 0.0 THEN is_Chart_next <= IN_off; y_reg_next <= 0.0; END IF; WHEN IN_off => IF u = 1.0 THEN is_Chart_next <= IN_tran2; temporalCounter_i1_temp := to_unsigned(0, 8); END IF; WHEN OTHERS => IF u = 0.0 THEN is_Chart_next <= IN_tran1; temporalCounter_i1_temp := to_unsigned(0, 8); END IF; END CASE; temporalCounter_i1_next <= temporalCounter_i1_temp; END PROCESS Chart_1_output;
グラフィカル関数
グラフィカル関数は、流れ図によってグラフィカルに定義された関数です。グラフィカル関数は、それらを呼び出すブロック線図とともにチャート内に存在します。MATLAB® 関数や C 関数と同様に、グラフィカル関数は引数を受け入れ、結果を返すことができます。グラフィカル関数は、遷移とステート アクションで呼び出すことができます。
次の図は、64 × 64 のカウンターを実装するグラフィカル関数を示しています。
次のコード例は、このグラフィカル関数から生成された VHDL コードを示しています。
x64_counter_sf : PROCESS (x, y, outx_reg, outy_reg) -- local variables VARIABLE x_temp : unsigned(7 DOWNTO 0); VARIABLE y_temp : unsigned(7 DOWNTO 0); BEGIN outx_reg_next <= outx_reg; outy_reg_next <= outy_reg; x_temp := x; y_temp := y; x_temp := tmw_to_unsigned(tmw_to_unsigned(tmw_to_unsigned(x_temp, 9), 10) + tmw_to_unsigned(to_unsigned(1, 9), 10), 8); IF x_temp < to_unsigned(64, 8) THEN NULL; ELSE x_temp := to_unsigned(0, 8); y_temp := tmw_to_unsigned(tmw_to_unsigned(tmw_to_unsigned(y_temp, 9), 10) + tmw_to_unsigned(to_unsigned(1, 9), 10), 8); IF y_temp < to_unsigned(64, 8) THEN NULL; ELSE y_temp := to_unsigned(0, 8); END IF; END IF; outx_reg_next <= x_temp; outy_reg_next <= y_temp; x_next <= x_temp; y_next <= y_temp; END PROCESS x64_counter_sf;
階層とパラレル化
Stateflow チャートは階層 (他のステートを含むステート) とパラレル化 (同時にアクティブにできる複数のステート) の両方をサポートしています。
Stateflow セマンティクスでは、パラレル化は同時実行と同義ではありません。パラレル ステートは同時にアクティブにできますが、これらは実行順序に従って順次実行されます (実行順序はパラレル ステートの右上隅に表示されます)。
階層とパラレル化の詳細は、Stateflow オブジェクトの概要 (Stateflow)およびパラレル ステートの実行順序 (Stateflow)を参照してください。
HDL コード生成の場合、チャート全体が単一の出力計算プロセスにマッピングされます。出力計算プロセス内で、次のように処理されます。
パラレル ステートの実行が順次進行します。
入れ子にされた階層ステートは、生成された HDL コード内の入れ子にされた
CASE
ステートメントにマッピングされます。
ステートのないチャート
流れ図のみから成るチャート (つまり、ステートのないチャート) は、C などの手続き型言語で使用される if-then-else
コンストラクターをキャプチャするうえで役立ちます。
例として、C に似た疑似コードで表された次のロジックについて考えます。
if(U1==1) { if(U2==1) { Y = 1; }else{ Y = 2; } }else{ if(U2<2) { Y = 3; }else{ Y = 4; } }
次の図は、if-then-else
ロジックを実装する流れ図を示しています。
次の生成された VHDL コード例は、流れ図から取得した入れ子になった IF-ELSE ステートメントです。
Chart : PROCESS (Y1_reg, Y2_reg, U1, U2) -- local variables BEGIN Y1_reg_next <= Y1_reg; Y2_reg_next <= Y2_reg; IF unsigned(U1) = to_unsigned(1, 8) THEN IF unsigned(U2) = to_unsigned(1, 8) THEN Y1_reg_next <= to_unsigned(1, 8); ELSE Y1_reg_next <= to_unsigned(2, 8); END IF; ELSIF unsigned(U2) < to_unsigned(2, 8) THEN Y1_reg_next <= to_unsigned(3, 8); ELSE Y1_reg_next <= to_unsigned(4, 8); END IF; Y2_reg_next <= tmw_to_unsigned(tmw_to_unsigned(tmw_to_unsigned(unsigned(U1), 9),10) + tmw_to_unsigned(tmw_to_unsigned(unsigned(U2), 9), 10), 8); END PROCESS Chart;
真理値表
HDL Coder™ は、次の HDL コード生成をサポートしています。
Stateflow チャート内の真理値表関数
Simulink® モデル内の Truth Table (Stateflow) ブロック
この節では、チャート内の真理値表関数と、チャート用に生成された VHDL コードについて説明します。
真理値表は、コンパクトな組み合わせロジックの実装に適しています。真理値表は一般的に非線形量子化やしきい値ロジックの実装に使用されます。次のロジックを検討します。
Y = 1 when 0 <= U <= 10 Y = 2 when 10 < U <= 17 Y = 3 when 17 < U <= 45 Y = 4 when 45 < U <= 52 Y = 5 when 52 < U
ステートをもたず、関数 Truth Table への呼び出しを 1 つもつチャートを使用すると、このロジックを簡潔に表すことができます。
次の図は、Truth Table を含む quantizer
チャートを示しています。
次の図は、真理値表エディターに表示されたしきい値ロジックを示しています。
次のコード例は、quantizer
チャートから生成された VHDL コードを示しています。
quantizer : PROCESS (Y_reg, U) -- local variables VARIABLE aVarTruthTableCondition_1 : std_logic; VARIABLE aVarTruthTableCondition_2 : std_logic; VARIABLE aVarTruthTableCondition_3 : std_logic; VARIABLE aVarTruthTableCondition_4 : std_logic; BEGIN Y_reg_next <= Y_reg; -- Condition #1 aVarTruthTableCondition_1 := tmw_to_stdlogic(unsigned(U) <= to_unsigned(10, 8)); -- Condition #2 aVarTruthTableCondition_2 := tmw_to_stdlogic(unsigned(U) <= to_unsigned(17, 8)); -- Condition #3 aVarTruthTableCondition_3 := tmw_to_stdlogic(unsigned(U) <= to_unsigned(45, 8)); -- Condition #4 aVarTruthTableCondition_4 := tmw_to_stdlogic(unsigned(U) <= to_unsigned(52, 8)); IF tmw_to_boolean(aVarTruthTableCondition_1) THEN -- D1 -- Action 1 Y_reg_next <= to_unsigned(1, 8); ELSIF tmw_to_boolean(aVarTruthTableCondition_2) THEN -- D2 -- Action 2 Y_reg_next <= to_unsigned(2, 8); ELSIF tmw_to_boolean(aVarTruthTableCondition_3) THEN -- D3 -- Action 3 Y_reg_next <= to_unsigned(3, 8); ELSIF tmw_to_boolean(aVarTruthTableCondition_4) THEN -- D4 -- Action 4 Y_reg_next <= to_unsigned(4, 8); ELSE -- Default -- Action 5 Y_reg_next <= to_unsigned(5, 8); END IF; END PROCESS quantizer;
メモ
Simulink モデルの Truth Table (Stateflow) ブロックのコードを生成するときに、HDL Coder によって Truth Table コード用に個別のエンティティ/アーキテクチャ ファイルが書き込まれます。このファイルの名前は Truth_Table.vhd
(VHDL の場合) または Truth_Table.v
(Verilog® の場合) です。
参考
State Transition Table (Stateflow) | Truth Table (Stateflow) | Sequence Viewer (Stateflow)