今日はPCI Express IPコアとは別に、DDR2 SDRAMのコントローラを作っています。
使っているSDRAMは、エルピーダのEDE5116ABSEというものです。
Virtex4用にDDR2 SDRAMの制御回路をざっくり書いて、実機にFITして動かしてみたのですが、論理合成するたびにDQSの信号をハイインピーダンスにするタイミングなどが若干変わってしまったり、FPGAの出力DDRプリミティブからデータを出力するときに、望んだタイミングに出てこなかったり、という具合でした。
どうやらFPGA内部のロジックセルや配線による遅延による影響が無視できない回路になっていて、ハイインピーダンスにするタイミングなどに問題が生じていました。
これでは、クロック速度に依存してしまう設計になって、よくありません。
というわけで、今夜は家に持ち帰って、詳細なタイミングを書き出して検討しています。
DDR2 SDRAMはだいたい125~400MHzくらいのクロックで動作します。FPGAの内部も同じく125~400MHzくらいで動かすことになります。データ転送レートはその2倍になります。一般的には、データレートは300MHz~666MHzくらいで動かすことになるでしょう。
ですが、DDR2 SDRAMといっても、中身はただのDRAMです。
バンクをアクティブにして読み出してプリチャージして再びアクティブにする、というサイクルの時間は大昔のDRAMのころからあまり変化していないのです。
そのかわり、ただのDRAMとは違ってバースト転送やバンク切り替えができるので、これらをうまく使えば高速にアクセスできるわけです。
ところが、DDR2 SDRAMではバースト長が8までしか対応できません。1つのコマンドでバンクの中身を全部吐き出すということができないのです。
このことを考慮して、533MHzでの動作タイミングチャートを書いてみました。

4つのバンクを順にプリチャージ付きで、バースト書き込みする場合のタイミング図です。
DDR2 SDRAMを533MHzで動かすということは、クロックは266MHzなので1クロックは3.75nsです。
バンクをアクティブにしてからWRコマンドを入力するまでの時間、つまりtRCDは15ns以上なので、4クロック後にしなければなりません。しかし、DDR2 SDRAMでは、Additive Latencyという機能が追加されたので、3クロック目に入れることができます。そうすると、3クロック目に入れられたWRコマンドは実際には4クロック目に解読されて、6クロック目から9クロック目までデータを入力することになります。
書き込み完了からプリチャージまでは15nsあけなければならないので、プリチャージは最短で14クロック目のところになります。プリチャージから次のアクティブコマンドまでは15nsあけなければならないので、同一バンクを再度アクティブにするには18クロックかかることになります。
つまり、533MHz動作ならライトプリチャージでどんどんデータを書き込んでいった場合、18サイクルかかってしまいます。バンクは4つしかないですから、2サイクルのアイドル状態がでてしまいます。
これでは、実効レートが16/18=88%に下がってしまいます。
ただのSDR SDRAMの場合は、バンクを切り替えバーストさせながら切れ目なく読み出せていたので、ちょっと困惑です。DDR2 SDRAMというのはこういう感じなのでしょうか。
実効レートが下がるのを回避するには、どうしたらいいんでしょう。
例えば、バンクをオートプリチャージせずに連続してコマンドを与えていくとか・・。
考えてみれば、tWRとtRPがそれぞれ15nsかかるのが厳しい原因のようです。
これは仕方ないですね。
この制限のもと、「毎回ライト・プリチャージ」というしばりを加えて、タイミングチャートとにらめっこしながらパズルを解いてみると、400MHz動作ならばOKという結論になりました。

FPGAの中から外に出ると、およそ1~2nsくらいの遅延が生じるので、そのことを考慮にいれます。
上の図は400MHz動作ですが、見事なまでに綺麗なタイミングでアクセスできることがわかりました。
すべてのパラメータがぴったりと一致します。
ですが、バンクが頻繁に活性化したりプリチャージするので、消費電力が大きそうですね。
なんだか、オートプリチャージなしのバーストコマンドを与えるのがよいような気がしてきました。
最後に、DDR2 SDRAMは、DDR SDRAMと同様にDQSという信号があります。
DQSはクロックとほぼ同じ位相で出力すればよいのですが、FPGAから出力したデータ(DQ)をDDR2 SDRAMがサンプリングする点は、DQSのエッジであるため、DQSとDQは僅かにタイミングをずらさなければなりません。
とはいっても、DQSもDQSも、266MHzクロックをDDRして作る信号です。1.875nsごとに変化します。
DQが確定してからDQSのエッジまでの時間は、937.5psがベストです。
こういった信号を作るには、FPGAの内部で90度位相のずれたクロックを使う必要があります。
つまり、
0度・・DQSを変化(下げる)
90度・・DQを変化(データの表)
180度・・DQSを変化(上げる)
270度・・DQを変化(データの裏)
これを繰り返すわけです。90度というのは、266MHz(533)動作なら937.5psに相当します。
さて、これを単純にFPGAの中で
process(CLK90) begin
if(CLK90'event and CLK90='1') then
とか、プリミティブのODDRのクロックにCLK90を入れると、まず間違いなくタイミングエラーを起こします。
なぜなら、0度のクロックで作った信号を90度のFFでサンプリングするということは、4倍の速度で動けといっているようなものだからです。FPGAのクロックが266MHzならば、普通の信号を90度のクロックでサンプリングしなおすのは1066MHzで動くのと同じです。
これはさすがのVirtex4でも無理でしょう。
そこで、CLK0で作った信号を、CLK270を入れたD-FFでサンプリングし、CLK180を入れたD-FFでサンプリングし、CLK90を入れたD-FFでサンプリングする、というように3段のD-FFを入れる、というテクニックを使います。こうすれば、各D-FF間は270度分の位相のずれしか生じないので、何とかタイミングレポートが通るようになります。
最近のコメント