Spartan3Eの500を使っていて「DCMで3逓倍したクロックが出てこない」というトラブルがありました。
48MHzのクロックをいれてDCMで3倍して144MHzを取り出すという回路で、DCMと付随するBUFG等はCoregenを使って生成するというごくありふれた回路です。
Coregenで作る「Single DCM」はリセット機能を持っていないので、DCMのリセット回路は自分で作らなければなりません。DCMのリセットは使わずに'0'固定でも一応動くのですが、クロックが停止したり再開したりするような回路だと、クロックが再開したときにDCMがロックしないことがあります。そういう回路ではDCMにリセット信号を入れなければなりません。
このリセット回路というのは、DCMのロックが外れる(='0')とリセットパルスを送る、という動作をします。DCMにリセットを送った直後はDCMのロックは当然はずれるので、リセット回路には不感時間を設けます。不感時間を作るために中にカウンタを作るのでクロックが必要になりますが、リセット回路のクロックにはDCMが出力するクロックは使えないので、IBUFGを通った後の「生クロック」を使います。
なお、Spartan3EのDCMは、データシートによればロックするまでに最大5msかかるとなっているので、不感時間は5ms以上にします。
このように普通のDCMの回路なのですが、とても質の悪いクロックが与えられた場合に、CLKFXがちゃんと出てこないという現象が発生しました。
質が悪いクロックというのは、あるときは48MHzでちゃんと発振しているのに、止まったり再開する、というのを何度も繰り返すクロックです。
データシートを見ると、DCMの中にはDLL(遅延ロックループ)の部分と、DFS(ディジタル周波数合成)と書かれた部分があります。
クロックをM倍やD分周してくれるのはDFSの部分なのですが、DCMのLOCKED信号はDLLのCLKINとCLKFBが同相であることを示す信号であって、DFSがロックしたかどうかは関係ないようなのです。
DFSがロックしたかどうかは、STATUS[2]を見るとわかるようです。
DCMにリセット信号を送ってから5ms後に、LOCKEDが'0'か、もしくはSTATUS[2]信号が'1'ならばDCMが正常に動作していない、と判断してリセットを送るようにしたところ、質の悪いクロックでもちゃんと動作するようになりました。
まとめ
Spartan3EのDCMを使ってM倍やD分の1のクロックを作る場合には、LOCKED信号とSTATUS信号を必ず見るようにして、CLK0とCLKFXの両方がちゃんと発振しているかどうかを確認する必要がある、ということがわかりました。
最近のコメント