DDR2メモリのアクセス回路
最近はDDR2メモリのアクセス回路を作っています。
メモリへのクロック速度が150MHz(300MHz)、200MHz(400MHz)、266MHz(533MHz)と変わっても使えるような回路にしているのですが、ようやくまともに動くようになってきました。
作っていてまず最初にわかってきたことは、
DDR2メモリに対して書き込みを行うのはそれほど難しくないということです。
なぜならば、FPGAが出力する、クロック、制御信号、データ、DQS信号は、タイミングが厳密にコントロールできるからです。
いいかえると、RASやCASなど各種の制御信号が値が最も大きく変化したタイミングに、クロックの変化の中心を合わせることは簡単にできるのです。
ただし、データ信号については、FPGAはクロックやストローブ(DQS)と90°位相をずらして出力する必要がありますが、XILINX FPGAならODDRプリミティブとDCMが作り出す90°クロックを使うことで、このタイミングは完璧にコントロールできます。
それに対して、DDR2メモリからデータを読み出すのは難しいです。
なぜならば、DDR2メモリがデータを出力してからFPGA内のレジスタでラッチされるまでの時間には、様々な遅延の要素があるからです。
仮に、DDR2メモリは、クロックから0.4nsにデータを出力するとしましょう。配線の遅延やFPGAの入力パッドの影響、入力セットアップで1.2nsくらいはかかるとしましょう。
この場合だと、クロックから1.6ns後にサンプリングしなければなりませんが、この遅延時間はクロックに関係なく、一定時間なのです。
例えば、1.6nsという時間は、150MHzのクロックならば約4分の1周期ですし、200MHzのクロックならば約3分の1周期、266MHzのクロックならば約半分のクロック時間に相当します。
FPGA内部のクロック立ち上がり立下りから、DDR2メモリが出力するデータを感じる時間は固定値であるため、FPGAのクロック速度に応じてサンプリングするタイミングを変えなければならないのです。
これは普通のDRAMや各種ICでも同じなのですが、DDR2メモリの場合は533MHzとかいう途方もない速度で送ってくるため、サンプリングできる時間の幅に余裕が少ないのが問題です。533ならば90°クロックでサンプリングしていたのを400では180°クロックでサンプリング、300では270°クロックでサンプリング・・などとしなければなりません。
もしデータ線に反射でも生じてしまっていたら、さらに時間の余裕が減ってしまいます。
そこでXILINXのFPGAでは、IDELAYという便利なプリミティブがあります。これは入ってきた信号に固定の時間の遅延を与えるものです。しかも、遅延時間は0.7ns~5.4nsの間で動的に調整できるのです。
したがって、DDR2メモリからのデータは、十分に後ろのクロックでサンプリングするようにしておいて、遅延時間は手動で設定するというようにすればよいようです。
注意しなければならない点は、Virtex4ではIDELAYを入れると、何も入れない状態と比べて無条件に0.717nsの遅延が生じてしまうことです。これはDDR2の回路では4分の1周期近くに相当します。
また、FPGAの中で、0°クロックで動くフリップフロップが出力した信号を、90°クロックで動くフリップフロップの入力に入れることは、通常はできません。
なぜならばDDR2メモリを扱うような回路はすでに数百MHzで動いているので、0→90°クロックというようにフリップフロップをつなぐと、FPGAの中でクロックからの遅延とセットアップタイムを合わせて1ns以下で処理しなければならなくなります。これはFPGAに1GHzで動作しろと要求しているようなものです。
FPGAの限界近い速度で動いている回路で90°クロックを使うには、270°クロックと180°クロックを駆使して序所にタイミングをずらしていかなければならないようです。
結局のところ、DDR2メモリのアクセス回路は、フリップフロップだらけになって、遅延がものすごく大きな回路になります。バースト転送すれば早いのですが、タイミングをそろえるために遅延がいっぱいです。
| 固定リンク
コメント
なにたふさん、こんにちは。
本当にDDR2のデータをリードするのは難しいですよね。私もSUZAKU-VのDDR2 SDRAMコントローラを作ろうと思っています。
Virtex4はクロックをDCMで何倍かにするためにCLKFXを使用するでしょうから、クロックジッタにも注意が必要ですよね。
今のところ、データを遅延して内部のクロックで受ける予定ですが、ジッタが多くてだめそうだったらDQSを内部クロックと同じ位相にシフトしてデータを受けようと思っています。
あと、問題はデータをいつ受けるかということですね。リードの時のFIFOのライト・イネーブルをいつ出すかというのがいつも頭の痛いところです。
投稿: marsee | 2007.12.15 05:46
marseeさんこんにちは
ほんと、DDRやDDR2のデータをリードするのは難しいですね。
こうしてFPGAで悩んでいると、パソコンのマザーボードは凄い!って思います。DIMMを何枚もさすので反射もすごいでしょうし。
いまやっているのはハイビジョンの試験装置なのですが、DCMを2段くらい重ねて約150MHzのクロックを作って、約300MHzでゆっくり(?)とDDR2を動かしています。
CLKFXは使用していますが、目に見えるようなジッタはありませんでした。
しかし次の案件では、DDRに533MHzを使うことが決定しているので、メモリコントローラを使いまわそうということでクロック可変で設計している次第です。
パソコンのチップセットなんかはきっとDQSで見ているのでしょうね。こんどChipSyncで自動でディレイを調整するというのにも挑戦してみようと思います。
>FIFOのライト・イネーブルをいつ出すかというのがいつも頭の痛いところです。
リードのイネーブル信号は、10段くらいのシフトレジスタを作っておいて、リード開始時に最初の4個をセットします。
すると、8段目くらいの適当なビットがFIFOのライト・イネーブルにぴったりのタイミングになるはずです。こうすると任意の長さのバースト転送にも対応できますし、回路構成の変更にあわせてカスタマイズが楽になります。
CAS  ̄|_| ̄ ̄ ̄ ̄ ̄ ̄ ̄
0 ___| ̄|_______
1 ___| ̄ ̄|______
2 ___| ̄ ̄ ̄|_____
3 ___| ̄ ̄ ̄ ̄|____
4 ____| ̄ ̄ ̄ ̄|___
5 _____| ̄ ̄ ̄ ̄|___
6 ______| ̄ ̄ ̄ ̄|___
7 _______| ̄ ̄ ̄ ̄|___
8 ________| ̄ ̄ ̄ ̄|___
このあたりでちょうど↑データが取れているはず
投稿: なひたふ | 2007.12.15 07:26
Virtex-2ではCLKFXのジッタを計算したら、驚くほどの値だったと思います。Virtex-4では、ジッタの値がタイミングアナライザに統合されているようですね。 ns; を入れて、ジッタを考慮したほうがよいかも知れません。
高周波では、UCF ファイルに「SYSTEM_JITTER =
>リードのイネーブル信号は、10段くらいのシフトレジスタを作っておいて、リード開始時に最初の4個をセットします。
データを遅延して、FPGAのクロックで受ければ、これでOKですね。
私は4つのシフトレジスタを用意して、値によって、どの位置でデータを取るかを検査しようと思っています。どの位置になるかは、DDR2との配線路長でも違ってくると思われます。
FIFOのライトイネーブルの出し方はなひたふさんの方法か、カウンタになると思います。
投稿: marsee | 2007.12.15 21:17
>私は4つのシフトレジスタを用意して、値によって、どの位置でデータを取るかを検査しようと思っています。どの位置になるかは、DDR2との配線路長でも違ってくると思われます。
以前そういう回路を設計をしたことがあります。
N個の(20≦N<30)ICが、高速シリアル信号(約300MHz)を出してきて、それをFPGAでデコードするというものです。
各ICとFPGAとの配線長はばらばらなので、データの到達時間は全くばらばらです。
これをVirtex4のIDELAYとISERDESでなんとかデコードしなければなりません。
やり方は、最初に高速シリアルICが、
| ̄|________| ̄|________| ̄|________
みたいな周期的なテストパターンを出力するようにしておいて、それをIDELAY=0で受け取り、ISERDESでデコードします。
そして、正しく受け取れていれば○、複数回の試行でデータが変化するようならば×とします。
次に、IDELAY=1にして、同じことをやります。
このようなことを64回繰り返して、IDELAY=0~63までのデータを全て取ります。そうすると、
××○○○○○○○○○○××○○○○○○○○○○××○○○○○・・・
という感じで周期的に×と○が繰り返します。
例えば、IDELAY=15付近と、IDELAY=45付近で×だとすると、IDELAY=30の点がベストな点ということになります。
こんな面倒なことをステートマシンでやって、FPGAの中に20数回路分入れたのですが、Virtex4なためか、ほとんどリソース増にはなりませんでした。
たぶん、ChipSyncを使うと同じようなことを自動的にやってくれるのだとは思います。
似たような回路をSpartan3で作ったときには、IDDRとか90°クロックを駆使して、一番綺麗に波形が取れるところを自動で選択するようにしたと思います。
投稿: なひたふ | 2007.12.16 22:31