15 / 37 · 概念
ノンブロッキング代入と同時状態更新
旧値と次の値を分け、パイプライン・カウンタ RTL を正確に解釈します。
レッスンは無料で読めます。受講登録すると進捗を保存できます。
右辺は以前の状態から評価します
クロックに基づく順序ブロックの <= は、右辺を評価した後、ノンブロッキングノンブロッキング代入 順序 RTL で <= と書く代入です。右辺を評価して更新を予約するので、同じエッジのレジスタが更新前の状態に基づいて計算できます。更新段階で結果を反映します。同じエッジで複数レジスタレジスタ 複数ビットの状態を記憶する回路です。このコースの同期式レジスタは、クロックエッジで定められた入力を記憶します。 詳しく見るを更新するとき、コードの行順だけで新しい値が連鎖して通らないように書けます。
always_ff @(posedge clk) begin
if (rst) begin
a <= 8'd0;
b <= 8'd0;
end else begin
a <= d;
b <= a;
end
end初期 a=b=0、入力が 5、9、2 なら、エッジ後の (a,b) は (5,0)、(9,5)、(2,9) です。二行目が更新後の a を読むと解釈すると、パイプラインパイプライン 計算をレジスタで区切った段に分け、複数入力を重ねて処理する構造です。データ・valid・制御信号の段をそろえる必要があります。 詳しく見るの一段を消したことになります。
下の各列は立上りエッジ立上りエッジ クロックが 0 から 1 に変わる瞬間です。CLK=1 の区間全体を指すレベルとは区別します。 詳しく見るの記録です。入力はエッジ直前、「更新後」の状態は更新直後です。並びはサンプル順で、物理的な伝搬遅延伝搬遅延 入力が変わってから、出力が正しい値に安定するまでの時間です。論理式の等価性と時間特性は別の性質です。 詳しく見るではありません。a=b=0 から、a が新しい d を記憶する間、b は以前の a を記憶するため、二行は一段ずれます。
波形データを表示
| 信号 | 波形 | バスの値 |
|---|---|---|
| エッジ | 234 | E0 → E1 → E2 |
| d | 234 | 5 → 9 → 2 |
| 更新後 a | 234 | 5 → 9 → 2 |
| 更新後 b | 234 | 0 → 5 → 9 |
blocking に変えると何が危険か
同じブロックを a=d; b=a; に変えると、b の計算がブロック内で既に変わった a を使えます。他の順序ブロックとのスケジュールにより、レースも起こり得ます。組合せ計算は blocking、状態記憶は nonblocking を原則とし、例外はイベントの意味を説明できる場合に限ります。
同じレジスタへ複数回代入しない
一つの手続き内で同じ q への複数の nonblocking 代入が実行されると、最後に実行された代入が結果を決める場合があります。独立した if で優先順位を隠すより、if / else if / else や明示的な next-state 変数で機能を表します。複数ブロックで同じレジスタを駆動することは避けてください。
RTL レビューでは、各レジスタに一つずつ次状態式を書くと有効です。式が二つ出たり、ある条件で定義されなかったりするなら、制御の優先順位を見直す合図です。
自分で考えてみましょう
初期 a=1、b=4 から、同じクロックブロックで a<=b; b<=a; を実行します。一つ後と二つ後のエッジの状態は何ですか。
解説を見る
一つ後は (a,b)=(4,1)、二つ後は (1,4) です。両代入が同じ以前の状態を読むので交換されます。a=b; b=a; と書くと、順番により両方が以前の b になる場合があり、同じ機能ではありません。