はじめに
FPGA は各社しばし同期リセット推奨だったと記憶していますが、FF周にはいろいろ機能がついてます。
KV260 (Zynq UltraScale+ MPSoC) 用の合成結果の中身を覗いてみたのでメモです。
普通に書いてみる
私が普段よく書く書き方が下記のような感じです。
module test( input var logic reset , input var logic clk , input var logic cke , input var logic din , output var logic dout ); always_ff @(posedge clk) begin if ( reset ) begin dout <= 1'b0; end else if ( cke ) begin dout <= din; end end endmodule
これを合成してみると
このように無駄なく各FFの機能への接続が推論されました。
リセットをクロックイネーブルの中に入れてみる
今度は下記のように、リセットを クロックイネーブルの if の中に入れてみます。
module test( input var logic reset , input var logic clk , input var logic cke , input var logic din , output var logic dout ); always_ff @(posedge clk) begin if ( cke ) begin if ( reset ) begin dout <= 1'b0; end else begin dout <= din; end end end endmodule
こう書き直すと、こうなってしまい LUT を消費してしまいました。
お作法通り書いておくことは重要そうです。
おわりに
リセット不要のFFで R端子使わないのもったいないので、ロジック的に値を0にしたいときに R 端子が使えないかどうか期待したのですが、CE を使ってる場合はLUTは必要になるようです。
ところでLUTを使うなら D 端子の入力でもよい気がしたのですが、R 端子を積極的に活用しようとするのは何かメリットがあるのかもしれません。気になるところです。
追記
そういえば「CLB内で LUT から FF の リセットに繋がるラインなんてあったっけ?」と思い、配置配線まで進行させたら、案の定一度 CLB の外に出て戻ってきていました。単体で見るとメリットがイマイチよくわからないですが、大きな回路だと有利だったりするのでしょうか?。