« 非同期FIFOでのタイミングエラー | トップページ | ZYNQ搭載のADCボードを作ります »

2014.03.22

XILINX 7 シリーズにおけるMMCM周波数の動的変更

XILINX 7 シリーズには、MMCMといって、従来のPLLやDCMをさらに進化させたクロック生成器が入っています。

MMCMの最大の特徴はなんといっても、分数の分周比や逓倍比が設定できることです。分数といっても1/8単位ではありますが、周波数の選択の幅がとても増えます。たとえば、50MHzから、SXGAのビデオ信号などで使う108MHzを作りたい場合には、M=20.25、D=9.375として、

50MHz×20.25÷9.375 = 108MHz

が生成できます。

HD1080pの148.5MHzを生成したい場合には、

50MHz×37.125÷6.25÷2 = 148.5MHz

とできます。

さて、この2つのクロックを動的に切り替えたい場合、どうしたらよいでしょう?

Clkdrp_1MMCMのパラメータはCoreGenで生成するときに決まってしまっていますが、DRP(Dynamic Reconfiguration Port)というポートを操作すると、分周比や逓倍比を実行時に動的に変えることができます。

MMCMのDRPのポートは右の図をご覧ください。

MMCMには様々な設定項目が入るレジスタがあって、DADDR[6:0]で指定します。DINやDOUTから設定値が出てきて、DWEやDEN、DCLK、DRDYを使って読み書きの指示を与えるようです。

ところが、DADDR[6:0]で内部レジスタのアドレスを指定するのだろうとは思うのですが、レジスタがどうなっているのかはさっぱりわかりません。そこで、まず実際に148.5MHzや、108MHzに設定したMMCMをCoreGenで作り、動かし、レジスタの値を読み出してみることにしました。

Clkdrp_2

DADDR(0)=8480、DADDR(1)=0092、DADDR(2)=0003・・・と何やら読めています。この値を書き込んでやればきっとMMCMが切り替わるのでしょう。

そんなふうに考えていた時期が俺にもありました

実際にはもっと複雑でした。私がたどり着いたのが、XAPP888というアプリケーションノート。このXAPP888では2つのMMCMのコンフィギュレーションを動的に切り替えるというものですが、非常に参考になりました。

XAPP888を読んでわかったことは、

  • 全部のレジスタを操作する必要はない
  • レジスタの値をDOUTから読んで、ReservedなところをMASKして残し、新たに設定する値をORでセットしてからDINに入れる
  • レジスタは0から順番に設定していくのではない

また、各レジスタの設定方法がかなり複雑であり、Lock RegisterやFilter Registerの設定値はテーブルをルックアップして求めなければならないこともわかりました。

結局、CoreGenで1回作って実機で動かして、DRPから読み出した値をVHDLソースにハードコーディングしておいて、それを書き込んだほうが楽という結論にたどり着きました。

そして、どういう順序でどのようにレジスタを設定すればよいかをまとめると・・

DRPレジスタのアドレス 説明

出力108MHz

出力148.5MHz

0x28 PowerReg 9900 9900
0x08 CLKOUT0 Reg1 1104 1082
0x09 CLKOUT0 Reg2 3880 2c00
0x0a CLKOUT1 Reg1 0041 0041
0x0b CLKOUT1 Reg2 0040 0040
0x0c CLKOUT2 Reg1 0041 0041
0x0d CLKOUT2 Reg2 0040 0040
0x0e CLKOUT3 Reg1 0041 0041
0x0f CLKOUT3 Reg2 0040 0040
0x10 CLKOUT4 Reg1 0041 0041
0x11 CLKOUT4 Reg2 0040 0040
0x06 CLKOUT5 Reg1 0041 0041
0x07 CLKOUT5 Reg2 2840 0c40
0x12 CLKOUT6 Reg1 0041 0041
0x13 CLKOUT6 Reg2 0c40 2440
0x16 DIVCLK 1041 0041
0x14 CLKFBOUT Reg1 1249 1491
0x15 CLKFBOUT Reg2 2c00 1880
0x18 Lock Reg1 01f4 00fa
0x19 Lock Reg2 7c01 7c01
0x1a Lock Reg3 ffe9 ffe9
0x4e Filter Reg1 9008 0908
0x4f Filter Reg2 0100 1000

という結果になりました。確かにXAPP888に書かれたビットフィールドの意味と照らし合わせて考えれば妥当なのですが、まぁ、これを自分で計算するのは大変です。VHDLのfunctionにすればよいのでしょうが・・

この値をDRPに書き込んでやれば、周波数は切り替わります。DENやDWE、DRDYの使い方は上の波形を参考にしてください。DWEはDENと共にアサートしないと効果がないようでした。

Clkdrp_3

そして、この値を書き込んでやるステートマシンを作ったところ・・・

Clkdrp_4Clkdrp_5

周波数を動的に切り替えることができるようになりました。

|

« 非同期FIFOでのタイミングエラー | トップページ | ZYNQ搭載のADCボードを作ります »

コメント

ウブロブランドコピー(N級品)販売通販専門店
ウブロコピー、ウブロブランドコピー、ウブロコピー時計、
ウブロコピー代引き、ウブロコピー 時計通販、ブランドコピー、
各種海外有名ブランド時計品を豊富に取り揃え、
しかもお客様を第一と考えて、驚きの低価格で提供しております

投稿: スーパーコピー時計 | 2021.12.03 18:29

2点ほど質問があるため下記に記載させていただきます。

1.そもそもの質問で恐縮ですが「動的に変更」の定義は何になりますでしょうか。
 ・PLL、MMCMのリセット信号は入れずにDRPからレジスタの変更を行う
 ・PLL、MMCMのリセット信号をアサートしてDRPからレジスタの変更を行う
 動的でなく普通に変更するということもある?※普通がどう変更するのかわかりませんが。

2.DRPレジスタの設定順についてですが、資料に記載がありましたでしょうか。
 記載いただいている順が妥当であることは何となくわかるのですが、
 決定的な根拠(資料)が自分は見つけられていません。
 資料に記載はなく、結果からの推論で設定順について述べられているのでしょうか。

ご教授いただければ幸いです。
よろしくお願いいたします。

投稿: | 2022.09.06 14:38

>1.そもそもの質問で恐縮ですが「動的に変更」の定義は何になりますでしょうか。
> ・PLL、MMCMのリセット信号は入れずにDRPからレジスタの変更を行う
入れずにです

> 動的でなく普通に変更するということもある?※普通がどう変更するのかわかりませんが。
普通は設計時に固定しますね

>2.DRPレジスタの設定順についてですが、資料に記載がありましたでしょうか。
資料はありません

投稿: なひたふ | 2022.09.06 15:50

ご回答いただきありがとうございます。

>普通は設計時に固定しますね
自分としても基本的にはそのように考えてはいるのですが、
FPGAの動作中にクロックを変更したいと考えております。
その上で動的ではなく、一度クロックの生成が止まってもよいという場合は、
PLL,MMCMのリセットを入れてDRPからレジスタ変更を行えばよいという認識でよろしいでしょうか。
もしくは設計時以外のPLL,MMCMの変更は動的に行うことでしか変更できない?

現在実機が手元にない状況で、情報収集しか出来ず、
質問の連投となってしまい大変申し訳ありません。
ご回答いただければ幸いです。
よろしくお願いいたします。

投稿: | 2022.09.06 16:42

うーん、リセットかけるとデフォルトの値にもどっちゃいますからね。

XILINXのプリミティブは、外からの信号で設定を変えられるやつと、論理合成時に決まるやつがあります。

データシート(ユーザガイド)を見れば「入力ポート」で設定するのか、アトリビュートで設定するのかの違いです。MMCMの分周比みたいなのはプリミティブのアトリビュートで設定するのですが、そういうのを後から変更するのがDRPです。

プリミティブによってはDRPができないものも、DRPに対応していないパラメータもいっぱいあります。

投稿: なひたふ | 2022.09.06 17:17

ご回答いただきありがとうございます。

>リセットかけるとデフォルトの値にもどっちゃいますからね。
基本的な知識が抜けていました。
既存のクロックから変更するためには動的に変更するしかないわけですね。

回答いただいた内容を参考にしつつ
色々と試しながら試行錯誤したいと思います。
ありがとうございます。

投稿: | 2022.09.07 09:14

コメントを書く



(ウェブ上には掲載しません)




« 非同期FIFOでのタイミングエラー | トップページ | ZYNQ搭載のADCボードを作ります »