ステートマシン (state machine)

動きを表すために、入力条件に従って、状況を切り替えていくロジックをステートマシンと言います。
一般的には、入力条件に従う切り替え回路は if や case 文で、状況を記憶させるにはFFを使います。
VHDLではこの切り替え回路と、記憶させるにはFFを分けて、2つのprocess文にすることで見やすい設計となります。


4つの状況がある簡単なステートマシンの例を次に示します。

library IEEE;
use IEEE.std_logic_1164.all;

entity State is

 port (
   Clk   :in std_logic; --FF clock
   Rst_n  :in std_logic; --asynchronous reset
   StrtSt :in std_logic;
   MoveSt :in std_logic;
   EndSt  :in std_logic;

   StatOut :out std_logic_vector (2 downto 0));

end State;

architecture RTL of State is

 constant c_idle  : std_logic_vector (2 downto 0) := "000"; --各ステータスは定数設定する
 constant c_wait  : std_logic_vector (2 downto 0) := "001";
 constant c_move  : std_logic_vector (2 downto 0) := "010";
 constant c_end   : std_logic_vector (2 downto 0) := "100";

 signal  timSts  : std_logic_vector (2 downto 0);
 signal  nxtSts  : std_logic_vector (2 downto 0);

begin

 StatOut <= timSts;

 process (Clk, Rst_n) begin           --状況記憶用のFF
  if (Rst_n = '0') then
   timSts <= c_idle;
  elsif (Clk'event and Clk = '1') then
   timSts <= nxtSts;
  end if;
 end process;

 process (timSts, StrtSt, MoveSt, EndSt) begin --状況切替回路
  case timSts is
   when c_idle => if (StrtSt = '1') then   --状況切替条件が合ったら
            nxtSts <= c_wait;    --切り替える
           else            --合わなかったら
            nxtSts <= c_idle;    --切り替えない
           end if;

   when c_wait => if (MoveSt = '1') then
            nxtSts <= c_move;
           else
            nxtSts <= c_wait;
           end if;

   when c_move => if (EndSt = '1') then
            nxtSts <= c_end;
           else
            nxtSts <= c_move;
           end if;

   when c_end  => if (StrtSt = '1') then
            nxtSts <= c_wait;
           elsif (MoveSt = '1') then
            nxtSts <= c_move;
           else
            nxtSts <= c_end;
           end if;

   when others => nxtSts <= c_idle;

  end case;
 end process;

end RTL;


VHDL目次          MAIL  HOME