2012年5月20日日曜日

Spartan6版 DDR2コントローラの作成 2

というわけで、DDR2 SDRAMコントローラを実機で動かしてみた。

実機動作の為のRTLは以下の構成とした。


合成はうまく行った。


メモリのリードライトチェックプログラムを走らせてエラーにならないことが確認できたので、
PCからUSB-UART経由で画像データをDRAMにダウンロードしてDVIに表示させてみた。
これも問題ない。 解像度はXGA (1024x768)




ということで、200MHz(DDR2-400)版のコントローラは割と簡単に作ることができた。
次は、400MHz(DDR2-800)に挑戦だぁー


2012年5月13日日曜日

Spartan6版 DDR2コントローラの作成

DDR2 SDRAMコントローラを作っている。
DDR2 SDRAMコントローラの作成はこのブログの始めのほう(2010年)でも行ったが、その時は
Spartan3A版で、Spartan3A Starter Kitで動作させた。 今回はSpartan6版で、DIGILENTのATLYS
ボード用だ。ATLYSボードに搭載されているDDR2 SDRAMはMicronのMT47H64M16HR-25Eと
いうやつで、スピードグレードはDDR2-800だ。 AtlysのReference Manualを見ると実際800Mbps
(DDR2なのでクロック周波数は400MHz)まで動作確認できているようだ。
ハードマクロでの性能とは言えすごいな。


今回のDDR2 SDRAMコントローラだが、以前作成したSparatn6版LPDDR SDRAMコントローラの
RTLをベースに、というかDDR2 SDRAM用に変更して作ることにし、一応RTLは出来た上がった。
周波数は400MHz (DDR2-800)と行きたいところだが、このスピードは簡単に達成できるとは思え
ないので、まずはLPDDR-SDRAMCと同じ200MHzで動く物を作ることにした。

以下はシミュレーションしているところだ。




次はこれを合成して実機で動かしてみるつもりだ。

2012年5月7日月曜日

next theme ... Atlys用DDR2 SDRAMコントローラ

次のテーマはAtlysボード(Spartan6)用DDR2 SDRAMコントローラを作ってみることにした。
AtlysボードでDVI (HDMI)に画像出力等をやろうとするとそれなりの容量のメモリが欲しくなる。

DDR2 SDRAMコントローラはこのブログの始めの頃にも作ったが、Spartan3A Starter Kit向けだった。 そこで今度は、Atlysボード(Spartan6)用のDDR2 SDRAMコントローラという訳だ。


2012年5月2日水曜日

SPIコントローラの作成 10

Atlysでも動作確認してみた。 AtlysのFPGA Spartan6 LX45はMicroBoardのSpartan6 LX9の4.7倍の規模なので、ROMに格納するFPGAデータのサイズも大きい。 IMPACTでプログラムした場合は以下のとおり1224秒(20分!!)もかかった。


これに対して今回作成したSPI IP & プログラムでは101秒(1分41秒)だ。


まあ、何とか我慢して待てるレベルだと思う。

ということで、今回のプロジェクトは一応終わりにしようと思う。

先日公開したRTL等のsnapshot版はrelease版に更新した。
http://www.hi-ho.ne.jp/bravo-fpga/


SPIコントローラの作成 9

前回のブログでcommand frameに対するACK/NAK応答は残すと書いたのだが、
これだとライトの高速化の障害となることが判ったため結局、なくすことにした。
また、ライトの高速化の為、自動受信モードを送信にも拡張して自動転送モードにすることにした。
この機能を使うライト用制御プログラムは以下のようになる。 (166行~171行)


元々の目的だったROM(N25Q)のFPGAデータ更新用プログラムは以下のようになった。
(FPGA制御部のみを示している。)


書込みに先立ちその領域を消去する必要があるが、このプログラムでは書込みループの中で、
書込みアドレス(addr)がセクタの先頭に達するタイミングでそのセクタの消去を行うようにした。
また、Verifyは自動受信モードで全データ分をr_buffに一気にリードしてからw_buff(書込み
データ)と比較するようにした。
このような諸々の工夫の結果、SPIコントローラと更新用プログラムが完成した。
肝心の処理時間だが、以下のようにMicroBoardのROMの更新は24秒(Verify含む)、Verify
のみは4秒で処理できている。


ちなみにIMPACTで書換えた場合を以下に示す。



IMPACTの場合の341秒に対して24秒なので14倍高速に書換できることになる。
やったー \(^_^)/


やっぱ、ROMの更新は短時間で済ませたいよね。


2012年4月30日月曜日

SPIコントローラの作成 8


伝文フォーマットの変更は止めようと思ったのだが、ここを変えればさらに高速化できることが明らか
なのにやらないのも何なので、やっぱり変更することにした。
以下のように変更した。 STX, ETX, SUMを廃止し、また、read commandの場合はCMDのみと
した。 command frameに対するACK/NAK応答は残す事にした。 リードバックフレームは正味の
データだけにした。



処理時間は以下のようになった。


256Kワードの転送時間は11.81秒で変更前の半分になった。


SPIコントローラの作成 7

リードの高速化について前回のブログに書いたとおり、先頭アドレスとデータ長を設定して起動したら連続してSPIサイクルを発生しデータを連続して送信するようにした。 データ長はCTLレジスタのbit31-12の20bitに割り当てることにし、レジスタ仕様は以下のようになった。


bit31-12を0にしての受信動作は従来と同じ動作となり、受信したデータはRXDレジスタをリード
することで得る。 bit31-12を0以上の値(データ長)にして受信動作を起動すると、設定回数分SPI
受信→UART送信動作を行う。 この機能を使う制御プログラムは以下のようになる。


処理時間は以下のようになった。

前回ブログと同じ256ワードのリードは0.42秒と6倍近く高速化できた。
また、256Kワード(1Mバイト)のリードも行ってみたところ、23.14秒になった。

UART I/Fは921600bpsで8bit,non-parity,1stopbitの設定で、また、通信フレームは従来通
りの8byte (STX,TYP,32bit_DATA,ETX,SUM)なので、256Kワードの転送時間の計算値は
(262144 x 8byte) / (921600 / 10bit) = 22.76秒であるので、ほぼUART側の上限値まで
高速化できた。  STX~SUM形式を止めて正味のデータ(32bit)だけを送信するようにすれば
さらに高速化可能だが変更の規模が大きくなっちゃうので、とりあえずはここまででいいかな。
次はライトの高速化を考えよう。

2012年4月28日土曜日

SPIコントローラの作成 6

ぶはー、、ようやく休みだ~
これでしばらくは好きな事に没頭できる。やっほーい

さて、UARTの高速化だが、Linuxでは115200bps以上の転送速度の設定は簡単には
いかないと思っていたのだが、なんのこたぁーない、cfsetspeedの引数で値を渡せば
いいだけだった。今回は921600bpsにした。


このプログラムと、921600bpsにしたFPGAとで通信できた。
ところがである。全体的な速度はあんまり速くならない、いや、まったく速くならない。
UART I/F部は115200bpsから921600bpsになった分高速化できているが、
例えばN25Qの256ワードのリードに要する時間は115200と921600とで同じだった。


これは、USBがストリーミング向けのI/Fのため、少量のデータをハンドシェイクで送受する
使い方では速度が出せないということと、現状のPC-FPGA間の通信仕様がまさにそういう
仕様になっているためだと思う。 具体的には、PC-FPGA間は以下のような伝文フォーマット
で通信を行っている。


また、SPIコントローラの制御方法も工夫が足りなかった。
リードの場合はCTLレジスタにパラメータを設定してリードサイクルを発生させ、受信したデータを
RXDレジスタからリードするという手順になるが、この場合PC - FPGA間では3回の交信が必要になる。
即ち、

1.  CTLレジスタへのライトコマンド ... PC→FPGA
2.  RXDレジスタのリードコマンド ... PC→FPGA
3.  RXDデータの受信 ... FPGA→PC

そこで、RXDレジスタのリードの場合は、同時にSPIの転送も発生するようにRTLを変更してみた。
プログラムとしては以下のようになる。 まず、96行目でCTLレジスタにリード用のパラメータ
をライトして最初のリードサイクルを発生させる。それ以降は、99行目のRXDレジスタのリードに
同期してSPIのリードサイクルが発生するのでRXDレジスタのリードを必要回数繰り返すだけだ。


この結果、時間は1秒程短縮できた。


先頭アドレスとデータ長を設定して起動したら連続してSPIサイクルを発生しデータを連続して
送信するようにすればN25Qのリードに関してはもっと高速化できるだろう。  ライトもなるべく
PC-FPGA間でデータの送受が発生しないようにする必要がある。
という訳で、PC-FPGA間の通信仕様も見直した方が良さそうだ。


2012年4月15日日曜日

SPIコントローラの作成 5

SPI コントローラをFUNCTION GENERATOR(Spartan6 LX9 Microboard)のRTLに追加した。
実はSPIコントローラ作成の動機はFUNCTION GENERATORのFPGAの回路情報の更新の度に
筐体の蓋を開けるのが面倒だったからだ。SPIがあれば蓋を開けてJTAG用のUSBケーブルを繋い
で・・・ということ無しにROMの更新が可能になる。 ただ、その為にはUSB-UART I/Fの高速化も
必須だが、それはこれからのチャレンジになる。とりあえず、今回は出来上がったSPIコントローラを
FUNCTION GENERATORのRTLに統合してみたという訳だ。



統合は問題なくできたが、動作確認をしている過程で前回のブログに書いた制御プログラムが
バグっているのが分かった。 また、SPI I/Fのクロック周波数は25MHzでないとダメなようだ。
50MHzではビット化けが発生する。

また、以前SDRAMコントローラを作ったときにSpartan 3Eにデジカメもどきを作った。
http://bravo-fpga.blogspot.jp/2011/09/sdramcspartan3e.html
この時はハードウェアとしてはSDカードソケットも実装していたのだが、FPGAにコントローラ部は
実装していなかった。今回SPIコントローラをこのRTLに実装してみた。回路規模的に入るかどうか
多少不安だったのだが、何と入りやがった!!  これには驚いた。恐るべしSpartan3E 250E
現状のシステムアーキテクチャは以下のとおりだ。




ただ、これの動作確認をするかどうかは未定だ。
FT232RL使用のUSB-UART変換モジュールをあのセットから外してしまったので、動かすためには
戻さなければならない。


AtlysやMicroboardでの動作確認は一応できているので、現状のRTLのスナップショットを以下に置いた。

http://www.hi-ho.ne.jp/bravo-fpga/


2012年4月8日日曜日

SPIコントローラの作成 4

SPI BUSのクロックをSPIモジュールのクロックと同じにしていたのだが、これだと
周波数を下げて使いたい場合にシステム全体の周波数を下げることになったり、
あるいは、非同期FIFOで繋いだりといったことになって使い辛い。
そこで、分周器を追加してSPI BUSのクロックを設定できるようにした。分周比は
1/2~1/64の間で設定できる。 SPI規格にはクロック極性(CPOL)と位相(CPHA)の
組み合わせで4種の動作モードがあるようなので、これにも対応した。
 また、SPI BUSの送受信データのエンディアンを設定できるようにした。
その結果、レジスタ仕様は以下のようになった。



制御プログラムは以下のような感じになる。
プログラムを起動した時点でN25Q128のSPI I/Fモードがどのモードか不明という前提で
まず、動作モードを調べ、次にそのモード用のコマンドでQuad I/O SPIモードに設定し直している。
(※. 差し替えました。 2012.04.29)


以下はリトルとビッグそれぞれのエンディアンでN25Q128のメモリをリードした結果だ。
SPI BUSのクロックは50MHzに設定した。


また、以下はbitファイルのhexダンプだ。

bitファイルの構造は先頭にファイル情報があり、その後(白黒反転部)が回路情報となっている。
上記のメモリリードの結果と比べると、回路情報部をそのままメモリに書き込めば良さそうだ。
(※.現在N25Q128に書き込まれている回路情報と上記でダンプしているbitファイルはまったくの
別物なのでダンプ内容の細部は異なるがデータ構造をみて判断している。)

ということで、SPI コントローラとしては動作は問題なさそうだ。しかし、N25Qの書換を高速に行
うためには、PC-FPGA間の通信も高速化する必要がある。現在はUSB-UARTで115200bpsと
なっているため、何とかしてこれをもっと高速化しなければならない。

また、このSPIコントローラはSD/MMCカードにも使えるんじゃないかと思う。
そのうち、DE0に実装して試してみよう。

2012年4月6日金曜日

SPIコントローラの作成 3

DigilentのAtlysやAvnetのMicroboardで使われているSPI Flash ROMのN25Q128用の
SPI コントローラを作っている。  RTLは一応完成しMicronのSimulation モデルを使っての
Simulationでも動作確認できたので、Atlysボードで実機デバッグをやってみることにした。
手始めに Standard SPI モードでRDID (Read Identication)コマンドを発行してみたのだが、
読めない。。。 何度試してみてもオール0が読めてしまう。コントローラの動作周波数を1MHz程度
に下げてみたりしたのだが、やはり読めない。Readコマンドも同様で読めない。
コントローラを止めてSPI I/Fの各信号を直接ソフトウェアから制御できるようにして、ソフト的に制御
してみてもやはり読めない。
Flash ROMのDQ1と接続しているSpartan6のピンにPULLUP属性をつけた場合、オール1が読め
るので、どうやらFlash ROMのDQ1ピンがドライブされずHi-Zのままになっているようだ。
デバイスが壊れているんだろうか?? でも、FPGAのコンフィグレーションは出来ている。
そこで、iMPACTでSPI FlashのReadbackやID情報の取得が出来るか試して見たところ、
IDCODEがオール0で読めてしまい、エラーとなることがわかった。
現象的には一致している。


でも、FPGAのコンフィグレーションは出来るんだよなー。
ボードの電源をONにすると、出荷時に書き込まれている回路情報でFPGAはコンフィグレーションされ、UART I/Fに文字列が送信されたりボタン類を操作するとLEDが点滅したりする。
この機能を果たす回路情報は他ならぬFlash ROMからFPGAに読み込まれている筈だ。????

うーむ。。。解らん。

解った!!

FPGA コンフィグレーション時にQIO-SPIモードに設定されるようだ。
QIO-SPIモードでRDIDコマンド(MIORDID)を発行したらリードできた。
なるほど、そういうことか。 やた!! 一歩前進だ。





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

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