For Good FPGA Design

CDC対策!(1)

今回は、異なるクロック間でのデータ受け渡し(Clock Domain Crossing: CDC)での注意点を解説します。よくやってしまいがちなミスを挙げ、NGな理由と正しい方法について解説します。FPGAを安定して動作させるためにとても重要です。

目次

結論

  • CDCで、データを送る側は必ずフリップ・フリップ出力にする

パルス伸ばし

周期が短いクロックCLK1から、周期が長いクロックCLK2へ、パルス信号を受け渡す際、何の対策もしないと、CLK2側でパルスを取り逃がすことがあります(図1)。

図1(a) CDC
図1(b) パルスのCDCの波形

そこで、図2、図3のようにORゲートを使ってパルスを伸ばし、周期の長いクロックCLK2でも受け取れる長さにする方法が考えられます。

フリップ・フロップで、D1に対して1サイクル遅れたD2を作り、D1とD2のORを取ることで、パルスを2サイクル分に長くしています。パルスが長くなったので、周期が長いCLK2でも受け取れる…なんだかうまくいきそうですよね?

図2 パルス伸ばしNGの例
図3 パルス伸ばしの波形(理想)

しかし、図2の回路ではCDCはうまくいかないときがあります。図2の回路で起こりうる波形を図4に示します。

実際のFPGAでは、D1とD2の経路の長さは同じではありません。したがって、D1のデータがCLK2のフリップ・フロップに到達する時間と、D2のデータがCLK2のフリップ・フロップに到達する時間は異なります。

もし、D2のほうが遅れて到達すると、D3は図4のようにラクダのコブのような波形になります。CLK1とCLK2の位相関係はどうなっているかわからない(それが非同期)ので、コブの谷のところでCLK2側がデータをラッチすることが起こり得ます。すると、図4のように、パルスを取り逃がしてしまいます。

図4 パルス伸ばしの波形(不具合発生)

これ、ホントに起こります。

しかも、データの到達時間は、デバイスの個体や温度などによってばらつきます。したがって、複数作った基板のうち、1枚だけうまく動かないとか、冷やした時だけうまく動かないとかが発生します。

こういう不具合は、再現性が低いためデバッグがかなりしんどいです。図2のような回路は避けるようにしましょう。

CDCではフリップ・フロップ出力にする

上記のような不具合を防ぐためには、図5のような回路にします。CLK1側の出力はフリップ・フロップ出力にします。

D3のところはラクダのコブになる可能性があります。しかし、それを同じクロックCLK1でいったん受け取ると、図6のD4のように、ちゃんとデータが受け取れます。なぜなら、同じCLK1なので、論理合成ツールがセットアップ時間、ホールド時間が満たされるように頑張って(配置・配線して)くれるからです。

すると、CLK2のフリップ・フロップからはちゃんと長くなったパルスD4が見え、パルスを受け取ることができます。

図5 パルス伸ばし回路
図6 パルス伸ばし回路の波形

パルスに限らず、組合せ回路出力の信号を別のクロックで受け取ると、同様の問題が発生します。CDCでは、必ずフリップ・フロップ出力にしましょう

まとめ

  • CDCで、データを送る側は必ずフリップ・フリップ出力にする
アバター画像
この記事を書いた人
ジーノ。大手電機メーカーで、基板設計の全般と、FPGAの設計に従事した経験を活かし、FPGAについて情報発信中。
RTL設計、シミュレーション、タイミング・クロージャ、FPGAまわりのハードウェア開発まで、幅広く取り扱っております。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA