FPGA開発日記

カテゴリ別記事インデックス https://msyksphinz.github.io/github_pages , English Version https://fpgadevdiary.hatenadiary.com/

Verilogの慣性遅延と伝播遅延

最近までハードウェア設計における慣性遅延と伝播遅延について知らなかったのでメモ。

VHDLでは、明確に慣性遅延と伝播遅延についての文法があるらしい。Verilogでは結構ややこしい。

まずは例題

以下のようなVerilogを記述した。それぞれinertial_ff, transport_ffの値はどうなる?

module delay_model;
  reg clk;

  reg [ 7: 0] ff;
  reg [ 7: 0] transport_ff, inertial_ff2;
  wire [ 7: 0] inertial_ff;

  always @ (posedge clk) begin
    ff <= $random;
  end
  assign #300 inertial_ff = ff;
  always @ (ff) #300 inertial_ff2 <= ff;
  always @ (ff) transport_ff <= #300 ff;

  initial begin
    clk = 1'b1;
    forever begin
      #(100) clk = ~clk;
    end
  end

  initial begin
    #2000;
    $finish;
  end

endmodule // delay_model

答え

f:id:msyksphinz:20170120001038p:plain

200unitで変化する値を、300unit遅延つけて伝播した場合、inertial_ffは値が飛び飛びに取得され、transport_ffは値が全て遅れて取得された。

慣性遅延(inertial delay)について

慣性遅延、伝播遅延について、文法的に解釈するならば、Veritakの解説が非常に分かりやすい。

  • 6.1 Transport とInertial Delay

http://japanese.sugawara-systems.com/tutorial/verilog/newpage18.htm

先ほどの記述

  always @ (ff) #300 inertial_ff2 <= ff;

300unit経ってからinertial_ff2への代入が実行されると解釈される。このため、ffの値は300unit後の値がinertial_ffに伝播される。

このため、ffが変化してから300unit後の値がinertial_ff2に入っていることが分かる。inertial_ffのほうはなんだかよく分からない値が入ってしまっている。

伝播遅延(transport delay)について

伝播遅延のほうは

  always @ (ff) transport_ff <= #300 ff;

いったんffの値がキューイングされ、300unit後に代入が実行される。このため、300unit後にtranspose_ffに代入されるのは300unit前のffの値となる。

f:id:msyksphinz:20170120002145p:plain