2012-12-19 8 views
10

VHDLのプロセスで2つ以上の連続実行が可能ですか?VHDLのプロセスは再入可能ですか?

プロセスの順次実行が完了していない間に別のイベント(感度信号リスト上)が発生した場合はどうなりますか?

処理のために私のVHDLモデルが念頭に置いてありますか?

+0

あなたの質問を明確にしたいかもしれません – briantyler

+0

状況のコード例を明確にすることはできますか?私はあなたが求めているものを知っていると信じていますが、具体的な問題がなければ答えるのは難しいです。 –

答えて

39

プロセスの実行中にイベントが発生することはありません!

イベントによってプロセスが呼び起こされると、プロセスは完了(「プロセス終了」)または明示的な「待機」ステートメントに移行し、スリープ状態になります。これは概念上、ゼロ時間を要する。つまり、プロセス内にループがあると、それらは完全に展開され、合成すると、すべての繰り返しを並行して実行するのに十分なハードウェアが生成されます。また、明示的な "wait"文が含まれていない限り、プロシージャや関数などの処理には時間がかかりません(この場合、プロシージャがインライン化されているかのように "wait"で停止します)。

このプロセス全体を通して、すべてのシグナルは、プロセスが起動したときに元々持っていた値を持ち、後で起こるシグナル割り当てが保存されます。 (変数はすぐに更新され、プロセスの後のステートメントは新しい値を参照します)。

プロセスが中断すると(「待機」または「終了プロセス」)、他のすべてのプロセスも中断するまで何も起こりません。 (しかし、彼らはすべて時間がゼロになることを忘れないでください!)。プロセスが「終了プロセス」で中断した場合、プロセスは、その感度リストが起動すると、最初から再開します。明示的な「待機」で中断した場合、その「待機」はイベントまたは将来の時間を指定し、「待機」の後に再起動します。 (注:1:同じプロセスで感度リストとウェイトスタイルを混在させないでください!)2:いくつかのイベントが合成可能になるまで待ってください(一部のツールは対処できるかもしれませんが)。

THENすべて信号の割り当てが行われる。すべてのプロセスが眠っているので、これは競合状態とタイミングの危険をすべて排除します。これらの割り当ての中には(クロックに '1'など)、それらに敏感なプロセスでイベントがスケジュールされることがあります。

すべてのシグナル割り当てが完了した後、タイムステップは無限に短いティック(デルタサイクルと呼ばれます)を転送し、スケジュールされたイベントを持つすべてのプロセスがウェイクします。

これは、新しいイベントがスケジュールされていないデルタサイクルが発生するまで続き、最後にシミュレーションはリアルタイムステップで進めることができます。

したがって

process(clk) 
begin 
if rising_edge(clk) then 
    A <= B; 
    B <= A; 
end if; 
end process; 

はVHDLで危険フリーです。

Verilogを使用する必要がある場合は、その一部が別の方法で発生することに注意してください。シミュレーション結果に同じレベルの予測可能性を使用することはできません。


もちろん、合成では、このプロセスを実行するためにリアルタイムでハードウェアを生成します。しかし、合成とバックエンドのツール(場所と経路)は、このモデルに忠実に従うか、失敗して失敗した理由を報告することを保証します。たとえば、すべての実際の遅延を加算し、合計が指定されたクロック周期よりも短いことを確認します。 (クロック速度を高く設定しないと!)。

ツールが成功を報告している限り(クロック速度のようなタイミング制約を正しく設定している限り)、上記の「ゼロ時間」モデルは真実であり、実際のハードウェアの動作はシミュレーション。保証、ツールのバグを禁止!

+4

なぜこの答えは、すべてのVHDLチュートリアルにはありませんか?私は今VHDLで何かをやってきたし、あなたはまだ私のためにいくつかの基礎を明らかにした! –

+0

賛辞をいただきありがとうございます! –

+0

"たとえば、すべての実際の遅延を合計し、合計が指定されたクロック周期よりも短いことを確認します(クロック速度を高く設定しない限り)。わかりません。したがって、クロック速度を高く設定しすぎると、クロック周期よりも長い合計が許可され、検証されません。 –

5

VHDL(またはその他のHDL)を使用して起動する場合は、シーケンシャルコードのすべての概念を破棄し、ハードウェアを通じたデータフローに焦点を当てることが非常に重要です。ハードウェアでは、すべてが本質的にパラレル(すべてが同時に起こります)ですが、常に変化するデータ(入力信号)を使用して常に変化する結果(出力信号)を計算します。

変数やwaitコマンドなどのより高度なトピックに入ることなく、プロセス内のすべてが同時に発生します。矛盾するものが同じプロセス内で発生した場合(同じ信号への複数の書き込み)、プロセスの最後のステートメントが優先されます。これは、VHDLの「シーケンシャル」コードが混乱する場所です。

これは値が信号に割り当てられる方法のために機能します。信号に値を割り当てるとき、信号の値はただちに変更されません!代わりに、割り当てられた値が記憶され、実際の信号値として​​後でコミットされます(次のデルタサイクルに備えて、事実上次の量子時間です)。

前のデルタサイクルからのすべてのプロセスが完了するまで次のデルタサイクルが開始されないため、シグナル値はプロセスが実行されていない場合にのみ変更されます。すべての信号が変更されると、次のデルタサイクルが開始され、変更された信号の1つに敏感なプロセスが実行されます。

プロセスが信号にも影響を受けやすい場合は、コンビネーションループと呼ばれるものがあります。例えば、出力が入力を供給するゲートです。これは(ほとんど)常にあなたの回路のエラーであり、通常、シミュレータは無限のデルタサイクルループに入ります。

ブライアン・ドラモンドの答えは私がこれを書いていたときにちょうどポップアップしたので、コメントを残しておきましょう。私はいくつかの詳細を追加します。

2

プロセスは、(原因イベント)を実行するために開始すると、他のイベントが何かをトリガするために許可される前に、それが完了するまで実行されます。

+0

これは 'entity'全体の中か、' process'の中のelse_ですか? – atomh33ls

+1

ちょうどプロセス。プロセスが終了すると、同じデルタサイクルを実行する準備ができているプロセスが次にスケジュールされることを知る方法がありません。それは同じエンティティからのものであってもよいし、そうでなくてもよい。そして(共有変数を使用していない限り)重要ではありません –

関連する問題