Spartan-3A スタータキット

〜DDR2メモリを使いたい〜


2007/07/15

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

えーと,実はまだDDR2メモリはまともに動いていないのだけど, とりあえずこのへんで一旦整理してみようかと思うので, メモ書きがてら書いてみた. なので以下で紹介しているソースはまともに動かないので注意, と前もって書いときます.

まあ実はDDRコントローラについては(ていうかほとんどのコントローラについては), ISE WebPACKのウイザード機能で作成することができるようだ. これを使えば,microblaze からコントローラとして使えるようなHDLを 自動的に生成してくれるみたい. でもそれじゃつまらんし勉強にならんので,自分でぜんぶ書いてみる.

で,DDR2メモリなのだけど,なんか詳しい資料があるようであまり無い. まあチップのデータシートを読めばいいのだけど,まずは予備知識がほしいので, とりあえず日本語の資料は何かないかなーと探してみた.

とりあえず,役に立った順に.

とりあえず Interface 2007/03 号の5章と7章を何度も何度も何度もわかるまで 熟読すれば,SDRAMとDDR-SDRAMについてわかるようになるとおもう. DDRはSDRAMの高クロック対応したものなので,まずはSDRAMについて知るとよい. んでDDR-SDRAMについてわかれば,DDR2-SDRAMも似たようなものなので大丈夫.

まずはInterface2007/03をよく読んで概要を知る. 次に,それだけでは初期化の細かい手順やレジスタに設定する値が わからないので,チップのデータシートをよく読む.

チップのデータシートだが, これは Spartan-3A スタータキットのユーザーガイドのDDR2の Related Resources の ところに

http://download.micron.com/pdf/datasheets/dram/ddr2/512MbDDR2.pdf

というように紹介されている micron のホームページからダウンロードする. ほかにもこの micron のホームページからはサンプルのHDLがダウンロード できるのだが,なんか読んでもよくわからなかったのでまあ気にしない.

で,上記ページからダウンロードできるデータシートなのだけど,

の3種類のチップに対しての説明になっている. これらはバンク構成が違うため,ロウ・アドレスとカラム・アドレスの指定方法が 異なるのだが,容量的にはすべて512Mbit(=64Mbyte)となっている. Spartan-3A スタータキットに積まれているチップは, スタータキットのユーザーガイドによれば MT47H32M16 なので, 8M × 16 × 4bank ということになる. データシートの1ページ目に書いてあるが,MT47H32M16 は ロウ・アドレスが8k,カラム・アドレスが1kになっている. よって8k×1k=8Mのアドレスを持てる. データバスが16bitなので,アドレスひとつで16bitのデータを所持できることになる (このため1ワードは16ビットということになる.以下では1ワード=16ビットとして 説明する)ため,8M(アドレス) × 16bit × 4bank で 512Mbit ということになる.

さらにデータシートを読むと, MT47H32M16 にもクロック耐性に応じて以下の亜種があることがわかる.

データシートの最後のほうには様々なタイミング値の範囲の表があるが, これらのタイミングは上記種別によって変わってくるので, これらの種別は意識する必要がある.しかし困ったことに, Spartan-3A スタータキットに積まれているDDR2メモリがどの種別なのか, スタータキットのユーザーガイドには載っていない (回路図では MT47H32M16CC-XXとなっている). Xilinkのページとかを調べてもみたのだが, とくに書いていないようだ.チップ表面にもとくに書いていない.なんてこった. 困った困った.

で,この種別なのだけど,データシートをよく読むと, http://www.micron.com/decoder にアクセスしてチップ表面の刻印の番号を入れることで,クロック耐性を 教えてくれることがわかる(データシートの Part Numbers の章に載っている). 参考までに,ぼくの持っているスタータキットでは チップの刻印は

4xF3
6VBII
D9DCG
となっている. で,上記ページの FBGA Code の欄に D9DCG を入れてサーチしたところ, 型番は
MT47H32M16CC-3:B
と出てきた.最後の :B はリビジョン番号(このことも,データシートに載っている) なのでとりあえず気にしないとして,クロック耐性は -3 なので DDR2-667 に相当する ことがわかる.これについてはスタータキットのロットによっては異なるチップが 乗っているかもしれないので,各自調べてほしい.

DDR2-667なので667MHzという高クロックが必要に思えるが,実際にはクロックの 立ち上がりと立ち下がりの両方が利用されるので, 必要な周波数は半分の333MHzということになる. ちなみにDDR2なのでプリフェッチ数が4のため,内部バスクロックはその半分の 166MHzとなる.まあこれについては気にする必要は無いのでどうでもいい.

ここで再度困るのは,Spartan-3A スタータキットのクロックは50MHzであるという ことだ.いままでそれでHDLを書いてきたし, VGAの水平同期とかも50MHzから分周して作った. 25MHzとかなら分周して作れるのだけど,333MHzってどうやって作るんだ? ていうかそもそも作れるの?

データシートの最後のほうのタイミング値の表を見ると, クロック周期であるtCKの範囲は(CL値によって最小値は変化するが)3000〜8000ps となっている.これは周波数にすると 125MHz〜333MHz となる. うーん困った.いちおう低いほうで125MHzとなっているが,50MHzで動作しない もんだろうか.もしかしたら動くかもしれないし,ダメかもしれない. まあやってみないとわからないだろう.

50MHz以上のクロックを得る方法なのだけど, 実はスタータキットのユーザーガイドのDDR2の章を見ると, ループバックしている回路があって, これを使ってなんかできるらしい. というのは Spartam-3A スタータキットのユーザーガイドには, このループバック回路のことはとくに詳しくは書かれていないのだけど, Spartam-3E スタータキットのユーザーガイドには,ループバック回路について, DCM(デジタル・クロック・マネージャ)で利用する旨の説明がちらっと書いてある. まー結論から言ってしまうと,DCMを使うことで高クロックは生成できて, それをDDR2に印加する際の遅延の補正をするためにこのループバック回路が 利用されるのだけど,今回紹介するコードを書いているときはとくに知らず, 今回のコードはとりあえず50MHzで動作することを期待して書いてあるので, とりあえずまあ説明しない.

で,作成したのがこんな感じ.

main.v
ddr2.v
rx.v
tx.v
s3astarter.ucf

ddr2.vはDDR2の操作をするためのコード,tx.v,rx.vはシリアル送受信のコード, そしてmain.vがそれらを統合して,全体としての状態遷移を行って動作するための コードになっている.

シリアル経由で以下のコマンドを入力することで,DDR2のリード・ライトを行う.

例えばシリアルから「$W000000101234abcd+」を送信すると, DDR2の0x00000010というアドレスに0x1234abcdというデータを書き込み, 「OK」を返してくる. さらに「$R00000010+」を送信すると,DDR2の0x00000010というアドレスのデータを 読み込み,16進表現にして返してくる.

で,実行してみたのだけどうまくいかない. シリアルで繋いでWコマンド送信すると,「OK」とかはちゃんと返ってくるので, シリアルの送受信はうまくできているし,ステートマシンもきちんと動作している ようだ. しかし書き込みの後に同一アドレスの読み込みを行っても,まともなデータが 返ってこない.原因としては以下が考えられる.

で,デバッグを進めているのだが,いまいちうまく動作してくれない. そもそも読み込みがまずいのか書き込みに失敗しているのかわからんので デバッグ場所を絞り込めないし,ハードのデバッグはなにげにたいへんだなあと実感.

以下,補足として,今回紹介した資料 (主にInterface2007/03号とチップのデータシート) だけではよくわからん部分(正確には,ぼく自身がよくわからなかったため 必死こいて読んで理解した結果のメモ書きの内容)を追加説明しておく.

Interface 2007/03 第5章に対する補足

p.96「表2 SDRAMのコマンド」でBA,APというピンがあるが, BAはバンクアドレス,APは「オートプリチャージ」の指定ピンのこと. ちなみにAPにはDDR2ではアドレス線の10番ピン(A10)が割り当てられている. カラムアドレス指定時には,A10がオートプリチャージの有無の指定ピンとなる.

Interface2007/03第7章に対する補足

p.131「図5 DQSのタイミング」 SDRAMではwriteコマンドとデータの発行を同時に行っていたが, DDRではCL-1の遅延の後,データを発行する. つまりリード時のレイテンシはCLだが,ライト時のレイテンシはCL-1になる.

DDR2のリード時はDQSは(メモリからの)出力だが, ライト時はDQSは(メモリへの)入力になる. つまりDQSは双方向信号である.

p.133「図7 DDR-SDRAMの状態遷移」の状態遷移(プリチャージとか,アクティブとか) は,どうもバンク毎にあるようだ.

p.134「DDR-SDRAMのリフレッシュ・サイクルはSDR-SDRAMの半分」とあるが, SDRでは15.6us(p.96参照)なので,DDRではその半分の7.8usになる. これは周波数だと128kHzになる.

「表2 SDR-SDRAM,DDR-SDRAM,DDR2-SDRAMの仕様の比較」で DDRは「プリフェッチ」が2となっているが,これは1クロックで同時に2ワードを 内部でリードしておいて,クロックの立ち上がりと立ち下がりの両方を使って 2倍の転送速度でデータを出力する,ということ. メモリの内部動作クロックはあまり高くできないので,並列に動作させることで (内部クロックは同じままで)外部クロックを高くしている. DDR2ではプリフェッチ数が4なので, (内部クロックは同じだが)DDRに対して2倍の速度でデータ転送できる.

p.135に「データ転送ストローブ信号の作動信号化」とあるが, DQSに対して逆相のDQS#も使う,ということ. DDRではクロックCKに対して逆相のCK#も利用しているが, こーいうのを「作動信号」という. またDQS#を利用するかどうかはモード設定で選択できるようになっているが, デフォルトでは有効になっているようだ.

p.135 DDR2ではバースト長は4または8とあるが, Spartan-3A スタータキットではDDR2のデータのバス幅が16bitなので, バースト長が8だと16bit×8=16バイトが1回のバーストでリード/ライトできる.

p.135「オン・ダイ・ターミネーション」 DDR2ではメモリのチップが終端抵抗を内蔵している. これはODT(On-die termination)というピンと, DDR2が持っている拡張モードレジスタ(EMR)の設定によって使用・未使用を 選択できるようなのだが, Spartan-3A スタータキットの回路図を見た限りではボード上で終端されている ようなので,設定は不要. (スタータキットのユーザーガイドのDDR2の章にも, 「全ての信号線はターミネートされている」という記述がある)

p.135 「ポステッドCASと付加レイテンシ」 Additive Latency (AL) のこと. CAS Latency (CL) にさらにALが加えられたぶんだけ遅延する. 実際にはALのぶんだけ遅延した後,コマンドが実行される (なので「Posted CAS Additive Latency」という名前になっている). コマンドの実行を遅らせることで,なんかメリットがあるのだろうきっと. (コマンドの打ち消しができるとかかしら) ALについてはデータシートp.26に説明がある.

データシートに関する補足

スタータキットに搭載されているDDR2メモリはデータ線が16bit幅なので, 上位8bitと下位8bitのそれぞれについてDMやDQSを持っている. このためDMについてはLDMとUDM,DQSについてはLDQSとUDQSという信号線を持っている. これにより,上位8bitと下位8bitを別個に操作できるようになっている.

リードの際にはDQSのエッジと データ信号のエッジが揃えられる. ライトの際にはDQSのエッジにデータ信号の中央が揃えられる. このため位相が90度ずれたクロックが必要になってくる. これに関してはDCMでまた考える.

Figure7 に初期化のタイミングチャートがあるが, 図中のtRPAやtMRDなど値については,p.116以降のTable48,49を参照. また初期化中はDQS,DQはハイインピーダンス状態にする必要があるらしい. 具体的な初期化処理の内容については図以降のNotesを参照. ちなみにNotesの13で,BA1=1,BA0=0となっているが, おそらくBA1=0,BA0=0の間違いと思われる.

p.20 Burst Type に 「however, sequential address ordering is nibble-based.」 という記述があるが,これは 「例えば本来の意味で『シーケンシャル』ならば,次ページの Table4の(A2,A1,A0)=111の場合には,7,0,1,2,3,4,5,6という順番になるべきだが, nibble-basedなので4ワード単位に区切られ,7,4,5,6,3,0,1,2という順番になる, という意味. nibbleは4を表す(リンゴとか噛んだときの歯型が4本なことが語源だとか)」 そう考えると,バースト順番はsequentialよりもinterleavedのほうが 規則的であるともいえる. ちなみにTable4は,アドレスに端数がある場合 (バースト長でアラインメントされてない場合)のバースト順番を表す. ちなみにinterleavedは以下のアルゴリズムで生成できる.

p.24 AL(Additive Latency)はEMRで設定できる.

p.25 EMRの設定で Output Drive Strength というのがあり, 出力する信号レベルを指定できるようだ. Interface2007/03のp.135によればDDR2の規格としてはSSTL-1.8が採用されている ようなので,この設定はデフォルトのままでたぶん大丈夫. ちなみにMRやEMRの設定値は,基本としてビットゼロがデフォルトのようだ.

p.25 EMRでDQS#を使うかどうかの設定ができるが, DQS#を使わないならば,DQS#は未接続になっていなければならないらしい. スタータキットでは,DQS#は接続されてしまっているので, DQS#の設定は「enable」にする必要有り. (まあハイインピーダンスにして浮かせてしまう,という方法もあるが)

p.26 Figure11中の「BL」は「Burst Length」のこと. MR(モードレジスタ)で設定可能.

p.27 Figure12中の「WL」はライト時のレイテンシ(Write Latency)のことで, WL = RL - 1 になる(ちなみにRLはリード時のレイテンシ(Read Latency)のこと). ちなみに
RL = AL + CL
WL = AL + CL - 1
となる.ALがゼロならば,ライト時には CL - 1 のレイテンシが必要,ということだ.

バンクとロウ・アドレスを有効化するのが「アクティベート」もしくは 「アクティブ・バンク」である. バンクをクローズするのが「プリチャージ」. ロウ・アドレス変更時にはプリチャージと再アクティベートが必要. オートプリチャージが有効だと,read/write後に自動でプリチャージされる.

DDRとDDR2は,外部から見たインターフェースは (ODTピンの有無やDQSの作動信号化などを除けば)ほとんど変わらない. ただしDDR2は内部で4プリフェッチになっているので,高クロックまで耐えられる. つまりDDR2は(細かい部分が微妙に異なったりはするが,基本的には) 「高クロックまで耐えられるDDR」と考えてもよい.

リードとライトのタイミングチャートは,DDRもDDR2も同じように思える. DDRに比べてDDR2ではプリフェッチ数が倍(DDRでは2,DDR2では4)なので, 高クロックでデータの送受信が行えるため高速,ということのようだ. つまりDDR2は高クロックまで対応できるだけで, タイミング的にはDDRもDDR2も変わらない.

SDR DDR DDR2
内部バスクロック133MHz133MHz133MHz
外部クロック 133MHz133MHz266MHz
データバス速度 133MHz266MHz533MHz

上記は内部バスクロックが133MHzの場合だが, DDRでは内部クロックと外部クロックが等しいが, 実際にはクロックの立ち上がりと立ち下がりの両方を利用する (このためプリフェッチが必要)ので,データバス速度は倍の266MHzとなっている. これに対してDDR2では,プリフェッチ数をさらに倍にして 外部クロックを2倍にすることで,データバス速度を4倍の533MHzにしている.

DRAMはコンデンサの集合体なので,内部クロックはあまり高くできない. このため同時に2ワードをプリフェッチしてクロックの裏も使って入出力するのがDDR. さらに4ワードをプリフェッチして,倍の外部クロックでも追いつけるようにしたのが DDR2. このためDDRとDDR2のリード/ライトのシーケンスは基本的に同じであり, 倍クロックまで印加できることと,高クロック耐性を上げるための対処 (DQS#とか)が入っているのがDDR2の違いになっている.


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