2011年10月10日

SDRAM周りの設計(5)

 気持ちよくSDRAM が動いたと思って他の箇所を直したら、全く動かなくなってしまいました。

 コメントでアクセスに問題がある事の指摘を受けたので、これも修正しましたが、ダメ。
 (どうもCS はベタLでも問題なかったようです)


 結局、データの取り込みのクロックが遅かったのが原因で、取り込みクロックを前にすると正常動作しました。
 3.5ns も前にしましたが...

 それに合わせて、チェック値も変更しました。


# wire delay(0.25ns) + SDRAM output delay(6ns) + wire delay(0.25ns)
set_input_delay -clock SDRAM_CLK -max 6.5 [get_ports DRAM_D*]

# wire delay(0ns) + SDRAM data hold(2.5ns) + wire delay(0 ns)
set_input_delay -clock SDRAM_CLK -min 2.5 [get_ports DRAM_D*]

 セットアップ側を8ns → 6.5ns にしています。


posted by えすび at 13:20| Comment(0) | FPGA化:SDRAM | このブログの読者になる | 更新情報をチェックする

2011年10月09日

SDRAM周りの設計(4)

 AC的に多分大丈夫な設計になったので、先に考えていたタイミングで論理設計を始めました。

 ...っと忘れてた。SDRAM は初期設定が必要なようなので、これも実装しました。

 SDRAM の初期設定
 1)電源投入直後は、SD_CKE = L、SD_LDQM = H、SD_UDQM = H、にする。
 2)リセット後、SD_CKE = H、SD_LDQM = L、SD_UDQM = L にする。SD_CLK にクロックを出力する。
 3)200 μs 待つ。
 4)precharge - ALL を発行する。
 5)Auto Refresh を8回以上行う。
 6)初期コマンドを設定する。設定する値は、バースト長1、CASレーテンシ2とする


 これだけ実装して、やっとSDRAM にアクセスが可能となります。


 ついでに、PC-6001 で使用するRAM に関しては、ALL 0xFF の書き込みを行います。
 ただし、リセット後にRAM に残っている値を使うソフトもあるので、書き込みを禁止するモードも設けます。


 SDRAM の試験はどうしようかと考えました。
 SDカードの時は、ロジアナで観測しましたが、SDRAM に関してはかなり面倒です。

 結局、立ち上げ時にBASICROM をSDカードから読み込んで、SDRAM に書き込む動作を利用しました。

 BASICROM のデータをグラフィックデータに変更して、VDG の参照アドレスを通常のRAMではなく、BASICROM空間を表示させました。


 かなり手こずると思ったんですが、一発で動きました(当然、シミュレーションでの確認は行っていましたが)。
 ちょっとびっくりです。



posted by えすび at 17:34| Comment(0) | FPGA化:SDRAM | このブログの読者になる | 更新情報をチェックする

SDRAM周りの設計(3)

 SDRAM 周りのACタイミングですが、どうもよくわからないので、適当に回路を組んでその結果を見る事にしました。

 FPGA → SDRAM への出力 に関しては、SD_CLK に対して、ばらつかなければ問題はありません。

 結果の一部です。

+--------------------------------------------------------------------------------+
; Clock to Output Times ;
+------------------+------------+--------+--------+------------+-----------------+
; Data Port ; Clock Port ; Rise ; Fall ; Clock Edge ; Clock Reference ;
+------------------+------------+--------+--------+------------+-----------------+
; DRAM_CLK ; CLK50M1 ; 2.027 ; ; Rise ; CLK100M ;
; DRAM_A[*] ; CLK50M1 ; 2.617 ; 2.472 ; Fall ; CLK100M ;
; DRAM_A[0] ; CLK50M1 ; 2.598 ; 2.453 ; Fall ; CLK100M ;
; DRAM_A[1] ; CLK50M1 ; 2.617 ; 2.472 ; Fall ; CLK100M ;
; DRAM_A[2] ; CLK50M1 ; 2.617 ; 2.472 ; Fall ; CLK100M ;
; DRAM_A[3] ; CLK50M1 ; 2.597 ; 2.452 ; Fall ; CLK100M ;
; DRAM_A[4] ; CLK50M1 ; 2.617 ; 2.472 ; Fall ; CLK100M ;
; DRAM_A[5] ; CLK50M1 ; 2.587 ; 2.442 ; Fall ; CLK100M ;
; DRAM_A[6] ; CLK50M1 ; 2.606 ; 2.461 ; Fall ; CLK100M ;
; DRAM_A[7] ; CLK50M1 ; 2.616 ; 2.471 ; Fall ; CLK100M ;
; DRAM_A[10] ; CLK50M1 ; 2.617 ; 2.472 ; Fall ; CLK100M ;
; DRAM_CAS_N ; CLK50M1 ; 2.577 ; 2.432 ; Fall ; CLK100M ;
; DRAM_CKE ; CLK50M1 ; 2.943 ; 2.633 ; Fall ; CLK100M ;
; DRAM_CLK ; CLK50M1 ; ; 1.899 ; Fall ; CLK100M ;
; DRAM_CS_N ; CLK50M1 ; 2.568 ; 2.423 ; Fall ; CLK100M ;
; DRAM_D[*] ; CLK50M1 ; 4.599 ; 4.234 ; Fall ; CLK100M ;
; DRAM_D[0] ; CLK50M1 ; 2.579 ; 2.434 ; Fall ; CLK100M ;
; DRAM_D[1] ; CLK50M1 ; 2.577 ; 2.432 ; Fall ; CLK100M ;
; DRAM_D[2] ; CLK50M1 ; 2.587 ; 2.442 ; Fall ; CLK100M ;
; DRAM_D[3] ; CLK50M1 ; 4.599 ; 4.234 ; Fall ; CLK100M ;
; DRAM_D[4] ; CLK50M1 ; 2.577 ; 2.432 ; Fall ; CLK100M ;
; DRAM_D[5] ; CLK50M1 ; 2.577 ; 2.432 ; Fall ; CLK100M ;
; DRAM_D[6] ; CLK50M1 ; 2.597 ; 2.452 ; Fall ; CLK100M ;
; DRAM_D[7] ; CLK50M1 ; 2.577 ; 2.432 ; Fall ; CLK100M ;
; DRAM_D[8] ; CLK50M1 ; 2.598 ; 2.453 ; Fall ; CLK100M ;
; DRAM_D[9] ; CLK50M1 ; 2.598 ; 2.453 ; Fall ; CLK100M ;
; DRAM_D[10] ; CLK50M1 ; 2.599 ; 2.454 ; Fall ; CLK100M ;
; DRAM_D[11] ; CLK50M1 ; 2.588 ; 2.443 ; Fall ; CLK100M ;
; DRAM_D[12] ; CLK50M1 ; 2.589 ; 2.444 ; Fall ; CLK100M ;
; DRAM_D[13] ; CLK50M1 ; 2.599 ; 2.454 ; Fall ; CLK100M ;
; DRAM_D[14] ; CLK50M1 ; 2.579 ; 2.434 ; Fall ; CLK100M ;
; DRAM_D[15] ; CLK50M1 ; 2.577 ; 2.432 ; Fall ; CLK100M ;
; DRAM_LDQM ; CLK50M1 ; 4.195 ; 4.363 ; Fall ; CLK100M ;
; DRAM_RAS_N ; CLK50M1 ; 2.578 ; 2.433 ; Fall ; CLK100M ;
; DRAM_UDQM ; CLK50M1 ; 4.257 ; 4.440 ; Fall ; CLK100M ;
; DRAM_WE_N ; CLK50M1 ; 4.600 ; 4.235 ; Fall ; CLK100M ;


 なぜか、DRAM_D のビット3と、DRAM_LDQM、DRAM_WE_N だけが、2ns 程度遅れています。
 タイミング制約も与えているのですが、全然効いていないようです。

 SDRAM の入力側のセットアップ時間に対してぎりぎりなのですが、一応満たしているのでOKとしました。
 問題になりそうなら、全体的に2ns 程度早く出力する事にします。


 SDRAM → FPGA の方ですが、

 遅延する方向に最悪の値 = FPGA→SDRAMへのクロックの配線遅延(1ns) + SDRAMの出力遅延値(6ns)+ SDRAM → FPGA の配線遅延(1ns)

 遅延しない方向の最良の値 = SDRAM のデータホールド値(2.5ns)


 上記の遅延を考慮すると、取り込むクロックは、通常のクロックより90度遅れた(2.5ns)クロックで取り込めばよさそうです。


 それを考慮して、〜.sdc を直してレイアウトした結果の一部です。


+----------------------------------------------------------------------------------------------------------------+
; Slow 1200mV 85C Model Setup: 'CLK100M_DI' ;
+-------+-----------+----------------------+--------------+-------------+--------------+------------+------------+
; Slack ; From Node ; To Node ; Launch Clock ; Latch Clock ; Relationship ; Clock Skew ; Data Delay ;
+-------+-----------+----------------------+--------------+-------------+--------------+------------+------------+
; 1.041 ; DRAM_D[6] ; SDRAM:U_SDRAM|q_i[6] ; SDRAM_CLK ; CLK100M_DI ; 12.500 ; -2.033 ; 1.138 ;
; 1.051 ; DRAM_D[2] ; SDRAM:U_SDRAM|q_i[2] ; SDRAM_CLK ; CLK100M_DI ; 12.500 ; -2.033 ; 1.128 ;
; 1.060 ; DRAM_D[3] ; SDRAM:U_SDRAM|q_i[3] ; SDRAM_CLK ; CLK100M_DI ; 12.500 ; -2.034 ; 1.118 ;
; 1.061 ; DRAM_D[4] ; SDRAM:U_SDRAM|q_i[4] ; SDRAM_CLK ; CLK100M_DI ; 12.500 ; -2.033 ; 1.118 ;
; 1.061 ; DRAM_D[7] ; SDRAM:U_SDRAM|q_i[7] ; SDRAM_CLK ; CLK100M_DI ; 12.500 ; -2.033 ; 1.118 ;
; 1.061 ; DRAM_D[1] ; SDRAM:U_SDRAM|q_i[1] ; SDRAM_CLK ; CLK100M_DI ; 12.500 ; -2.033 ; 1.118 ;
; 1.061 ; DRAM_D[5] ; SDRAM:U_SDRAM|q_i[5] ; SDRAM_CLK ; CLK100M_DI ; 12.500 ; -2.033 ; 1.118 ;
; 1.063 ; DRAM_D[0] ; SDRAM:U_SDRAM|q_i[0] ; SDRAM_CLK ; CLK100M_DI ; 12.500 ; -2.031 ; 1.118 ;
+-------+-----------+----------------------+--------------+-------------+--------------+------------+------------+

+----------------------------------------------------------------------------------------------------------------+
; Slow 1200mV 85C Model Hold: 'CLK100M_DI' ;
+-------+-----------+----------------------+--------------+-------------+--------------+------------+------------+
; Slack ; From Node ; To Node ; Launch Clock ; Latch Clock ; Relationship ; Clock Skew ; Data Delay ;
+-------+-----------+----------------------+--------------+-------------+--------------+------------+------------+
; 2.353 ; DRAM_D[0] ; SDRAM:U_SDRAM|q_i[0] ; SDRAM_CLK ; CLK100M_DI ; 2.500 ; -1.753 ; 0.852 ;
; 2.355 ; DRAM_D[4] ; SDRAM:U_SDRAM|q_i[4] ; SDRAM_CLK ; CLK100M_DI ; 2.500 ; -1.755 ; 0.852 ;
; 2.355 ; DRAM_D[7] ; SDRAM:U_SDRAM|q_i[7] ; SDRAM_CLK ; CLK100M_DI ; 2.500 ; -1.755 ; 0.852 ;
; 2.355 ; DRAM_D[1] ; SDRAM:U_SDRAM|q_i[1] ; SDRAM_CLK ; CLK100M_DI ; 2.500 ; -1.755 ; 0.852 ;
; 2.355 ; DRAM_D[3] ; SDRAM:U_SDRAM|q_i[3] ; SDRAM_CLK ; CLK100M_DI ; 2.500 ; -1.755 ; 0.852 ;
; 2.355 ; DRAM_D[5] ; SDRAM:U_SDRAM|q_i[5] ; SDRAM_CLK ; CLK100M_DI ; 2.500 ; -1.755 ; 0.852 ;
; 2.365 ; DRAM_D[2] ; SDRAM:U_SDRAM|q_i[2] ; SDRAM_CLK ; CLK100M_DI ; 2.500 ; -1.755 ; 0.862 ;
; 2.375 ; DRAM_D[6] ; SDRAM:U_SDRAM|q_i[6] ; SDRAM_CLK ; CLK100M_DI ; 2.500 ; -1.755 ; 0.872 ;
+-------+-----------+----------------------+--------------+-------------+--------------+------------+------------+


 数字的にOKなので、とりあえずこれでよしとしました。


 ちなみに使用した〜.sdc はこれです。

sdc ファイル



posted by えすび at 17:33| Comment(0) | FPGA化:SDRAM | このブログの読者になる | 更新情報をチェックする

SDRAM周りの設計(2)

 SDRAM のアクセスについて、今回は次のようにしました。

・リード時
 ローアドレス、バンクを指定して、ACT コマンドを出力。
 カラムアドレスを指定して、RDコマンド出力。この時、A10='H' にして、オートプリチャージにする。
 2クロック後にデータが出力される

・ライト時
 ローアドレス、バンクを指定して、ACT コマンドを出力。
 カラムアドレス、データを指定して、WRコマンド出力。この時、A10='H' にして、オートプリチャージにする。

 それぞれのアクセスをしていない間は、CBR(オートリフレッシュ)状態にしておく。
 リード/ライトのアクセスの前に、CBR を解除する。少し時間を置いてから、リード、ライトが開始できる。


SDRAM タイミングチャート



 これで動くかどうかよくわかりませんが、とりあえずこれで設計してみます。


 また、SDRAM は100MHzでアクセスするにしても、配線遅延やデバイスの遅延などを考えないと、SDRAM から出力されるデータを正確に受信する事ができません。

 模式図、タイミングは次の通りです。


SDRAM とのやりとり(1)

SDRAMとのやりとり(2)


 SDRAMの入力のsetup/hold 値は、データシートより、tSI = 2ns、tHI = 1ns です。

 これは、
 ・クロックの立ち下がりでデータを出力する。
 ・クロックとデータの遅延値をほぼ同じにする。

 ことで満たすことが出来ます。


 問題は、SDRAM から入力されるデータを取り込む時で、元のCLK100M から見ると

 FPGA の出力遅延 + 配線遅延 + SDRAM の出力遅延 + 配線遅延 + FPGA の入力バッファの遅延

 の遅延が付きます。

 また、SDRAM の出力遅延と、SDRAM のデータホールドタイムが違うため、取り込むデータの有効な幅は、1クロック未満になります。

 これらを考慮して、SDRAM から入力されるデータの丁度真ん中辺りでデータを取り込むことが出来るように、取り込みクロックを決める必要があります。

 併せて〜.sdc でタイミング制約を与える必要があります。


 かなり面倒なんですが、これをちゃんとやっとかないと、まともに動かなかったり、たまに調子が悪くなったりするので、手は抜けません。



posted by えすび at 17:32| Comment(2) | FPGA化:SDRAM | このブログの読者になる | 更新情報をチェックする

2011年10月07日

SDRAM周りの設計(1)

 SDRAM周りの設計に先立ち、いろいろ調べてみる。

 DE0 のCDROM に資料としてSDRAMのデータが入っていたんですが...これが実装されているものと全く違う!
 (CDROMに入っていた、IS42S16400 というのを使われているボードもあるようです)

 コンパチ品だとは思いますが、スピードグレードとか全然調べられないので、メーカ名から探しました。

 メーカHP http://www.zentel.com.tw/

 Zentel の AV364S49ETP-G6 というのが使われていました。


 また、使い方がよくわからなかったので、以下を参考にしました。

 http://suz-avr.sblo.jp/article/40758669.html
 http://www.softech.co.jp/mm_080206_firm.htm


 SDRAM って、ランダムアクセスをさせると意外と遅いんですね。リフレッシュはどうしよう。

 ...こういう事をまとめてみて、タイミングを考えてみる事にします。

posted by えすび at 22:29| Comment(0) | FPGA化:SDRAM | このブログの読者になる | 更新情報をチェックする