Menu
CoddyTech

代入遅延

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 で使用する
challenge icon

チャレンジ

すること:

代入の遅延を追加して、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
quiz icon腕試し

このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。

基礎のすべてのレッスン

自分で練習してみよう: Verilogオンラインコンパイラ