代入遅延
CoddyのVerilogジャーニー「基礎」セクションの一部 — レッスン 69/90。
これまでのレッスンでは、一般的な遅延 (#10 a = b;) とゲート遅延 (and #5 (out, a, b);) について学習しました。今回は、代入遅延について説明します。これは、代入文の一部としてプロシージャルブロック (initial や always など) の内部で発生する遅延です。
代入遅延は、指定された時間待機してから代入を実行します。遅延は # 記号の後ろ、かつ代入の前に配置されます。
構文:
variable = #delay expression;一般的な遅延 #10 a = b;(遅延させてから代入)とは異なり、代入遅延 a = #10 b; は、その時点での b の値を取得し、10タイムユニット待機してから、それを a に代入します。
代入遅延 vs 一般的な遅延
| 一般的な遅延 | 代入遅延 | |
|---|---|---|
| 構文 | #10 a = b; | a = #10 b; |
| 値が読み取られるタイミング | 代入時(遅延後) | 即座に(遅延前) |
| どの値が代入されるか? | その時点での b の値 | 時刻0(または読み取り時)の b の値 |
| 値が代入されるタイミング | 遅延後 | 遅延後 |
例:違い
initial begin
b = 1;
#5 b = 0;
// 一般的な遅延
#10 a1 = b; // 10待機してからbを読み込む (b=0) → a1=0
// 代入の遅延
a2 = #10 b; // 今すぐbを読み込み (b=0)、10待機してから代入 → a2=0
endここでは、どちらも同じ結果になります。違いが現れるのは、遅延の間に b が変化したときです。
主な違いの例
To show b changing during the delay, we need two separate initial blocks that run in parallel:
initial begin
b = 1;
a1 = #10 b; // 時刻0でb=1を読み取り、時刻10でa1=1を代入します
end
initial begin
#5 b = 0; // 時刻5(遅延の間)にbを0に変更します
end- 時刻 0:
a1はb = 1を読み取ります - 時刻 5:
bが0に変わります (a1がまだ待機している間に) - 時刻 10:
a1には (時刻 0 に読み取られた値である)1が代入され、0ではありません
別のブロックで一般的な遅延 #10 a2 = b; を使用すると、b は時刻 10 に読み取られます (値 0)。
重要なルール
| ルール | 説明 |
|---|---|
= は # の前に置きます | a = #10 b; であり、 a #10 = b; ではありません |
| 値は即座に読み取られます | 右辺はすぐに評価されます |
| 代入は遅延の後に発生します | 左辺は後で値を受け取ります |
| 手続き型ブロック内でのみ使用されます | initial または always 内で使用されます |
チャレンジ
作業内容:
a が 15 時間単位後に b の値を取得し、かつ b を即座に読み取るように、欠落している代入遅延を追加してください。
チートシート
代入遅延 (Assignment delay) は、右辺を即座に読み取り、指定された遅延時間を待機してから代入を行います:
variable = #delay expression;通常の遅延との主な違い:
通常の遅延 #10 a = b; | 代入遅延 a = #10 b; | |
|---|---|---|
| b の値の読み取り | 遅延後 | 即座 |
| 値の代入 | 遅延後 | 遅延後 |
遅延の最中に b が変化した場合、結果が異なります:
initial begin
b = 1;
a1 = #10 b; // 今すぐ b=1 を読み取り、時刻 10 で a1=1 を代入する
#5 b = 0; // 時刻 5 で b が変化する — a1 は依然として 1 を受け取る
// #10 a2 = b; の場合 → 時刻 10 で b=0 を読み取るため、a2=0 となる
end手続き型ブロック(initial または always)内でのみ有効です。
自分で試してみよう
module assignment_challenge;
reg a, b;
// 遅延の間に b を変更するための独立したブロック
initial begin
b = 1;
// TODO: 代入遅延を追加
// a は 15 時間単位後に b を取得する必要がある
// 今すぐ b を読み取り、遅延後に代入する
end
initial begin
#5 b = 0; // 遅延の間に b を変更
#20 $display("Time %0t: a = %b", $time, a);
$finish;
end
endmoduleこのレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。