2011年9月8日木曜日

SDRAMCの作成

ちょっとした思いつきでSDRAM CONTROLLERを作成している。
思いつきというのは、CAN IPの実機評価の時に使用したSpartan3E Boardの
裏面か子基板を作ってSDRAMを実装し、且つ、Camera I/FとSpartan3A StarterKitや
DE0のようなVGA I/FとSD Card I/Fを付けて動かしてみたいというものだ。
Spartan3EのBoardはDesign Wave Magazineに付属していたが同じ仕様の物が
マルツパーツで販売されていて今でも入手可能だ。
ということでこのSDRAMCの最終的な目標はSpartan3E XC3S250Eに実装することだが、
その為にはSDRAMを入手したり基板を作成したりといった事も必要になってくるが、まずは
SDRAMC IPの動くものを準備したいので先にDE0で開発を行うことにした。

今回作成するSDRAMCは以前作成した高速版DDR2 SDRAM CONTROLLERを元に
しており、その構造を下図に示す。今回は最終目標がXC3S250Eへの実装という事もあり
できるだけ小さく作りたかったのでBank Interleave等は行わずBA addressもROW
addressの一部として扱い全体を1 Bankとして制御するようにした。そのため、BC
(Bank Controller)は1つだけになっている。 data bus幅は内部(MPIF側)は32bit、
SDRAM側は16bitだが、throughputを保つためにSDRAMはFPGA内部の2倍の周波数
で駆動する。具体的には内部50MHz、外部100MHzを考えている。。。動くといいな。ワクワク



下図はMULTIPORT I/F(上手のPORTA, PORTB, ・・・部)のI/F仕様だ。



下図はcore moduleのみのsimulation波形で、前半がWrite、後半がReadだ。


このSDRAMCはSDRAMをopen policyでもclose policyでも制御できるようになっている。
mp2dc_lstという信号はpageを閉じさせる信号であり、この信号が1の場合は
SDRAMへのRead/WriteはRead with PrechargeまたはWrite with Prechargeになる。
通常はburst転送の最終dataの転送時にmp2dc_lstを1にしてpageを閉じさせるが、
同一Row pageへのaccessが続くような場合はmp2dc_lstを1にしないようにして、
Precharge及び次のaccess時に発生するBank Activeを起こさないようにも出来る。
また、mp2dc_lstが0のままでaccessを終えた次のaccessが違うRow pageへのaccess
だった場合は、SDRAMCがそれを検知してPrecharge、Bank Active処理を行う。
下図はそのような場合のsimulation波形だ。


性能について、Write Latency(下図のA→B)は3.5、Read Latency(同C→D)は6だ。
まずまずではないかと思う。


ちなみに余談だが、下図はDE0に付属しているDemonstration用Designの一つ、
DE0_NIOS_SDCARDのSOPC Builderで生成したsdram.vのsimulation波形だ。


このsdram.vは内部側bus幅も16bitでclockも同一だ。Nios IIは32bit CPUなので内部
は32bitだが、32bit - 16bitのsizingはcpu_data_master_arbitratorで行っているようだ。
clockが同一のため、throughputは半分になってしまうことになり、一寸もったいない気がする。

ちなみに、さらに余談だが、以下はDE0_SOPC.vのcpu_data_master_arbitrator内部の32bit→16bit mux記述だ。


 //mux write dbs 1, which is an e_mux
 assign cpu_data_master_dbs_write_16 = (cpu_data_master_dbs_address[1])? cpu_data_master_writedata[31 : 16] :
                    (~(cpu_data_master_dbs_address[1]))? cpu_data_master_writedata[15 : 0] :
                    (cpu_data_master_dbs_address[1])? cpu_data_master_writedata[31 : 16] :
                     cpu_data_master_writedata[15 : 0];

この記述をよく見ると、同じ論理がダブっている。他の記述にも冗長な箇所が散見された。
softwareでRTLを生成させているからかも知れないし、論理合成時にこのような冗長部は落とされて
いくのだとは思うのだが、そうとう雑な回路だなという感じがした。

Latencyだが、Write(図のA→B)が5、Read(同C→D)が13となっていて以外と大きい。
気になったのが、Prechargeの仕方だ。上図の場合前半のWriteも後半のReadも同一の
Row pageに対して行っているのだが、何故かReadの前にpageを閉じて(Prechargeして)
改めて開き直している(Bank Activeしている)。
close policyでいくならWriteの終了時にPrechargeすれば、Precharge後のtRPの待ち時間
を次のaccess開始までの時間に収めることができると思うのだが。。。

という訳で現時点では、性能的には私のSDRAMCの方が良さそうな気がする。
まだ実動作させていないので大きな事は言えないが。。
今回作成したSDRAMC coreをAvalon I/F対応にするのは簡単に出来そうなので、
いつか、Avalon I/Fを付けてNios II systemで動作させてみたいと思う。

回路規模について見てみた。
sdram.vとSDRAMCをiseで合成した。
FlipFlopの数は当然ながらSDRAMCの方が多い。ただ使用SLICE数は何故か逆転しており、
僅かながらSDRAMCがsdram.vを下回る結果となった。



0 件のコメント:

コメントを投稿

自作CPUで遊ぶ 25

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