Spartan-3A スタータキット

〜DCMでクロック生成〜


2007/08/26

あなたは 人目のお客様です.

DDR2メモリがうまく動作していない のだけれど,以前も書いたけどやはりクロックが問題な気がする.

ということで,DCMを使ったクロック生成をやってみよう.

まずDCMについてなのだけど, だいたい想像はつくけど Digital Clock Manager の略だ. なにができるかというと, たとえば基準のクロックから定数倍,定数分割したクロックを生成できる. つまりクロックの逓倍や分周が行える. また,位相を90度ずらしたクロックとかを生成したりできる. さらにフィードバックを利用することで, 配線遅延による位相のズレを補間してクロック生成することもできる. まあクロック周りでやりたいことはたいていできる.

DCMについては DesignWave 2005/04 に記事がある. この記事は冒頭部分を上記ページからダウンロードして参照できるのだけど, その記事によれば,DCMはDDR利用時に90度位相がずれたクロックがほしいとき などには必須の機能のようだ. で,この記事を参考にして...といいたいところなのだけど, 残念ながらバックナンバーを入手できていない. うーむ,ぜひ読みたいのだが.

DCMについてはXilinxのページで DCM で検索すると,DCMのヘルプが出てくる. あとDCMのデータシート(dcm_module.pdf)の場所も出てくる.

あとXilinxのページで配布している Spartan-3 のアプリケーションノートの xapp462 に詳しい説明がある. これは日本語版があるので読みやすい. 注意として,DCMに関するアプリケーションノートは Spartan-3A のアプリケーションノートを検索しても見つからない (Spartan-3 のアプリケーションノートで検索しなければならない. まあ Spartan-3A も Spartan-3 シリーズのひとつなのだから, 当り前といえば当り前なのだけど). ちなみにSpartan-3のアプリケーションノートには, 他にも有用な情報がいろいろあるので注意. 調べるときにはSpartan-3Aのところだけでなく, Spartan-3 に関しても調べる必要があるということだ.

アプリケーションノートには,PLLやDLLのしくみや違いについての説明, フィードバックの使いかたや原理についての説明も有る.必見.

あと このページ も参考になる.こちらはPLLとかについて説明してある.

で,HDLの作成なのだけど,xapp462によれば,以下の3通りの方法がある.

  1. ISE WebPACK のウィザード機能を使う
  2. ISE が持っている言語テンプレートのサンプルソースを使う
  3. サンプルソース(上記2と同様のもの)を ここ からダウンロードして使う(これは VerilogHDL 版だけど,VHDL 版もある)
ウィザード機能を使えば,GUIで希望の設定をすればあとは ISE が 適切なHDLを出力してくれる. これは便利で簡単なのだけど,まあせっかくなので (ていうかウィザード使ってさくっと動いてもつまらんので) 勉強がてら, VerilogHDLのサンプルファイルをダウンロードして参考にしつつ 自前でガリガリ書いてみることにする. サンプルとしては,上記3からダウンロードしたものと, あとDesignWaveの記事の冒頭部分(ダウンロードしたもの)を参考にする.

※ ここではとりあえずダウンロードした記事冒頭部分を参考にしてしまったけど, みんなはちゃんとお金を出してDesignWaveを買おうね!

で,書いてみたのだけどうまく動作しない.

いろいろ調べたのだけど,Spartan-3シリーズのユーザーガイド(ug331)に DCMの説明の章があって, よく読んだところ以下の2点に注意する必要があるようだ.

IBUFGについてなのだけど,これは自分の勝手な想像なのだけど, クロック線を複数本に分割する際に用いるように思える. クロック線は高速なので,複数箇所で利用したい場合にはこのようなバッファを とおして複数に分割するのではなかろうか(あくまで想像だけど)? これはDDR2の実装でも必要なように思うので注意 (クロック線を直接利用せずに,IBUFGでバッファを通してから使うとか). まあこのへんは,きっとDesignWaveに説明があるのだろう. あー,バックナンバー読みたい.

で,作成したのが以下.

dcm.v
s3astarter.ucf

DCMで以下のクロックを生成して,LEDの右4つがちかちか点滅する.

上記の4種類のクロックをDCMで生成し, 50,000,000回をカウントするたびにLEDを点滅するようにしてある. 基準のクロックは50MHzなので, たとえば右から3つ目のLEDは, その2倍として2秒おきに点滅する,ということだ.

ところで,ソースコード中ではIBUFGとかBUFGとかDCMとかDCM_SPとかの モジュールを利用しているのだけど, これらのモジュールを利用する場合はなにか宣言とかはいらないのかしら? VHDLではそういう宣言というかライブラリの指定が必要みたいだし, C言語ならばライブラリをリンクしたりするけど,どうなのだろう? まあとくにそういった宣言は無しでいきなりモジュールを利用してしまっても うまく論理合成できているのでいいみたいなのだけど,ちょっと気になる.

で,論理合成してスタータキットにダウンロードすると無事にLEDが ちかちか点滅しだした.

一番左のLEDは基準のクロック.これは50MHzなので,高速に点滅していて (上記画像ではよくわからないけど)一見するとちょっと暗めに点灯している ように見える.

左から2番目のLEDはDCMのLOCKEDを繋げてある. 点灯しているので,DCMはロックされ,正常にクロックを生成していることがわかる.

左から3,4番目のLEDはステータスを表している.両方点灯しているので, ステータスとしては3番目の DCM_STATUS_LOCKED (dcm.v参照) になっている.

実際に点滅の間隔を見てみたところ,クロックに問題はなさそうだ.よしよし.

次はこれをDDR2に応用してみたい.


メールは kozos(アットマーク)kozos.jp まで