ノンブロッキング代入
CoddyのVerilogジャーニー「基礎」セクションの一部 — レッスン 50/90。
前回のレッスンでは、ステップバイステップで実行されるブロッキング代入(=)について解説しました。今回は、すべてが一度に並列実行されるノンブロッキング代入(<=)について解説します。
ノンブロッキング代入(Non-blocking assignment)は <= 演算子を試用(uses)します。次の文の実行をブロック(遮断)しない(not block)ため、「ノンブロッキング」と呼ばれます。ブロック内のすべてのノンブロッキング代入は同時に(at the same time)実行されます。
構文:
variable <= expression;Non-Blocking Assignment(非ブロッキング代入)を使用するタイミング
Non-blocking assignment(<=)は、順序回路(sequential logic) — クロックを使用し、メモリを持つ回路で使用されます。出力はクロックエッジ(通常は立ち上がりエッジ)でのみ変化します。
順序回路の例:
- フリップフロップ
- レジスタ
- カウンタ
- ステートマシン
- シフトレジスタ
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両方の代入は同時に行われ、クロックエッジより前の値が使用されます。
まとめ
| ルール | 説明 |
|---|---|
順序回路の logic には <= を使用する | always @(posedge clk) |
組み合わせ回路の logic には = を使用する | always @(*) |
non-blocking 代入は並列に実行される | All 代入が同時に行われる |
values はタイム Step の end で更新される | 即座には更新されない |
チャレンジ
非ブロッキング代入を完成させる
不足している非ブロッキング代入を追加して、この2ビットシフトレジスタを動作させてください。
動作原理:
- クロックエッジごとに、
q1にdが代入されます q2にq1の古い値が代入されます
手順:
q1にdを代入します(非ブロッキング)q2にq1を代入します(非ブロッキング)
自分で試してみよう
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このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。