2

2 つのシングル ビット フリップフロップで「完了」したシングル ビット信号をバッファリングしたいと考えています。私のデザインでは、done 信号が 1 クロック サイクルだけ立ち上がります。そこで、以下のコードを書きました。

//first level buffer done signal for one cycle to get ciphertext_reg ready
always @(posedge clk or posedge rst) begin
    if(rst)
        done_buf_1 = 1'b0;
    else
        done_buf_1 = done;
end

//second level buffer
always @(posedge clk or posedge rst) begin
    if(rst)
        done_buf_2 = 1'b0;
    else
        done_buf_2 = done_buf_1;
end

機能シミュレーションで、done_buf_1 は done の 1 サイクル後に立ち上がりますが、done_buf_2 は done_buf_1 と同時に立ち上がります。

これについての説明は何ですか?

ありがとうございました!

4

3 に答える 3

3

解決策 (「ノンブロッキング割り当てを使用する」) に関する回答は既に得られていますが、これを行う必要がある理由を次に示します。

どちらのalwaysステートメントにも同じイベントがあるため、任意の順序で実行できます。起こっているように見えるのは、最初のものが最初に実行されているということです。ラインが...

done_buf_1 = done;

...ヒットすると、割り当てが完了するまでブロックされます(「ブロック」割り当てです)。したがって、done_buf_1 はすぐに新しい値を取ります。これは、非ブロッキング バージョンとは異なります...

done_buf_1 <= done;

...これは、「タイムスライスの最後にdone_buf_1にdoneの値を与える(これは今評価します)」と言っています。

次に進み、done_buf_2 が割り当てられます。

done_buf_2 = done_buf_1;

ここで、done_buf_1がブロッキング割り当てで更新された場合、既に の現在の値がありdone、両方の信号が同時に上昇することがわかります。ノンブロッキング代入の場合は、タイム スライスが終了するまで更新されないため、done_buf_1の前の値が保持され、結果として の 2 サイクルの遅延が発生します。donedone_buf_2

しかし、別の問題もあります。イベントは同じなので、always ステートメントはどちらの順序でも実行できると言ったことを覚えていますか? 2 番目のコードが最初に実行された場合、コードは意図したとおりに動作するように見えます (db2 = db1; db1 = done;問題ありません)。したがって、このようなブロッキング割り当てを使用すると、特にツール間で不安定な結果が生じることを知っておく価値があります。これは、いくつかの微妙なバグにつながる可能性があります。

于 2012-06-18T08:20:09.193 に答える
2

ブロッキング割り当て=を使用して同期ロジックをモデル化しています。ノンブロッキング割り当てを使用する必要があります<=

于 2012-06-16T17:53:14.087 に答える
1

=他の人が言ったように:これにはブロッキング割り当て( )を使用しないでください。

要点は、「これ」が異なるプロセス間で通信する仕事であるということです。ブロック代入に固有の競合状態により、これは予測不能になります。VHDL はこれを非常に真剣に受け止めているため、これらのタイプの割り当てを分離して、間違ったものを使用できないようにしています (共有変数から遠ざける限り)。

Jan Decaluwe からの主題に関するいくつかの興味深い文章:

于 2012-06-18T11:03:09.317 に答える