FC2カウンター FPGAの部屋 DDR SDRAMのDQS信号でデータをサンプルする方法2
FC2ブログ

FPGAやCPLDの話題やFPGA用のツールの話題などです。 マニアックです。 日記も書きます。

FPGAの部屋

FPGAの部屋の有用と思われるコンテンツのまとめサイトを作りました。Xilinx ISEの初心者の方には、FPGAリテラシーおよびチュートリアルのページをお勧めいたします。

DDR SDRAMのDQS信号でデータをサンプルする方法2

DDR SDRAMのDQS信号でデータをサンプルする方法のうち、SRL16EプリミティブでFIFOを作って実際にDDR SDRAMのデータを受ける方法だ。これはXAPP758Cでも使われていたが、CLB内のLUTをFIFOとして使用する方法だ。LUTをFIFOとして使用するためにSRL16Eプリミティブを使用している。これはデータを取り出せる位置が任意に選べるシフトレジスタである。4ビットのアドレスがあって、アドレスを入れるとそのアドレス番号のシフトレジスタのデータが出力できる。なおSRL16というプリミティブもあるが、SRL16Eとの違いはイネーブルがあるかどうかである。
これを使用してFIFOにすることにした。FIFOにするためのコードはVHDLで自分で書いた。
使用するFPGAはXC2VP7-6FF896だ。サンプルプロジェクトはここにあるので参照してほしい。
最初にPACEでIOピンを割り当てよう。今まで数回PACEによるIOピンの割り当てはやってきたので、以前の画像で済ませてしまうことにする。入出力ピンの名前は違っているので注意願います。
まずは、SEのProcessesウインドウのUser Constraintsを展開してAssgin Package Pinsをダブルクリック。
pace_1_060126.png


BANK7のみSSTL2レベルのIOに対応するためにVREFピンをPROHIBITする。メニューバーのIOBsからProhibit Special Pins...を選択する。下図のようなダイアログが開くので、BANK7にチェックを入れる。次にProhibit Pin TypesのVREFにチェックを入れ、OKボタンをクリック。
pace_1_060126.png


Design Object ListペインからDevice Architectureペインに、下のUCFファイルを見ながらI/Oをドラックアンドドロップしてほしい。(でも、UCFファイルを直接コピーしたほうが早いか。。。)
pace_1_060126.png


ピンアサイン部分のUCFファイルです。

NET "wr_en" LOC = "K26" ;
NET "reset" LOC = "D26" ;
NET "rd_en" LOC = "K25" ;
NET "full" LOC = "K27" ;
NET "empty" LOC = "N24" ;
NET "dqs" LOC = "C30" ;
NET "dout<7>" LOC = "N23" ;
NET "dout<6>" LOC = "L29" ;
NET "dout<5>" LOC = "K29" ;
NET "dout<4>" LOC = "J28" ;
NET "dout<3>" LOC = "J27" ;
NET "dout<2>" LOC = "M26" ;
NET "dout<1>" LOC = "M25" ;
NET "dout<0>" LOC = "K30" ;
NET "din<7>" LOC = "M24" ;
NET "din<6>" LOC = "M23" ;
NET "din<5>" LOC = "J29" ;
NET "din<4>" LOC = "H29" ;
NET "din<3>" LOC = "D28" ;
NET "din<2>" LOC = "C27" ;
NET "din<1>" LOC = "J24" ;
NET "din<0>" LOC = "J23" ;
CONFIG PROHIBIT = C29;
CONFIG PROHIBIT = J30;
CONFIG PROHIBIT = L30;
CONFIG PROHIBIT = N30;
CONFIG PROHIBIT = R29;



次にFloorplannerで論理素子を割り当てよう。ピンもFloorplannerで割り当ててもよい。
"Processes"ペインのImplemnent Designを開き、その中のTranslateを開く。その中のFloorplan Designをダブルクリックする。そのFloorplannerで下図のようにLUT3,SRL16Eを割り当てる。
ddr_receive_1_060418.png


論理素子割り当て部分のUCFは以下の通り。

INST "delay3" LOC = "SLICE_X2Y75" ;
INST "delay2" LOC = "SLICE_X1Y75" ;
INST "delay1" LOC = "SLICE_X0Y75" ;
INST "lut_fifo_inst/SRL16E_inst7" LOC = "SLICE_X0Y70" ;
INST "lut_fifo_inst/SRL16E_inst6" LOC = "SLICE_X0Y70" ;
INST "lut_fifo_inst/SRL16E_inst5" LOC = "SLICE_X0Y71" ;
INST "lut_fifo_inst/SRL16E_inst4" LOC = "SLICE_X0Y71" ;
INST "lut_fifo_inst/SRL16E_inst3" LOC = "SLICE_X0Y72" ;
INST "lut_fifo_inst/SRL16E_inst2" LOC = "SLICE_X0Y72" ;
INST "lut_fifo_inst/SRL16E_inst1" LOC = "SLICE_X0Y74" ;
INST "lut_fifo_inst/SRL16E_inst0" LOC = "SLICE_X0Y74" ;


Processesウインドウから"Implement Design"を展開して"Place & Route"を展開し、"View/Edit Routed Design (FPGA Editor)"をダブルクリック。
そうすると論理合成、インプリメントをしてFPGA Editorが起動する。
クロックとして使用してるdqs_delay_3をみると、かなり短い距離で配線されていることがわかる。delayを見てみると0.261nsから0.665nsの間である。
ddr_receive_2_060418.png


次にTiming Analyzerを起動して、DQSパッドからdqs_delay_3(遅延素子で遅延したクロックとして使用)の遅延時間とD入力パッドからSRL16Eのセットアップ時間までの遅延を比べてみる。
ddr_receive_3_060418.png


D3を比べてみるとDQSは2.847ns遅延して、D3用SRL16Eまでは1.682ns遅延する。DQSのほうがSRL16Eのセットアップ時間を加えた遅延時間より1.165ns遅れてるので、データを受けられるはずだ。これから受信クロックからシステムクロックに乗せ変えなければならないが。このFIFOからもう一度非同期FIFO入れても良いだろう。ほかにも方法があると思う。

ちょっと条件を変えてやってみよう。FloorplannerでDelay3とDelay1の位置を反対にする。
ddr_receive_4_060418.png


これでインプリしてFPGA Editorを起動すると、dqs_delay_3の遅延を見ると、大幅に伸びている
ddr_receive_5_060418.png


0.566nsから1.055nsまでの遅延になっていて、前より伸びている。論理素子の位置によってだいぶ変わるようである。注意が必要のようだ。
ちなみに今までのPlace & Route Effort LevelはStandardでインプリしている。ちなみにHighでやっても変わらないようだ。UCFにタイミング制約を何も書いていないのでやりようがないのだろう。
  1. 2006年04月17日 05:45 |
  2. DDR SDRAMコントローラ
  3. | トラックバック:0
  4. | コメント:0

コメント

コメントの投稿


管理者にだけ表示を許可する

トラックバック URL
http://marsee101.blog.fc2.com/tb.php/198-949fa95f
この記事にトラックバックする(FC2ブログユーザー)