MUXシンクロナイザ

[] [] []


×

 
ダブルFFシンクロナイザは1ビットの信号には使えるが、多ビットの信号にそのまま使うと、現実の回路では信号間にスキューが生じるので各ビットが同時にサンプリングされるとは限らない。例えば3'b0113'b100と変化したとき、過渡値3'b010をサンプリングしうる。

多ビットの信号を互いに非同期なクロックclk_aからクロックclk_bへ転送するにはどうすればよいだろうか

1つの方法は、転送元のFFと転送先のFFが更新されるタイミングが重ならないように上位プロトコルで保証することである。例えば、両方のFFをソフトウェアで更新していれば逐次的にしか更新できないので、回路上は何もしなくても更新タイミングが重なることはない。

ここで、非同期転送FF間に組合せ回路(マルチプレクサ)が入っているので、前項で見たようにハザードをサンプリングしないかという心配がある。ハザードが出ると困るのは、マルチプレクサy = (en_b)? dat_a : dat_b においてen_b=0の間に、選択してない方の入力dat_aが変化した時である。一般のAND-ORゲートで組んだマルチプレクサでは、en_b=0dat_aANDされているので、dat_aが変化してもyにハザードは出ることはなく大丈夫である。

FPGAでは組合せ回路はAND-ORゲートでなくルックアップテーブル(LUT)で実現されるが、実は1個のLUTに収まっていれば大丈夫である。これは次項で詳しく調べる。

◇◇

上位プロトコルによるのではなく回路的に更新タイミングが重ならないようにするには、1ビットのイネーブル信号を使って更新タイミングを作ればよい。(マルチプレクサを使うのでここではMUXシンクロナイザとよぶ)

MUXシンクロナイザを使うとき、en_adat_aの更新周期tCLKAclk_bの周期tCLKBの間には制約がある。

図においてclk_aのエッジがclk_bのエッジ0-1間にあるとき、dat_aclk_bのエッジ3でサンプリングされるので、

  3 * tCLKB + tCLKA (凾ヘen_adat_aのスキュー)

と、clk_bclk_aより少なくとも3倍速くなければならない(実際は凾考慮して4倍以上にした方がよい)

clk_bがもう少し遅くてもよいようにするには、dat_aの方もダブルFFで受ければよい。このときen_bが変化するよりも前にdat_bの入力が確定していなければならないという条件(補足)からen_aの方も1段増やす必要がある。

このとき、clk_aのエッジがclk_bのエッジ0-1間にあるとき、en_bclk_bのエッジ4で有効になるので、dat_aclk_bのエッジ2でサンプリングすればよく、

  2 * tCLKB + tCLKA (凾ヘen_adat_aのスキュー)

と、clk_bclk_aより少なくとも2倍速ければよい。(実際は凾考慮して3倍以上にした方がよい)

◇◇◇

(補足) イネーブルen_aとデータdat_aの両方をダブルFFで受けると不都合な理由

×

 

en_adat_aの変化タイミングがclk_bのサンプリングと重なった場合、en_a1かつdat_a=過渡値をサンプリングしうるので、このときdat_bが過渡値になってしまう。


[] [] []