最近までハードウェア設計における慣性遅延と伝播遅延について知らなかったのでメモ。
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
答え
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
の値となる。