工業製造
産業用モノのインターネット | 工業材料 | 機器のメンテナンスと修理 | 産業プログラミング |
home  MfgRobots >> 工業製造 >  >> Industrial programming >> VHDL

VHDLで有限ステートマシンを設計:信号機の実践例

有限ステートマシン(FSM)は、現在の入力だけでなく、過去の入力と出力のシーケンスにも出力が依存する決定論的ロジックモデルです。FPGA設計や時間依存VHDLアルゴリズムでは、FSMが状態を持つ振る舞いを捉えるための標準的な抽象化です。

VHDLのFSMは通常、state信号を用いて前回の構成を記憶するクロックドプロセスとして実装されます。state信号は内部レジスタとして機能し、設計が複数クロックサイクルにわたるイベントに反応できるようにします。

Basic VHDL Tutorials – Part 3

信号機としてのFSM

4方向交差点を信号機で制御する場合を考えます。信号機は有限の可視状態(例:南北赤、南北青、東西赤など)を巡回します。各状態の持続時間(赤/黄5秒、青60秒)は経過クロックサイクルで駆動されます。

VHDLで有限ステートマシンを設計:信号機の実践例

これらの振る舞いを、すべての可能な状態を列挙した型でモデル化します:

type t_State is (NorthNext, StartNorth, North, StopNorth, WestNext, StartWest, West, StopWest);

その型の信号を宣言して現在状態を保持:

signal State : t_State;

state信号を配置したら、FSMロジックは単一のクロックドプロセス内でcase文を用いて記述します。各when分岐は異なる状態に対応し、その状態での出力代入を含みます。カウンタが経過時間を追跡し、所定閾値に達したら次の状態へ遷移します。

ワンプロセスFSMテンプレート

process(Clk) is
begin
  if rising_edge(Clk) then
    if nRst = '0' then
      State <= ;
      Counter <= 0;
    else
      case State is
        when  =>
          
          if  then
            State <= ;
          end if;
        ...
      end case;
    end if;
  end if;
end process;

注意: FSMはワンプロセス、ツープロセス、スリープロセススタイルで実装可能。詳細はFSM Styles Explainedを参照。

実践演習

以下は、信号機コントローラを実装した完全で合成可能な例です。シミュレーションを簡単にするため100Hzクロックを使用しつつ、現実的なタイミングをデモします。

テストベンチ

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity T20_FiniteStateMachineTb is
end entity;
architecture sim of T20_FiniteStateMachineTb is
  constant ClockFrequencyHz : integer := 100; -- 100 Hz
  constant ClockPeriod : time := 1000 ms / ClockFrequencyHz;
  signal Clk : std_logic := '1';
  signal nRst : std_logic := '0';
  signal NorthRed : std_logic;
  signal NorthYellow : std_logic;
  signal NorthGreen : std_logic;
  signal WestRed : std_logic;
  signal WestYellow : std_logic;
  signal WestGreen : std_logic;
begin
  i_TrafficLights : entity work.T20_TrafficLights(rtl)
    generic map(ClockFrequencyHz => ClockFrequencyHz)
    port map(
      Clk => Clk,
      nRst => nRst,
      NorthRed => NorthRed,
      NorthYellow => NorthYellow,
      NorthGreen => NorthGreen,
      WestRed => WestRed,
      WestYellow => WestYellow,
      WestGreen => WestGreen
    );
  Clk <= not Clk after ClockPeriod / 2;
  process is
  begin
    wait until rising_edge(Clk);
    wait until rising_edge(Clk);
    nRst <= '1';
    wait;
  end process;
end architecture;

ステートマシンモジュール

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity T20_TrafficLights is
  generic(ClockFrequencyHz : integer);
  port(
    Clk : in std_logic;
    nRst : in std_logic; -- アクティブロー リセット
    NorthRed : out std_logic;
    NorthYellow : out std_logic;
    NorthGreen : out std_logic;
    WestRed : out std_logic;
    WestYellow : out std_logic;
    WestGreen : out std_logic
  );
end entity;
architecture rtl of T20_TrafficLights is
  type t_State is (NorthNext, StartNorth, North, StopNorth, WestNext, StartWest, West, StopWest);
  signal State : t_State;
  signal Counter : integer range 0 to ClockFrequencyHz * 60;
begin
  process(Clk) is
  begin
    if rising_edge(Clk) then
      if nRst = '0' then
        State <= NorthNext;
        Counter <= 0;
        NorthRed <= '1'; NorthYellow <= '0'; NorthGreen <= '0';
        WestRed <= '1'; WestYellow <= '0'; WestGreen <= '0';
      else
        -- デフォルト出力
        NorthRed <= '0'; NorthYellow <= '0'; NorthGreen <= '0';
        WestRed <= '0'; WestYellow <= '0'; WestGreen <= '0';
        Counter <= Counter + 1;
        case State is
          when NorthNext =>
            NorthRed <= '1'; WestRed <= '1';
            if Counter = ClockFrequencyHz * 5 - 1 then
              Counter <= 0; State <= StartNorth;
            end if;
          when StartNorth =>
            NorthRed <= '1'; NorthYellow <= '1'; WestRed <= '1';
            if Counter = ClockFrequencyHz * 5 - 1 then
              Counter <= 0; State <= North;
            end if;
          when North =>
            NorthGreen <= '1'; WestRed <= '1';
            if Counter = ClockFrequencyHz * 60 - 1 then
              Counter <= 0; State <= StopNorth;
            end if;
          when StopNorth =>
            NorthYellow <= '1'; WestRed <= '1';
            if Counter = ClockFrequencyHz * 5 - 1 then
              Counter <= 0; State <= WestNext;
            end if;
          when WestNext =>
            NorthRed <= '1'; WestRed <= '1';
            if Counter = ClockFrequencyHz * 5 - 1 then
              Counter <= 0; State <= StartWest;
            end if;
          when StartWest =>
            NorthRed <= '1'; WestRed <= '1'; WestYellow <= '1';
            if Counter = ClockFrequencyHz * 5 - 1 then
              Counter <= 0; State <= West;
            end if;
          when West =>
            NorthRed <= '1'; WestGreen <= '1';
            if Counter = ClockFrequencyHz * 60 - 1 then
              Counter <= 0; State <= StopWest;
            end if;
          when StopWest =>
            NorthRed <= '1'; WestYellow <= '1';
            if Counter = ClockFrequencyHz * 5 - 1 then
              Counter <= 0; State <= NorthNext;
            end if;
        end case;
      end if;
    end if;
  end process;
end architecture;

5分間シミュレーション実行すると、FSMが8状態を巡回し、青フェーズがそれぞれ1分間持続する波形が得られます。

VHDLで有限ステートマシンを設計:信号機の実践例

分析

コードからの主要ポイント:

結果の波形は、FSMが正しく進行することを確認:State信号が8つの定義状態を切り替え、各青フェーズが1分間持続。

まとめ

次のチュートリアルで高度なFSMテクニックを学習します。

VHDL

  1. 有限状態マシン:フィードバックを活用したプログラマブルシーケンスコントローラの構築
  2. OMNI CNCレーザー機で作るパーソナライズドクリスマスギフト
  3. Qtステートマシンのパフォーマンスを最大化:実装手法別ベンチマーク
  4. VHDLで文字列リストを作成する: ベスト・プラクティスと実装例
  5. Tcl駆動テストベンチでVHDLコード・ロック・モジュールを検証する
  6. VHDLテストベンチ・シミュレーションを優雅に終了させる方法
  7. VHDLでPWMコントローラを実装: 設計、シミュレーション、FPGAデモ
  8. VHDLで乱数生成: 一様分布からOSVVMまで
  9. ブロックRAMにおける堅牢なVHDLリングバッファFIFOの設計
  10. VHDLで自己検証テストベンチを構築する実践ガイド
  11. VHDLで保護型とアクセスポインタを用いた動的リンクリスト実装