同期化回路の落とし穴

2023/03/28に公開

FPGA超入門 その3-注意点-で簡単に書いた同期化について、もう少し詳しく書きたいと思います。

単純な同期化回路(同期化FF)

上記で一番単純なものは、FFを2段つなげたものと書きました。

これが同期化回路として動作するのはなぜなのかを、少し解説したいと思います。
A,B,Cの各点において、どのような動作になるのかタイミングを示すと、下記のようになります。

まずAは同期化回路への入力信号になります。CLKとは別のクロックに同期していたり、外部のスイッチがつながっている等、CLKとは無関係に信号が変化するものとします。
そのため、BはAの信号をCLKで取り込んだ信号ですが、このB点において、メタステーブル状態が発生する可能性があります。メタステーブル状態は一般的に長続きせずHかLに落ち着きます。
CではBの信号が安定した状態でCLKで取り込むので、以降にメタステーブル状態が伝搬することなく、入力信号AをCLKで同期化した信号として使うことが出来ます。

しかし、様々な落とし穴が待っているので、注意が必要です。

落とし穴:2段で足りるのか

ある条件下ではFFが2段では足りず、落とし穴にはまる可能性があります。

case1:FF間の伝搬遅延が大きい

1段目と2段目もFF間の伝搬遅延[1]が大きいと、2段目のFFにメタステーブル状態が伝わってしまうこともあり、2段では足りなくなる場合があります。

ただ、基本的にはツールで伝搬遅延が小さくなるように配置配線してくれるため、あまり意識することはないかもしれませんが、ツールによってはオプション的な記述を追加することで、意識的に隣接した極近いところに置けるようにも出来ますので、覚えておいて損はないでしょう。

case2:入力信号や同期化CLKの周波数が高い

メタステーブルは入力信号や同期化CLKの周波数の高さに比例して発生確率が高くなります。
例えば下記の例のように、メタステーブルが継続している時間より早く、次のクロックが来てしまった場合、2段目のFFにメタステーブル状態が伝わってしまいます。

case3:入力信号の周波数と同期化CLKの周波数が近い

入力信号の周波数と同期化CLKの周波数が近い場合も注意が必要です。
極端な例ですが、入力信号の周波数と同期化CLKの周波数が全く同じで位相がセットアップ/ホールドを満足しないものだった場合、毎クロック、メタステーブルが発生する可能性があります。

後段にメタステーブル状態が伝わらないとしても、正しい情報が伝わらなくなるので、このような場合は、同期化FFではなく別の方法で同期化した方がよいだろうと考えます。

落とし穴:パルス信号

入力信号がパルス信号だった場合、落とし穴にはまる可能性があります。
同期化FFの場合、ある程度の時間安定している必要があります。最低でも1CLKはセットアップ/ホールド時間を満足して安定して取り込めないといけません。
パルス信号を例として、少し解説したいと思います。
CLKの周期より短い幅のパルス信号の入力では、位相によって、取り込めたり取り込めなかったりします。

CLKの周期の幅のパルス信号の入力では、位相の違いによってメタステーブル状態が発生し、入力パルスが消失してしまうことがあります。

どの位相でも取り込むには、最低でもCLKの周期+セットアップ時間+ホールド時間のパルス幅が必要で、CLKの2周期以上が望ましいと考えます。

上記はパルス信号を例として挙げましたが、拡張して考えると、CLKの周期より早い~同程度で変化する入力信号は、同期化FFでは正しく同期化できない可能性があることが分かります。

落とし穴:複数bit信号

入力信号が複数bit信号だった場合、落とし穴にはまる可能性があります。
1bitだと問題ない同期化FFでも複数bitになると問題が生じる可能性が出てきます。
複数bit信号がそれぞれ同じ長さの配線となることはまず無く、到着時間に差が生じるので、bitによってメタステーブルが発生したりしなかったりと差が生じ得ます。そのため、複数bitを値として見ると、一瞬入力された値とは異なる値が見えることがあります。後段の回路によっては、この値が異常な動作の引き金になることもあり、注意が必要です。

具体的には、この異常な値が後段で使われないような工夫が必要となります。

Dual Clock FIFOによる同期化

Dual Clock FIFOは使用頻度の高い部品のHDL記述例 -FIFO-の例2の非同期FIFOのように入力側(書き込み側)と出力側(読み出し側)を別々のクロックで動作させることが出来るFIFOです。FIFOはFirst In First Outのバッファで、先に入力されたデータが先に出力されます。

このため、Dual Clock FIFOの入力側に同期化させたいデータを入れれば、出力側に同期化されたデータを得ることが出来ます。
同期化FFではうまくいきにくい同期化もDual Clock FIFOではうまくいく場合があります。逆もまた然りで、Dual Clock FIFOではうまくいきにくい同期化もありますので、状況に応じて使い分けるなどが必要になってきます。

Dual Clock FIFOで注意が必要なものをいくつか挙げてみます。

落とし穴:外部入力

外部入力信号のDual Clock FIFOによる同期化は落とし穴にはまる可能性があります。
例えば、外部のスイッチ入力などクロックが存在しない入力信号は、FIFOに書き込む際に何かしらのクロックに同期化させるなどが必要となってきます。(その時点で同期化出来ているのであればFIFOは不要ですが。)

外部入力でも、それが同期しているクロックをFIFOに接続出来れば、同期化出来ることもありますが、そのクロックと外部入力データの位相がずれていて、FIFOのセットアップ/ホールドを満足しない場合は、正しく同期化出来ません。

落とし穴:入出力レート

FIFOの入力レートと出力レートが異なる場合は落とし穴にはまる可能性があります。
入力レート<出力レートの場合はFIFOが空になるため、任意の連続した期間で有効な出力データを得られなくなりますが、FIFOにデータ有効のフラグを持たせるなどすればよい場合もあります。
入力レート>出力レートの場合はFIFOに溜まっていき、いずれ溢れてしまい正しく同期化出来なくなります。

入力レート=出力レートとさせるためには、間欠した読み書きをしたり、入出力でbit幅を変えたり、様々な工夫が必要となってきます。
入出力が同じ周波数であれば問題ないかと言えば、必ずしもそうではなく、例えば同じ100MHzと言っても、クロック源が異なる場合は厳密に見ると異なる周波数となります。このような場合は、長時間経過しないとFIFOが空になったり溢れたりせず、再現性の低い不具合となり得ますので、特に注意が必要です。

落とし穴にはまらないために

どうしたら同期化回路の落とし穴にはまることなく安心なものとなるか、また落ちてしまってもすぐに抜けだすにはどうしたらよいか、これはまたいずれまとめたいと思います。

脚注
  1. この場合、1段目FFの出力信号が2段目FFの入力に到達するまでの時間。例えば配線が長いとその分時間がかかる。 ↩︎

Discussion