のプロセスを 2 つ以上連続して実行することはできVHDL
ますか?
プロセスの順次実行が完了していない間に別のイベント (感度シグナル リストで) が発生した場合はどうなりますか?
それは可能ですか、それとも私VHDL
のプロセスのモデルが完全に間違っていますか?
のプロセスを 2 つ以上連続して実行することはできVHDL
ますか?
プロセスの順次実行が完了していない間に別のイベント (感度シグナル リストで) が発生した場合はどうなりますか?
それは可能ですか、それとも私VHDL
のプロセスのモデルが完全に間違っていますか?
プロセスの実行中にイベントが発生することはありません。
プロセスがイベントによって起動されると、完了 (「プロセスの終了」) または明示的な「待機」ステートメントまで実行され、スリープ状態になります。これには、概念的にゼロの時間がかかります。つまり、プロセスにループがある場合、それらは効果的に完全にアンロールされ、合成すると、すべての反復を並行して実行するのに十分なハードウェアが生成されます。また、プロシージャ、関数などは、明示的な「待機」ステートメントが含まれていない限り、時間がかかりません (その場合、プロシージャがインライン化されているかのように、プロセスは「待機」で中断されます)。
このプロセス全体を通して、すべてのシグナルは、プロセスが起動したときに最初に持っていた値を持ち、シグナルの割り当ては後で発生するように保存されます。(変数はすぐに更新されます。プロセス内の後のステートメントで新しい値が表示されます)。
プロセスが(「待機」または「プロセスの終了」で)一時停止すると、他のすべてのプロセスも一時停止するまで何も起こりません。(しかし、それらはすべてゼロ時間かかることを忘れないでください!)。プロセスが「プロセスの終了」で一時停止した場合、そのセンシティビティ リストによってウェイクアップされると、プロセスは最初から再開されます。明示的な「待機」で一時停止する場合、その「待機」はイベントまたは将来の時間を指定し、「待機」後に再開します。(注: 1 : センシティビティ リストと待機スタイルを同じプロセスに混在させないでください! 2: 何らかのイベントが合成可能になるまで待機します (ツールによっては反対する場合があります) ; しばらく待機するのはシミュレーションのみです)
次に、すべての信号割り当てが実行されます。すべてのプロセスがスリープ状態になるため、競合状態とタイミングの危険がすべて解消されます。これらの割り当ての一部 (クロックへの '1' など) により、イベントはそれらに敏感なプロセスでスケジュールされます。
すべての信号の割り当てが完了すると、時間は 1 つの無限に短いティック (デルタ サイクルと呼ばれます) 進み、スケジュールされたイベントを持つすべてのプロセスが起動されます。
これは、新しいイベントがスケジュールされていないデルタ サイクルが発生するまで続き、最終的にシミュレーションはリアルタイム ステップで進むことができます。
したがって
process(clk)
begin
if rising_edge(clk) then
A <= B;
B <= A;
end if;
end process;
VHDL ではハザードフリーです。
Verilog を使用する必要がある場合は、その一部が異なる方法で発生することに注意してください。また、シミュレーション結果で同じレベルの予測可能性に依存することはできません。
もちろん、合成では、このプロセスを実行するのに実際に時間がかかるハードウェアを生成します。ただし、合成およびバックエンド ツール (配置配線) は、このモデルに忠実に従うか、失敗して失敗した理由を報告するかのいずれかを保証します。たとえば、実際の遅延をすべて合計し、その合計が指定したクロック周期よりも短いことを確認します。(クロック速度の設定が高すぎる場合を除きます!)。
つまり、ツールが成功を報告している限り (そしてクロック速度などのタイミング制約を正しく設定している限り)、上記の「ゼロ時間」モデルが真であると見なすことができ、実際のハードウェアの動作はシミュレーションと一致します。ツールのバグを除いて、保証されています!
VHDL (またはその他の HDL) の使用を開始するときは、シーケンシャル コードの概念をすべて破棄し、代わりにハードウェアを介したデータ フローに注目することが非常に重要です。ハードウェアでは、すべてが本質的に並列です (すべてが同時に発生します) が、常に変化するデータ (入力信号) を使用して、常に変化する結果 (出力信号) を計算します!
変数、待機コマンドなどのより高度なトピックに立ち入ることなく、プロセス内のすべてが同時に発生します。同じプロセス内で競合が発生した場合 (同じシグナルへの複数の書き込み)、プロセスの最後のステートメントが優先されます。これは、VHDL の「シーケンシャル」コードに関する混乱の原因となることがよくあります。
これは、値がシグナルに割り当てられる方法により機能します。シグナルに値を割り当てても、シグナルの値はすぐには変化しません! 代わりに、割り当てられた値が記憶され、後で実際のシグナル値としてコミットされます (次のデルタ サイクル (実質的に次の時間量) に備えて)。
次のデルタ サイクルは、前のデルタ サイクルからのすべてのプロセスが完了するまで開始されないため、シグナル値はプロセスが実行されていない場合にのみ変化します。すべてのシグナルが変更されると、次のデルタ サイクルが開始され、変更されたシグナルの 1 つに敏感なプロセスが実行されます。
プロセスが書き込み信号に敏感な場合、出力が入力に供給されるゲートなど、組み合わせループとして知られているものがあります。これは (ほとんど) 常に回路内のエラーであり、通常、シミュレータは無限のデルタ サイクル ループに入ります。
これを書いているときにブライアン・ドラモンドの答えが現れたので、今のところ書くのはこれだけですが、お気軽にコメントを残してください。詳細を追加します。
プロセスが(イベントのために)実行を開始すると、他のイベントが他のイベントをトリガーできるようになる前に、プロセスは完了まで実行されます。