DDR SDRAM コントローラを作った
先日復活した Spartan-3E Starter Board には DDR SDRAM が載っているので、これを読み書きする回路を自作してみました。
コードは例によって github.com に push しておきましたが、だいぶ完成度が低いスパゲッティ回路なので、 参考にはされないほうがよいと思います。
概要
Xilinx の FPGA で SDRAM を使いたければ、 Memory Interface Generator で SDRAM コントローラのハードマクロを生成するのが定石なのでしょうが、 今回はデバイスや ISE の各種ツールおよびシミュレータ (ISim) の勉強を兼ねて自分で RTL の回路設計をやってみました。 とはいっても VHDL を気のむくままに書きなぐり、 動くようになるまでいじくりまわしただけなので、 回路設計と言えるようなことはしていません。
1 週間ほど資料を読みあさっていじくった結果、 非常に素朴な何の工夫もない SDRAM コントローラが ISim 上で動くようになりました。 ストローブ信号 1 回ごとに必ず RAS/CAS アドレス設定をして、 バースト長が 2 固定のオートプリチャージつき読み書きを 1 回だけやります。 接続されている 512Mb DDR SDRAM MT46V32M16TG-6T はデータバス幅が 16bit なので、 だいたい 6 ないし 7 サイクル毎に 32bit のデータひとつを読み書きすることになります。 メモリ帯域は Spartan-3 Starter Board の 32bit 幅 10ns 非同期 SRAM にも劣る情けない代物です。
SDRAM コントローラを実機上で動かすためには それを使って実際にメモリを読み書きするアプリケーションも作らねばなりません。 今回はなるべく簡単にテストするためかつて Spartan-3 Starter Kit でやったように、 コンフィギュレーション PROM に格納した画像データを SDRAM に書き込んだ後、 それを読みだして VGA に出力するという回路にしてみました。
Spartan-3E Starter Board では PROM の空き領域が 234KB ほどあったので
2 ドット/バイトで 640×480×8色 の画像を詰め込むことができました。
画像は Wikipedia からの拾い物 を GIMP で減色し、
額縁部分はおなじみの /usr/include/X11/bitmaps/root_weave
を使いました。
本当は内部クロック 100MHz (DDR 200MHz) で動かしたかったのですが、 100MHz ではどうしてもまともな読み書きができず 50MHz でしか安定動作しません。 100MHz で動かすと画面にしましまが出たりします。 今後は汚い VHDL の書き直しとタイミング解析を真面目にやって 100MHz で動くようにしたいと思います。
はまった点や Tips など
- Xilinx FPGA には DDR 信号の読み書きをするための専用のプリミティブ IDDR2/ODDR2 が存在するので、これを使用する。
- DDR SDRAM に供給するクロックも ODDR2 プリミティブ経由で出力する (Clock Forwarding)。 クロックジェネレータ (DCM) の出力をそのまま SDRAM に出すと アドレス線・制御線の出力と遅延が揃わない。
- SDRAM のデータ入出力のセットアップ・ホールド時間を確保するため DQS 信号にはサブクロック (数 ns 程度) の遅延を挿入する必要がある。 今回は数段の LUT2 プリミティブを動くようになるまで適当に入れてみたが、 これでは環境や個体によって動かなくなる可能性が高い。 安定性を高めるには XAPP454 でやってるように DCM の PLL で遅延時間をクロックに同期させるといった ややこしいことをする必要があるようだ。
- Spartan-3E Starter Board において、 コンフィギュレーション PROM (XCF04S) から初期化データを読み込む D0 端子には 同じ信号線を共有する SPI バスのデバイスも接続されている。 それらをしっかりオフにする回路も FPGA に作っておかないと、 信号衝突が起きて PROM のデータを正しく読み取れない。
- Micron のページからは Verilog HDL で書かれた DDR SDRAM のシミュレーションモデルがダウンロードできる。 これと自作回路を組み合わせたビヘイビアシミュレーション (sim.vhd を参照) が設計の初期段階から非常に役に立った。 SDRAM に入力されたコマンドを表示してくれるし、 初期化手順が間違っていたりタイミングがまずかったりすれば警告してくれる。
- 同様にコンフィギュレーション PROM (XCF04S) のシミュレーションモデルも探したが、 これは見つからなかったので 0xdeadbeef を吐き続ける 32bit シフトレジスタをくっつけておいた。
- 上で作ったビヘイビアシミュレーションに対して 論理合成結果を使ったタイミングシミュレーションを SDF ファイルの遅延データのバックアノテーションつきで行うべきである。 最悪値を使った波形を見ると自分の回路が 50MHz でしか動かん理由がよくわかる。
参考にしたデータシート・アプリケーションノート
以下のリンクには PDF ファイルも含まれているので注意。
- Digilent, Inc.
- Spartan-3E Starter Board … User Guide と基板の回路図がダウンロードできる
- Micron Technology, Inc.
- MT46V32M16TG-6T … データシートとシミュレーションモデルがダウンロードできる
- Xilinx, Inc.
- DS123 Platform Flash In-System Programmable Configuration PROMs
- DS312 Spartan-3E FPGA Family Data Sheet
- UG331 Spartan-3 Generation FPGA User Guide
- UG617 Spartan-3E Libraries Guide for HDL Designs
- XAPP694 Reading User Data from Configuration PROMs
- XAPP454 DDR2 SDRAM Interface for Spartan-3 Generation FPGAs
- XAPP454.zip … VHDL/Verilog Code
- UG628 Command Line Tools User Guide
- UG660 ISim User Guide
- UG612 Timing Closure User Guide
感想
- RTL の回路設計はやはりしんどい。 ソフトウェアみたいにテキストエディタだけで設計と記述を完結させることは難しく、 正しい回路を書くにはまず方眼紙に状態遷移図や波形を描いて考えるのが結局は早道だったりする (慣れの問題かもしれないが)。 高位合成の処理系でこれがどれだけ楽になるか試してみたい。
- VHDL がしんどい。特にポートと信号の記述の繰り返しが多いのがつらい。 ベンダのサンプルやシミュレーションモデルとかも Verilog HDL で書かれたものが多い感じなので、いいかげん Verilog HDL も覚えよう。
- ISim は初めて使ったが、シンプルで使いやすく、 昔の ISE にバンドルされていた Windows 版しかない ModelSim とは違って Linux でも普通に動くので大変よかった。 ただし無料の ISE WebPACK ライセンスでは HDL 50000 行を超えると性能劣化する機能制限があるので回路が複雑になると使えないかもしれない。
- Spartan-3E Starter Board のデジタル 8 色しか出ないビデオ出力がつまらない。 また Dsub 15 ピン入力を持つディスプレイも少なくなってきたので、 HDMI でフルカラー出力できるようにしたい。 aitendo で HDMI コネクタのブレイクアウト基板というのが売ってるので、これをくっつけてどうにか信号出力するか。
2015/03/23 09:26:51 JST