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つのクロックを動的に切り替えたい場合、どうしたらよいでしょう?
MMCMのパラメータは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で作り、動かし、レジスタの値を読み出してみることにしました。
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と共にアサートしないと効果がないようでした。
そして、この値を書き込んでやるステートマシンを作ったところ・・・
周波数を動的に切り替えることができるようになりました。
| 固定リンク
コメント
ウブロブランドコピー(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