2012年6月17日日曜日

Spartan6版 DDR2コントローラの作成 7


今回作成したコントローラのRTL等一式を以下に置いた。
http://www.hi-ho.ne.jp/bravo-fpga/


今回のDDR2-800用DRAMコントローラは800MHzという高速で動作させるためにSpartan6のISERDES2, OSERDES2, IODELAY2等のハードマクロを使用した。 そういう意味では800MHzで動いて当たり前と言えるかも知れないが、このコントローラの作成を通してこれらマクロのクセや使い方を学習することが出来た。その辺について幾つか書いておく。

今回作成したコントローラのPHYの基本的部の構造を以下に示す。 128bit版ではこの上位で100MHz/128bitと200MHz/64bitの乗替えがあるが、これは普通のverilog記述にしている。


今回は点線で囲っている範囲をdc_ddrioというmoduleにして、これをDDR2 SDRAM I/Fの全ての信号(クロック、コマンド系、データ系)で使用している。当初は、コマンド系は400MHzのレートの出力なのでIOB内のOFFを、クロックはODDRを、それぞれ使うつもりでいたのだが、OFFやODDRを通る経路とIODELAYを通る経路(データ系)の遅延差が大きい(つまりスキューが大きい)ことが判ったので、これを回避するために全信号でdc_ddrioを使うことにした。

OSERDES2
I/O SERDES2, IODELAY2はSDRモードとDDRモードでの動作が可能だが、本コントローラではSDRモードで使用しており、そのため、供給クロックはデータレートと同じ800MHzとなっている。
何故、DDRモードにしなかったかと言うと、OSERDES2がSTROBE信号をクロックの両エッジでサンプリングしてしまうからだ。 以下はXilinxのUG381に載っているOSERDES2のブロック図だ。



これによると、IOCE(STROBE)パルスが1の時(正確には1段F/Fを通っているが)にD1~D4, T1~T4をシフトレジスタにロードし、IOCEが0の時にシフト動作を行う。 ISEのインストールディレクトリ配下(ISE_DS/ISE/verilog/src/unisim/)にはシミュレーション用の各種モデルがあるが、そこのOSERDES2.vをシミュレーションして動作を見たところ、DDRモードの場合はI/Oクロックの両エッジでシフト動作が行われることが判ったが、(IOCEが1に時の)ロード動作もクロックの両エッジで行われることが判った。これだと先頭のビットが2シンボル分出力されることになりマズい。もしかすると、これはシミュレーションモデルの問題で実物の動作は違うのかも知れないが、UG381を見てもはっきりしないためSDRモードで使うことにした。

IODELAY2
UG381によると、IODELAY2はT~TOUTも遅延制御がされるように読めるのだが、シミュレーションモデルでシミュレーションして見たところ違った。TOUTは遅延制御されないようだ。念のため、IODELAY2.vをエディタで開いて確認してみたが遅延制御されない構造になっていた。これも、実際のハードは遅延制御されるのかも知れない。アンサーデータベースも検索してみたが、情報を見つけられなかったので、遅延制御されないものとして使うことにした。これが何に関係するかというと、ライト時のDQSとDQに関係してくる。ライト時はDQSとDQは90°位相をずらす必要があるが、これをIODELAY2の出力遅延で実現しようとする場合にT系が遅延が効かないと非常に制御が面倒くさいことになってしまった。そのため、DQS系、コマンド系のdc_ddrioモジュールには800MHzを反転して入力することで、90°位相差がつくようにした。 verilogのソース上はdc_ddrioのインスタンス部でクロックを反転する形になっているが、I/OSERDESやIODELAY2はクロック入力部で正転/反転が設定できるようになっているため、RTLを合成するとその設定が変わるだけだ。



一応、これでこのプロジェクトは終わりにしようと思う。


0 件のコメント:

コメントを投稿

自作CPUで遊ぶ 25

まだ制御ソフトが完成していないので今まではスピンドルを移動するために一々簡単なプログラムを書いて移動させていたのだが、非常に面倒なのでCNCペンダント的なものを作ることにした。 右側の縦に2つ並んでいるスイッチ...