Xilinx Memory Interface Generator (MIG) による DDR2 SDRAM のアクセス のバックアップ差分(No.3)

更新


  • 追加された行はこの色です。
  • 削除された行はこの色です。
[[公開メモ]]

#contents

* 概要 [#v3e85f93]

以下の内容はまだ試行錯誤中のもので、間違っている可能性が多分にあります。

紛らわしい記事ですみません。

一応、Xilinx FPGA から DDR や DDR2、DDR3 といった高速メモリにアクセスするために、
Memory Interface Generator (MIG) というソフトを使ってIPコアを生成する方法と、
生成したIPコア経由で Spartan 3A DSP から DDR2 メモリにアクセスする方法をまとめる予定です。
一応、Xilinx FPGA から DDR や DDR2、DDR3 といった高速メモリにアクセスすることを目的に、
+ Memory Interface Generator (MIG) というソフトを使ってIPコアを生成する方法
+ 生成したIPコア経由で Spartan 3A DSP から DDR2 メモリにアクセスする方法

をまとめる予定です。

詳細としては、

 Core name: Xilinx MIG
 Version: 3.3
 Release Date: December 2, 2009

を使って、

 Spartan 3A DSP 1800 Starter Platform

用のコアを作成し、その使い方について調べたものです。

* 入出力ポートを指定してコアを生成する [#c78446c5]

まずは MIG を使ってIPコアを生成する方法についてなのですが、
一見簡単そうに見えて、思ったよりも難しかったです。

+ Xilinx の Reference Board 用にコアを作る方法
+ FPGA とメモリとの間をどのように結線すべきか MIG に決めてもらう方法

は簡単に分かったのですが、Starter Platform を買った場合のように
PCBがすでにできていて、MIG が想定するのと異なるピン配置で
FPGA がメモリと接続されている場合に使えるコアを
どのように生成すればよいかが分かりにくかったので、
以下に手順をまとめておきます。

** MIG の2ページ目で [Create Design] を指定する [#r9f457ed]

MIG を起動した際の一番目の選択肢です。

&attachref(mig2.png,,50%);

最終的には Verify UCF and Update Design and UCF を使うのですが、
まだ .ucf がないので、ここでは一旦 [Create Design] を選びます。

** メモリの仕様に合わせてオプションを選択する [#me3ee50b]

Spartan 3A DSP 1800 Starter Platform 用に次のように指定しました。

自信のないところもあるのですが、、、

うまく行かなかったらまた考えます。

|Memory Selection|DDR2 SDRAM|
|>||
|Frequency|8000 ps = 125MHz|
|Write Pipe Stages|4|
|Memory Type|Components|
|Memory Part|MT47H32M16-3|
|Data Width|64|
|Data Mask|Check|
|>||
|Burst Length|4|
|Burst Type|sequential|
|Output Drive Strength|Fullstrength|
|RTT(nominal)-ODT|150ohms ?|
|DQS# Enable|Enable|
|>||
|Use DCM|Uncheck|
|Class for Address and Control|Class II|
|Class for Data|Class II|
|Debug Signals for Memory Controller|Disable|

** Available/Reserved ピンは指定しない [#c95111af]

つぎにピン配置を決めるのですが・・・

[Create Design] モードというのは、新たにPCBを起こす際に
MIG にお勧めの結線方法を提案してもらうというモードなので、
このモードではどんなに頑張っても1つ1つのピン配置を
こちらから指定することはできません。

メモリとの接続に使ってもよいピンを MIG に教えると、
MIG がピン配置を勝手に決め、その配置でコアを生成するという
話になっています。

デフォルトでは全てのピンが Available Pins に入っていて、
MIG はその中から適当なピンを選んでコアを生成します。

そういう話ですので、このモードではどんなに頑張っても
1つ1つのピン配置をこちらから指定することはできません。

もちろんそれでは困るのですが、
どうしようもないので後で直すことにして、
ここではそのままにしておきます。

ちなみに、このページの [Read UCF File] は他の用途に使っているために
メモリとの配線に使えない Reserved Pins を指定するためのもので、
メモリとの配線方法を指定するためのものでは無いので、
押しても役に立ちません。
ちなみに、このページの [Read UCF File] は興味を引くボタンなのですが、、、

他の用途に使っているためにメモリとの配線に使えないピンを Reserved Pins 
として登録するためのもので、メモリとの配線方法を指定するためのものでは無いので、
残念ながら押しても役に立ちません。

** Bank もこの時点では気にしない [#d099ae7e]

MIG は Available Pins から適当なピンを選んで信号線を割り当てますが、
このページでは信号線の種類毎に、使う Bank を指定することができます。

&attachref(mig4.png,,50%);

繰り返しになりますが、この時点ではピン配置を気にする必要は無いので、
すべてのピンが割り当てられるまでチェックを増やしていけばOKです。

デフォルトでは Address ピンの割り当てがうまくできていなかったので、
Bank1 の Address/Control をチェックすることで、
すべてのピンを割り当てました。

** コアを生成する [#m28d5b83]

どんどんページをめくって、最後にライセンスを承諾するとコアが生成されます。

** ピンを指定するための ucf ファイルを作る [#j3b09d33]

ここからいよいよピン配置を指定する段階です。

私の場合 ddr2mi という名前でコアを作ったのですが、
私の場合 ddr2mi という名前でコアを作ったので、
できたコアは以下のディレクトリにありました。

(project folder)/ipcore_dir/ddr2mi/user_design

このフォルダの par/ddr2mi.ucf に、MIG が適当に決定したピン配置と、
そのピン配置に最適化された回路を生成するための ucf ファイルが作成されています。

このファイルから #bank というコメントが付いている行を抜き出すと、
ピン配置を指定している部分を抽出できます。
ピン配置を指定している行だけを抽出できます。

unix ライクなコンソールが使えれば、

 LANG:console
 $ grep "#bank" ipcore_dir/ddr2mi/user_design/par/ddr2mi.ucf | sort > ddr2mi_pins.ucf

とすることで、

ddr2mi_pins.ucf
 NET "cntrl0_ddr2_a[0]" LOC = "J21" ;     #bank 1
 NET "cntrl0_ddr2_a[10]" LOC = "B2" ;     #bank 3
 NET "cntrl0_ddr2_a[11]" LOC = "H7" ;     #bank 3
 NET "cntrl0_ddr2_a[12]" LOC = "G6" ;     #bank 3
 ...
 
 NET "cntrl0_ddr2_dqs_n[6]" LOC = "J4";     #bank 3
 NET "cntrl0_ddr2_dqs_n[7]" LOC = "J6";     #bank 3
 NET "cntrl0_rst_dqs_div_in" LOC = "G4";     #bank 3
 NET "cntrl0_rst_dqs_div_out" LOC = "F5";     #bank 3

のようなファイルができます。

これを自分のボードに合わせて編集し、正しいピンを指定します。

** ucf ファイルを元にコアのピン配置を変更する [#g2034423]

指定したピン配置を元に、FPGA 内部のプリミティブの配置も変更しなければ
ならないのですが、手作業では無理なので、もう一度 MIG を起動してコアを再生成します。
上記の手順でピン配置だけを変更しても、FPGA 内部のプリミティブ配置は MIG 
が最初に提案したピン配置に最適化されているのでそのままでは動きません。

そこで、もう一度 MIG を起動してコアを作り直します。

Design ペインの Hierarchy で先ほど生成した ddr2mi をダブルクリックして MIG を起動します。

&attachref(mig6.png,,50%);

今度は [Verify UCF and Update Design and UCF] を選択し、~
Load Prj File に ipcore_dir/ddr2mi/user_design/mig.prj ~
Load UCF File に ddr2mi_pins.ucf ~
Load UCF File に ddr2mi_pins.ucf (ピンを指定するための自分で作ったファイル)~
を指定します。

Next を連打して、もう一度ライセンス条項を許諾すると、
指定したピン配置でコアを生成できます。

&attachref(mig6.png,,50%);

** 正しいピン配置になっているかどうか確認する [#n22a8f15]

 LANG:console
 $ grep "#Bank" ipcore_dir/ddr2mi/user_design/par/ddr2mi.ucf | sort > ddr2mi_pins.ucf

としてみると、指定したとおりのピン配置でコアが生成されていると思います。
としてみると、指定した通りのピン配置でコアが生成されていると思います。

* MIG の生成したコアを使う [#p0f9bc5f]
* MIG が生成したコアを使って Spartan 3A DSP から DDR2 メモリにアクセスする [#p0f9bc5f]

まだ準備段階です。

ボードに載っているメモリは Micron の [[MT47H32M16BM-3>http://www.micron.com//document_download/?documentId=455]] だそうです。

DDR2 メモリには最低動作周波数が規定されていて、このチップでは 125MHz となっているため、
Spartan 3 ではちょっと厳しめですが、この周波数でデータの受け渡しをしなければなりません。

また、MIG のインターフェースは元クロックと 90度 および 180度 
位相の異なるクロックを利用してデータの受け渡しをするように設計されていて、
そのあたりもちょっとハードルが高いです。

とはいえ、考え方が分かってしまえば、高速回路設計の勉強にもなっていい感じです。

(まだ実機で動かせるところまで進んでいませんが)

** モードレジスタの値 [#w267ac5a]

ddr2mi_parameter_0.v によれば、
 LOAD_MODE_REGISTER                       13'b0010100110010

となっていますので、これをメモリのデータシートと突き合わせると、

&attachref(mode_reg.png);

|項目|値|意味|
|Mode Register Definition|00 | Mode register (MR)|
|PD Mode|0| Fast exit|
|Write Recovery|010 | 3|
|DLL Reset|1 | Yes|
|Test Mode|0 | Normal Mode|
|CAS#|0||
|CAS Latency (CL)|11 | 3|
|Burst Type|0 | Sequential|
|Burst Length|010 | 4|

という設定であることが分かりました。
という設定であることが分かります。

* メモ [#s277dbef]

- Invalid property "SYN_USEIOFF 1" というワーニングは XST が Synplify 用の制約である SYN_USEIOFF を認識できないために出るものなので、無視して良さそうです。

* コメント [#h67dcb11]

#article_kcaptcha


Counter: 55356 (from 2010/06/03), today: 2, yesterday: 0