4

VHDL で見られる多くの FSMnext_stateは、FSM ロジックで変数 " " を設定し、これをプロセス外の状態変数に個別に割り当てることによって機能します。

state <= state_five単純に「 ;」と書いて何か問題があれば 代わりに次の状態を設定しますか? 私がいつも見ているように、多くの人が状態に直接割り当てるのではなく、別の次の状態変数を使用する理由があると推測していますが、私が知る限り、それがコードを作成することを除いて違いはありませんより長く、より複雑に見えます。

私は何かを逃しましたか?それとも単にスタイルの問題ですか?もしそうなら、なぜそのスタイルが良いのか、それは私には不必要に思えます.

4

3 に答える 3

6

「ただ書いて何か問題あるのstate <= state_five;?」

何もありません-状態の割り当てがクロックプロセスで行われる場合。

これは、あまりにも多くの教科書やオンライン チュートリアルで教えられている信頼性の低い (センシティビティ リストを間違えやすいため) 2 プロセス スタイルではなく、すっきりとしたシンプルで信頼性の高い「単一プロセス ステート マシン」スタイルにつながります。

「single process state machine」を検索すると、良い例題と詳細な議論を見つけることができるはずです。

歴史的なメモ : 前世紀には、単一プロセス スタイルに問題のある合成ツールがいくつかあった可能性があります。しかし、それは今それを避ける理由にはなりません。

于 2013-01-10T11:16:58.337 に答える
3

一部の人々が常に 2 プロセスのステート マシン (つまり、1 つの同期プロセスと 1 つの並行プロセス) を記述する理由は、他の人が言っているように、学校でそのようにすることを学んだためです。

ただし、場合によっては、このコーディング スタイルが実際には、単一の同期プロセスを使用するよりも優れていることがあります。つまり、同じコンテキストで同期割り当てと同時割り当てを混在させることができます。次の 2 つのコードを考えてみましょう。どちらも同じことを実行します。

2 プロセス ステート マシン:

process (clk)
begin
  if rising_edge(clk) then
    state <= state_next;
  end if;
end process;  

process (all)
begin 
  state_next <= state;
  case state is 
    when s_idle => 
      if req_i = '1' then 
        fifo_read <= '1'; -- Concurrent assignment
        state_next <= s_check_data; -- "Synchronous" assignment 
      end if; 
    when s_check_data =>
      if fifo_out = x"1234" then
        (...)
      end if;
    (...) 
  end case; 
end process;

1 プロセスのステート マシン:

process (clk)
begin 
  if rising_edge(clk) then
    case state is 
      when s_idle => 
        if req_i = '1' then 
          fifo_read <= '1';
          state <= s_wait_for_data;
        end if;
      when s_wait_for_data =>
        state <= s_check_data;
      when s_check_data =>
        -- Data word from FIFO now available.
        if fifo_out = x"1234" then
          (...)
        end if;
      (...) 
    end case;
  end if;
end process;

2 番目の例の余分な状態に注意してください。VHDL では同期プロセスで同時割り当てを行う方法がないため (あったらいいのに!)、 fifo_read 信号にレジスタが追加され、1 サイクル遅延します。この例は非常に単純ですが、常に 1 つのプロセスのステート マシンに固執すると、コードが非常に混乱し、理解が困難になることがあります。また、ステート マシンがハードウェアでより多くのリソースを消費し、コードが長くなる可能性もあります。どちらのスタイルも常に正しい選択ではありませんが、私は通常、1 プロセスのバリアントを好みます。

于 2013-01-16T16:50:42.573 に答える
2

または、変数を使用することもできます:

state := state_five

変数を使用して状態を保存するということは、変数がプロセスに対して完全にローカルのままであり、全体の名前空間を汚染しないことを意味しますarchitecture

reportまた、デバッグ時にステート マシンの進行状況を追跡するためにprintf (申し訳ありません) を使用する習慣がある場合 (これは、波形ビューアーよりも望ましい場合があります)、ステート マシンの最後で目的の次の状態を報告できることも意味します。便利なプロセス。

追加: コメントに記載されているように、変数の割り当ては「即座に」発生します (明確にするために、これによりcaseステートメントがすぐに次の状態に切り替わるわけではありません!)

この効果は、プロセスの最後の次の状態に基づいて上記の信号に割り当てることにより、サイクルの早い段階で出力が必要な場合に (時折) 有利に使用できます。それを行う必要が生じた場合、ステートメントと(クロックされたプロセスの最後にある)next_state以外のすべてに使用する明示的な変数を持つ傾向があります。このようにするつもりだったことをコード レビュアーに示します。casestate := next_state;

于 2013-01-10T14:47:10.893 に答える