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 件のコメント:

コメントを投稿

ERROR: Failed to spawn fakeroot worker to run ...

なにかと忙しくてなかなか趣味の時間を確保できない。 ...orz  家の開発機のOSはLinux Mintなのだが、最近バージョンを22に更新したところ、myCNC用のpetalinuxをビルドできなくなってしまった。ビルドの途中で ERROR: Failed to spawn ...