2

Altera の次のように実装された多くのステート マシンを見てきました。

ARCHITECTURE a OF state_machine IS
   TYPE STATE_TYPE IS (s0, s1, s2);
   SIGNAL state   : STATE_TYPE;
BEGIN
   PROCESS (clk, reset)
   BEGIN
      IF reset = '1' THEN
         state <= s0;
      ELSIF (clk'EVENT AND clk = '1') THEN
      CASE state IS
     WHEN ...

それに代わるものは次のとおりです。

ARCHITECTURE a OF state_machine IS
   TYPE STATE_TYPE IS (s0, s1, s2);
BEGIN
   PROCESS (clk, reset)
      VARIABLE state : STATE_TYPE := s0;
   BEGIN
      IF reset = '1' THEN
         state <= s0;
      ELSIF (clk'EVENT AND clk = '1') THEN
      CASE state IS
     WHEN ...

別の方法でそれを行うことの長所(ある場合)と短所は何ですか?私は代替案を 1 か所でしか見たことがありませんが、それには何らかの正当な理由があるに違いないと推測しています。

4

4 に答える 4

2

私はローカルなものをローカルに保つのが好きなので、状態情報がプロセス内でのみ必要な場合は、変数を使用します。その場合、プロセス内で状態タイプを宣言することも好きです。

ARCHITECTURE a OF state_machine IS
BEGIN
   PROCESS (clk, reset)
      TYPE STATE_TYPE IS (s0, s1, s2);
      VARIABLE state : STATE_TYPE := s0;
   BEGIN
      ...

別のプロセス (インタラクティブなステート マシンなど) から FSM の状態にアクセスする必要があるまれなケースでは、状態を格納するためにシグナルを使用します。

多くの場合、好みの問題である場合、信号対変数の決定。一部の開発者は、変数は悪であり、決して使用しないと考えています。他の人 (私のような) は、ローカルのものをローカルに保つためにできる限りそれらを使用します。おまけとして、変数は信号よりも軽量なオブジェクトであるため、シミュレートも高速になります。

于 2013-09-17T06:54:20.833 に答える
1

私はしばしばvariable呼ばれるを使用しstateます。定義を非表示にし、それを使用しているプロセスだけに限定します。1 つのプロセスに 2 つの通信ステート マシンがある場合、それらは両方ともstateローカルと呼ばれる変数を持つことができます。時々それはうまくいきます。それ以外の場合は混乱します!

多くのコード スタイルの問題と同様に、最も読みやすい方法を決定する必要があります。変数を使用しない機能的な理由はありません (状態変数だけでなく、あらゆる種類の変数)。

変数を使用してできるもう 1 つのことは、プロセスの最後に意図した次の状態を読み取ることです。これは、出力のレイテンシを短縮する必要がある場合に役立ちます。繰り返しになりますが、長いロジック チェーンを誤って作成してしまい、デザインの速度が低下する可能性があるため、注意が必要です。

于 2013-09-16T12:29:22.060 に答える
-1

変数は、同じクロック サイクル内のプロセスで使用される部分和または中間生成物を決定する場合に最適です。ただし、変数がクロック サイクルごとに駆動されない場合は、ラッチが推論されます。次のクロック サイクルで状態を「記憶」する必要があるため、アシスタント レジスタ信号なしで変数を使用すると、ラッチが発生します。明確にするために...

  signal state_sig : state_type;
begin

process(clk, rst)
  variable state : state_type := s0;
begin
  if rst = '1' then
    state_sig <= s0;
  elsif rising_edge(clk) then
    state := state_sig
    case state is 
     when s0 =>
      if blah = '0' then
       state := s1;
      end if;
     ....
     ....
    end case;
  if state = s1 then state := s2; end if;
  state_sig <= state;
 end if;
end process;

上記の例では、状態変数が登録される前に変更することで、状態 s1 に移行することを回避できます。ステート マシンの動作を変更する手っ取り早い汚い方法。ただし、state_sig 信号を使用して状態を「記憶」し、ラッチの推論を回避する必要があります。

于 2014-07-31T12:57:55.087 に答える