Xilinx Memory Interface Generator (MIG) による DDR2 SDRAM のアクセス のバックアップソース(No.4)

更新

[[公開メモ]]

#contents

* 一旦公開中止 [#v3888636]

このページに書かれていた内容で大間違いをしていたかもしれないので、~
確認が取れるまで一旦公開を中止します。

//
//* 概要 [#v3e85f93]
//
//以下の内容はまだ試行錯誤中のもので、間違っている可能性が多分にあります。
//
//紛らわしい記事ですみません。
//
//一応、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|32|
//|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 はその中から適当なピンを選んでコアを生成します。
//
//もちろんそれでは困るのですが、
//どうしようもないので後で直すことにして、
//ここではそのままにしておきます。
//
//ちなみに、このページの [Read UCF File] は興味を引くボタンなのですが、、、
//
//他の用途に使っているためにメモリとの配線に使えないピンを Reserved Pins 
//として登録するためのもので、メモリとの配線方法を指定するためのものでは無いので、
//残念ながら押しても役に立ちません。
//
//** Bank もこの時点では気にしない [#d099ae7e]
//
//MIG は Available Pins から適当なピンを選んで信号線を割り当てますが、
//このページでは信号線の種類毎に、使う Bank を指定することができます。
//
//&attachref(mig4.png,,50%);
//
//繰り返しになりますが、この時点ではピン配置を気にする必要は無いので、
//すべてのピンが割り当てられるまでチェックを増やしていけばOKです。
//
//** コアを生成する [#m28d5b83]
//
//どんどんページをめくって、最後にライセンスを承諾するとコアが生成されます。
//
//** ピンを指定するための ucf ファイルを作る [#j3b09d33]
//
//ここからいよいよピン配置を指定する段階です。
//
//私の場合 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 
//が最初に提案したピン配置に最適化されているのでそのままでは動きません。
//
//そこで、もう一度 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 (ピンを指定するための自分で作ったファイル)~
//を指定します。
//
//Next を連打して、もう一度ライセンス条項を許諾すると、
//指定したピン配置でコアを生成できます。
//
//** 正しいピン配置になっているかどうか確認する [#n22a8f15]
//
// LANG:console
// $ grep "#Bank" ipcore_dir/ddr2mi/user_design/par/ddr2mi.ucf | sort > ddr2mi_pins.ucf
//
//としてみると、指定した通りのピン配置でコアが生成されていると思います。
//
//* MIG が生成したコアを使って Spartan 3A DSP から DDR2 メモリにアクセスする [#p0f9bc5f]
//
//まだ準備段階です。
//
//Spartan 3A DSP 1800 Starter Platform には Micron の 16bit 幅で 512Mbit の 
//DDR2 SDRAM である [[MT47H32M16BM-3>http://www.micron.com//document_download/?documentId=455]] が
//2つ載っていて、合計で 32bit 幅 1024Mbit の構成になっています。
//
//DDR2 メモリには最低動作周波数が規定されていて、このチップでは 125MHz となっているため、
//Spartan 3 ではちょっと厳しめですが、この周波数でデータの受け渡しをしなければなりません。
//
//また、MIG のインターフェースは元クロックと 90度 および 180度 
//位相の異なるクロックを利用してデータの受け渡しをするように設計されていて、
//そのあたりもちょっとハードルが高いです。
//
//とはいえ、考え方が分かってしまえば、高速回路設計の勉強にもなっていい感じです。
//
//(まだ実機で動かせるところまで進んでいませんが)
//
//** メモリの構成 [#i33d0468]
//
//合計 1024Mbit で 32bit 幅なので、アドレス空間は 0x0000000 - 0x1ffffff の 25ビット幅になります。
//
//ddr2mi_parameter_0.v を見ると
// LANG:verilog
// `define   ROW_ADDRESS                              13
// `define   COLUMN_ADDRESS                           10
// `define   BANK_ADDRESS                             2
//
//となっていて、合計値は正しく 25 ビットになっていました。
//
//** モードレジスタの値 [#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: 55396 (from 2010/06/03), today: 2, yesterday: 0