ノンブロッキング代入
CoddyのVerilogジャーニー「基礎」セクションの一部 — レッスン 50/90。
前回のレッスンでは、ステップごとに実行されるブロッキング代入 (=) について学習しました。今回は、すべて一度に(並列に)実行されるノンブロッキング代入 (<=) について学習します。
非ブロッキング代入は <= 演算子を使用します。次の文の実行をブロックしないため、「非ブロッキング」と呼ばれます。ブロック内のすべての非ブロッキング代入は、同時に実行されます。
構文:
variable <= expression;ノンブロッキング代入を使用するタイミング
ノンブロッキング代入 (<=) は、順序回路(クロックを使用し、メモリを持つ回路)に使用されます。出力はクロックエッジ(通常は立ち上がりエッジ)でのみ変化します。
順序回路の例:
- フリップフロップ
- レジスタ
- カウンタ
- ステートマシン
- シフトレジスタ
Verilogの例:
initial begin
a <= 5; // スケジュールされましたが、まだ実行されていません
b <= a + 2; // スケジュールされました。aの古い値を使用します
c <= b * 3; // スケジュールされました。bの古い値を使用します
end3つの代入すべてが、古い値を使用して同時に実行されます。タイムステップの終わりに、すべての更新がまとめて行われます。
alwaysブロックにおけるノンブロッキング代入(順序回路)
ノンブロッキング代入は、順序回路 — クロックを使用し、メモリ(フリップフロップ、レジスタ、カウンタ)を持つ回路に使用されます。
always @(posedge clk) begin
q <= d; // クロックエッジでqにdが代入される
count <= count + 1; // クロックエッジでcountがインクリメントされる
end両方の代入は、クロックエッジ前の値を使用して同時に行われます。
まとめ
| ルール | 説明 |
|---|---|
順序回路には <= を使用する | always @(posedge clk) |
組合せ回路には = を使用する | always @(*) |
| ノンブロッキング代入は並列に実行される | すべての代入が同時に行われる |
| 値はタイムステップの最後に更新される | 即座には更新されない |
チャレンジ
非ブロッキング代入を完成させる
この2ビット・シフトレジスタを動作させるために、不足している非ブロッキング代入を追加してください。
仕組み:
- 各クロック・エッジで、
q1はdを取得します q2はq1の古い値を取得します
行うこと:
dをq1に代入する(非ブロッキング)q1をq2に代入する(非ブロッキング)
チートシート
ノンブロッキング代入 (<=) は、すべてのステートメントを並列に実行します。古い値を使用し、タイムステップの最後に更新されます。
// すべて a と b の古い値を使用します
a <= 5;
b <= a + 2; // 古い a を使用
c <= b * 3; // 古い b を使用クロック同期の always ブロック内での順序回路(フリップフロップ、レジスタ、カウンタ)には <= を使用します:
always @(posedge clk) begin
q <= d; // ノンブロッキング
count <= count + 1; // ノンブロッキング
end| 代入 | 用途 | 実行方式 |
|---|---|---|
<= | 順序回路 (posedge clk) | 並列 |
= | 組合せ回路 (always @(*)) | 逐次(ステップバイステップ) |
自分で試してみよう
module shift_register (
input clk,
input reset,
input d,
output reg q1,
output reg q2
);
always @(posedge clk or posedge reset) begin
if (reset) begin
q1 <= 0;
q2 <= 0;
end else begin
// TODO: シフトロジックを追加
// ステップ 1: d を q1 に代入 (非ブロッキング)
// ステップ 2: q1 を q2 に代入 (非ブロッキング)
end
end
endmoduleこのレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。