2011年9月28日水曜日

SDRAMCのSpartan3Eへの実装 2

動いた!!

半田付けの結果は、SDRAMの端子ではなくてコネクタ用ランドで半田ブリッジが1箇所あっただけだった。 それを修正後RTLの方はほぼ無修正でいけた。 もちろんSDRAMは100MHzで駆動している。
結構動くもんなんだなーっと感心感心。

これはMemory R/W check programが動作している様子。Memoryの全領域の検査を終える毎にLEDが点滅するのでゆっくりした点滅周期になっている。



Errorになった場合はこの動画のように早い点滅になる。
これは意図的にError状態にして撮影した。



次は子基板を作ろう。

2011年9月25日日曜日

SDRAMCのSpartan3Eへの実装

SDRAMCのSpartan3E(XC3S250E)への実装をしている。
使用する基板は以下のマルツパーツのMFPGA_SPAR3Eというもので、Design Wave Magazine
2007/07 号の付属基板と同じ物だ。この基板にはSDRAMは実装されていないので、当初は子基板
を作ってそちらに実装しようあるいは基板裏面に張り付けようか等考えていたが、結局後者の方法
で行くことにした。



基板裏面のレジストを削除後、カプトンテープを貼り、その上にSDRAMを貼付けた。



以下は配線を終えたところ。線材は0.26mm UEW線を使用している。
半田付け作業はほぼ1年ぶりだったので、0.8mm pitchへの半田付けは少々手こずった。
果たして、動作するんだろうか。 (-_-;;



この基板にはSDRAMの他に CAMERA I/F (TCM8230MD)、I2C I/F、 UART I/F、
SD CARD I/F を持つ。できればVGA I/Fも入れたかったのだが端子数が足りず断念した。
基板コネクタの信号割り当ては以下の通りだ。



さすがに、CAMERA I/FやUART I/F、SD CARDのコネクタをこの基板に付けることは
出来ないので、これらは子基板に実装するつもりだ。

上記写真のような実装の仕方なので、動くかどうか判らないが出来ればSDRAMは100MHz
で動作させたいと考えている。
SD CARD Controller以外のRTLを構築して合成し、Timing violation等出ないことは
確認できた。



ここまでやってきて何だが。
このやり方はちょっと無理があるかも知れない。。。
もうちょっと頑張ってみよう。

2011年9月22日木曜日

jwrt download 100

jwrtはsourceforgeで公開しているが、2010-04-10に公開してから1年半弱、
Download数がちょうど100になっていた。



国数は24ヵ国、記念すべき100 Download目はSouth Africaだった。



ちょっぴり感動。

2011年9月21日水曜日

DE0のSDRAMの動作上限周波数

DE0のSDRAMは160MHzで動作させることが出来ているが、
STAして検討した結果ではそれ以上の周波数でもSetupやHoldは確保できそうな感じだ。
そこで、どの位が上限なのか色々試して見たところ175MHzまでは動作した。
FPGA側は200MHz位まではいけそうなのだが、SDRAMが166MHz品なのでこの位が
限界なのかもしれない。



これはMemory R/W Check Programが動いている様子だ。

2011年9月19日月曜日

SDRAMCのDE0での動作確認 3

SDRAMCをNios II Systemに組込み動作確認を行った。
Altera版SDRAMC(SOPC BuilderのLibraryのSDRAMC)との性能差を見ることが目的なので、
同じSystem構成でDRAMCがAltera版のものと自作SDRAMC版を生成して動作させることにした。
ただし、新しくSystem構成を考えるのは面倒なのでDE0のDemonstration用Designの一つである
DE0_NIOS_SDCARDを基にしたが、Nios IIはEconomy版に変更した。

自作SDRAMCをSOPCのComponentとして登録する手順としてはまず、Avalon-MM用のWrapper moduleを作成し、次にComponent EditorにHDLをAddして信号やInterface等の設定を行った後、FinishするとComponent Libraryに登録されるので、それをSOPC SystemにAddする。



Wrapper moduleの中身であるが、これは下図のようにほぼ信号名の付け直しで済んだ。


自作SDRAMCを組み込んだSystemが出来たので、合成してsof fileを生成後実機に流し込み、
何がしかのProgramを作成して走らせれば実機での動作確認が出来るが、この方法だと感覚的
にしか違いが判らない気がしたのでまずはSimulationで確認することにした。

単純なRead/Writeの確認
まず下図のようなProgramを書いてSimulationしてみた。
このProgramではtext, data, stack等の全てのsectionをonchip_memに配置するようにして、
Programから明示的に読み書きしない限りはSDRAMへのAccessが発生しないようにした。



下図はAltera版SDRAMCのSystemでのSimulation波形だ。
SDRAMへのAccessはもっと近接していると思ったら違った。随分スカスカだ。
objdumpを確認したところ、Nios IIをEconomy版にしたためもあると思うが番地計算で
値を4倍するのに加算命令2回で行う等冗長な命令列になっていた。
(Nios IIはShifterは持ってなかったっけか?)

2011/09/20 追記
後にNios IIプロセッサ・リファレンス・ハンドブック(n2cpu_nii5v1_j.pdf)を参照したところ、
Nios II/eコアは「最大で6クロック・サイクルあたり1つの命令を実行」するらしい。
波形を見る限りでは「最大で6クロック」というより「常に6クロック」という感じだが。。。
一方、Nios II/eは最大200MHzまで動作可能という記述もどっかの資料に書いてあったが、
ということは頑張って200MHzで合成できたとしても実質はその1/6の33.333MHzの性能しか
出ないということのようだ。 Nios II/e は。

下図では、SDRAMへの最初のWriteから最後のReadの完了までで2260nsかかっている。
Altera版SDRAMCはAvalon-MM側も16bitであるのに対してNios IIは32bit busなので、
Avalon-MM MasterとSDRAMC間のTransactionは必ず2回発生する。
この2回のTransactionがどういう間隔で発生するのか興味があった。 WriteはData転送を
行うI/F境界で転送が成立した時点でWrite完了と見做せるので連続的に発生できる筈である。
実際波形を見ても、WriteはBurst的になっている。 Readについても、Avalon-MM I/Fは
Split Transaction型のI/Fなので一々Read Dataの到着を待つ必要はなく連続してRead
要求を発行できる筈だ。が、波形をみるとそうなっていない。 1 Transaction毎にRead Data
の戻りを待っている。 Avalon-MM I/FのMaster があまり工夫されていないのだろう。



下図は自作SDRAMCのSystemでのSimulation波形だ。
上記と同様にWrite開始からRead完了までで1761nsだった。




ただし、波形をみてもわかる通りこの方法の場合、SDRAMへのAccessの占める時間は
僅かなのでこの結果を持って性能差を判断することは適切ではないだろう。
そこで、次に下図のようなProgramで且つこのProgram自体もSDRAM上に配置し、
且つStackやData sectionもSDRAM上に配置した状態で動作させてみた。
この状態の方がより現実的だろう。



実行時間としてはSDRAMのAccessが始まる時点から、Nios IIのInstruction busの
Addressがmain関数の最終番地になるまでを見た。(下図のret命令部)



下図がAltera版SDRAMC SystemのSimulation結果だ。



また、下図が自作SDRAMC SystemのSimulation結果だ。



Altera版の実行時間が2msec、自作版が1msecなので性能差は2倍だ。
ただ、これは自作版の方が性能が良いと見るよりは、むしろ、自作版の方が普通であり
Altera版の方が性能が低いと見るべきだろうと思う。なぜならbus幅が16bitと、
内部の1/2のためThroughputが0.5になってしまっているからだ。
(32bit幅のSDRAMを搭載したSystemでは差はないかも知れないし。。。)
DE0のように16bit幅のSDRAMを搭載したSystemでは、自作SDRAMCのようにSDRAM
 I/F部を倍速で動かすことでThroughput 1.0を保つことは可能なので、要は工夫次第と
いうことだろう。

最後にsofを実機に流し込んで、SDRAMの全領域のR/W check programを走らせて
Errorにならない事を確認した。また、160MHz駆動版(内部80MHz、SDRAM160MHz)
も作成して動作させてみたがこちらも動作した。

ここまでのRTL一式はいつも通り、
http://www.hi-ho.ne.jp/bravo-fpga/
に置いた。

次はこのSDRAMCをSpartan3Eに実装しよう。

2011年9月15日木曜日

SDRAMCのDE0での動作確認 2

前回のblogでclockの位相を同位相にしたと書いたのだが、念のため再度STAしてみた。
前回はclockの時間をTimeQuestのReportPathで、それ以外の信号の時間をReportTimingで
得ていたがこの方法だとclockの時間が分かり辛かった。
そこで、今回は仮想のclockをcreate_generated_clockで生成して、このclockに対するReportTimingを実行してDRAMへのclock、他の信号のtimingを得た。
下図はDRAM_CLKの値で、これから遅延値は5.126-3.101で2.039nsだった。


また、clock以外の信号で最大遅延経路はDRAM_WEとDRAM_DQ[3]で、最小遅延経路はDRAM_CSだった。




Read (DRAM_DQ → capture F/F)の値はReport Pathで調べた。



また、SDRAMのspecは以下の通りだ。

以上の値から計算するのだが、図を書いたり手で計算するのは面倒なので、
下図のようにverilogでprogramを書いてsimulationし波形で確認した。

その結果、holdが仕様を満たしていない(仕様1nsに対して580ps)ことが判明した。


そこで、SDRAMのclockの位相を2.0ns早めるようにした。


DE0に付属しているSDRAMの仕様書はIntegrated Circuit Solutionのものだが、
実際に実装されているのはZentelのA3V64S40ETPG6という166MHz品だ。
仕様書はここから入手できる。 http://www.zentel.com.tw/

そこで上記programで160MHzの場合について計算してみた。
holdは余裕がある。setupも仕様1.5nsに対して1.637nsで大丈夫そうだ。


setup/hold関係は一応問題なさそうだ。
160MHz対応にするためにはこの他にtRCDやtRFC等のtimingの見直しも
必要になるが、とりあえずこれらは現状ままとして合成して実機で動かしてみた。

結果は動作した。
以下の動画はDRAMのR/W check programを実行させている様子だ。


また、以下の動画は同じprogramを100MHzで動かしている様子だ。
160MHzと比較してLEDの点滅が遅いのが解る。


という訳でDE0でSDRAMを160MHzで動作させることが出来た。 やったー!  \(^_^)/

2011年9月11日日曜日

SDRAMCのDE0での動作確認

SDRAMCのRTLが出来上がったのでDE0用にSystemを構築して動作確認を行った。
今回はzumi32の実機動作確認時に文字列をDisplayに表示するRTLを流用して、
DE0用に変更して使用した。
内部動作周波数が50MHzと低いので特に躓くこともなく容易に合成できた。


clock系について、100MHzはSDRAM_CLKに供給用と内部用に分けてSDRAM_CLK
の位相を変えられるようにしたのだが、合成後のSTA(Static Timing Analysis)の値を計算
した結果同位相で問題なさそうだったので結局、同位相にした。



次に以下のようなSDRAMの全領域の読み書き検査Programを作成して1時間程走らせて、
Errorにならないことが確認できた。


次に文字列のbitmapをSDRAMのVRAM領域に展開するProgram(zumi32の実機確認時
に作成したものを若干変更)を動作させてみた。こちらも動作した。


今回のProjectの最終目標は作成したSDRAMCをSpartan3E XC3S250Eに実装することなので、
その作業に移ろうと思うが、その前に、SDRAMC CoreにAvalon I/Fを付けてNios II Systemで
動作させ、SOPC Builderで生成したSDRAMCとの性能差を見ようと思う。
前回のblogに書いたようにSDRAMC単体性能では私のSDRAMCの方が性能は良いはずだが、
Systemに統合した場合にどの程度違いが出るのか是非見てみたい。

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を下回る結果となった。



自作CPUで遊ぶ 22

今使用しているモータードライバはDM556Dというものだが、このドライバはMicro Stepが 800 [pulse/rev] 〜 40000 [pulse/rev]の範囲で設定できる。 Mi...