代入遅延
CoddyのVerilogジャーニー「基礎」セクションの一部 — レッスン 69/90。
これまでのレッスンでは、一般的なディレイ(#10 a = b;)およびゲートディレイ(and #5 (out, a, b);)を扱いました。ここでは、プロシージャルブロック(initial や always など)の内部で代入文の一部として発生するディレイである代入ディレイ(assignment ディレイ)について解説します。
Assignment delayは指定された時間waitsし、その後assignmentを実行します。delayは#記号のafter、かつassignmentのbeforeに配置されます。
構文:
variable = #delay expression;一般的な delay #10 a = b; (delay の後に assign) とは異なり、assignment delay a = #10 b; はその時点での b の値を取得し、10 time units waits してから a に assigns します。
Assignment Delay vs General Delay
| General Delay | Assignment Delay | |
|---|---|---|
| 構文 | #10 a = b; | a = #10 b; |
| 値が読み取られるタイミング | 代入の時点(delay の後) | 即座(delay の前) |
| 代入される値 | その時点での b の値 | 時刻 0(または読み取り時点)での b の値 |
| 値が代入されるタイミング | delay の後 | delay の後 |
例:違い
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ここではどちらも同じ result になります。違いは delay の during に b が changes するときに現れます。
Key Difference Example
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 内で使用されます |
チャレンジ
作業内容:
不足している assignment delay を追加して、a が 15 time units 後に b の値を受け取るものの、b の読み取りは即座に行われるようにしてください。
自分で試してみよう
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このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。