代入遅延
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 に代入します。
代入遅延と一般遅延の違い
| 一般遅延 | 代入遅延 | |
|---|---|---|
| 構文 | #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:
a1がまだ待機している間に、bが0に変わります - 時刻10:
a1には0ではなく、時刻0に読み取った値である1が代入されます
別のブロックで一般的な遅延#10 a2 = b;を使用すると、時刻10にbが読み取られます(値は0)。
重要なルール
| ルール | 説明 |
|---|---|
= は # の前に置く | a = #10 b; であり、a #10 = b; ではない |
| 値はすぐに読み取られる | 右辺はただちに評価される |
| 代入は遅延の後に行われる | 左辺には後で値が設定される |
| 手続きブロックでのみ使用する | initial または always で使用する |
チャレンジ
すること:
代入の遅延を追加して、aが15時間単位後に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このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。
基礎のすべてのレッスン
自分で練習してみよう: Verilogオンラインコンパイラ