7シリーズFPGAでの非同期クロック切り替え

注文済みの基板の到着を待つ間に、FPGAデザインの修正を行いました。

ADCにつながる信号線のピン配置を変更しても良かったのですが、今回の基板は、前回とは異なるコネクタに装着することになります。 つまり、新旧二つの基板を、同時に一つのZ-turn boardに装着することができます。 それで、Z-turn board上に実装されているディップスイッチで、どちらの基板からの信号を処理するかを変更できるようにしました。

FPGAの大きさとしては、両方の基板からのADCデータを同時に処理することも可能です。 でも、そこまでする必要性を今は感じません。それで、FM処理回路自体は1つだけで、当該回路にどちらの基板から信号を供給するかを、スイッチで切り替えるという算段です。

それで、ひとまず想定した実装を行って、既存基板で動作することを確認しようとしたら、どうにも動作しませんでした。 調べてみたところ、MMCMのlocked信号がHighになっていない。つまり、基板からの40MHzのクロックがちゃんと切り替えられていない。

結果として、次のようにすることで解決できました。

BUFGCTRL bufg_inst (  // use as asynchronous MUX
    .IGNORE0    (1'b1),
    .IGNORE1    (1'b1),
    .CE0        (1'b1),
    .CE1        (1'b1),
    .S0         (!SW[2]),
    .S1         (SW[2]),
    .I1         (w_adc_ck_bufg),
    .I0         (w_adc_ck_b_bufg),
    .O          (w_adck)
);

最初はBUFGMUX_CTRLを使用していましたが、それが原因でした。UG472をよく読んでみると、 BUFGMUX_CTRLは基本的には、どちらの入力クロックも常時トグルしている場合に使用することが前提となることが分かりました。

それだと、場合によって(必要な要件によって)は当然困った事態になりますので、ちゃんと回避方法が準備されています。 それが、BUFGCTRLのIGNOREピンです。IGNORE0をHighにすると、I0ピンのクロックからI1ピンへのクロックの切り替えが(クロックの変化を待たず)即時に行われます。IGNORE1をHighにすると、I1ピンからI0ピンへのクロック切り替えが即時に行われます。

というわけで、上記のように記述することで、現在のように片方の基板が接続されていない(したがってI0がずっとLow)場合でも、 SW[2]の切り替えに応じてクロック選択が可能になりました。

comments powered by Disqus