研修中、Verilog HDL で 7 セグデコーダーを作成していたところ、
Quartus II 上で “ラッチが存在しています” という warning が出てしまいました。
こちらがそのときの warning メッセージです。
そのときにできた論理を RTL Viewer で見てみました。
RTL Viewer で論理を見ると確かにラッチがある…。
どうしてラッチが生成されてされてしまったのだろう?
ラッチというものを記述した覚えがないのに…。
7 セグデコーダーでは主に case 文しか記述していないので、そこしか原因がないと考え、過去にうまくいった case 分の記述と比較してみることにしました。
すると default の記述をしていないことがわかったので、追加してみました。
default 記述をした改善後の RTL Viewer が下図です。
はい…、これが原因ですね!
case 文の default の記述ひとつでここまで回路が変わってしまうんですね!
繊細過ぎて扱うのに一苦労です…。
ところで、コンパイル・レポート見てみると FPGA が消費する ロジック・エレメント (LE : FPGA の容量) の数が異なっていました。
case 文は条件を定義して実行する式を記述していくので、全ての条件を網羅しない場合、前の値を保持しなければならないと推論して、ラッチを構成します。
default 文ですべての条件を記述しないと、記述されていない条件の前の値を保持しようとしてラッチを生成してしまいます。
default 文は忘れずに書いておくことが重要なんですね。
見落としがちな warning も目を向けてみると結構勉強になるかもしれません。
ちなみに、研修中にラッチはよくないと散々言われ続けてきましたが、
シンボルで見ても、動作を見てもとほとんど同じなのにどうしてラッチはだめなのでしょう?
上図で見てもプリミティブ・レベルは一緒に見えます。
しかし、実際にラッチの構造を見ると NAND で組まれていてフィードバックされていることが分かります。
(Quartus II ってすごい、ここまで見えるんだ!)
ラッチについて全然わからなかったので先輩に質問してみました!
ラッチもフリップフロップもデータを保持するための機能ですが、フリップフロップはクロックの立ち上がりエッジ(または立下りエッジ)でデータを取り込んでいて、ラッチは、出力をフィードバックし入力に戻すことを繰り返して保持をしているそうです。
下図がラッチの構造です。
また、フィードバックは配線の長さによって遅延時間が変化するため、つねに同じタイミングでデータが取れるわけじゃないようです。
何度も書き換えられる FPGA や CPLD は 必ず、ロジックセルという単位の中にフリップフロップが入っているので、似たような機能があるなら安全なフリップフロップで回路を組んだ方がいい!ということですね。