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)を発行したらリードできた。
なるほど、そういうことか。 やた!! 一歩前進だ。





2012年4月1日日曜日

浮動小数変換器

このところ本業の方で一日中神経を集中して作業する状態が続いているせいか帰宅してからは気力が萎えてしまって中々大好きなFPGAに向き合えていない。 ソフトウェアの検証なんかするもんじゃねーなぁ。 やっぱ年かなー、年はとりたくないもんじゃのう、まったく。 あーこりゃこりゃという感じじゃわい。

話は変わって、先日某FPGA系BBSで浮動小数点に関するスレッドが立っていて私も自分のコードを晒したりして書き込んだのだが、昨日もっと簡単な方法を思いついた。入力が精々10bit位までしか対応できない非常にばかばかしい方法だがFPGAならではのやり方でもある。
それは、BRAMを使うという方法だ。 即ち、入力が8bitの場合 256x32bitの変換テーブルをBRAMに実装するという方法だ。非常に安直だが値づけした結果も確実に得られるし、レイテンシーも最小で実現できる。
ひとつ賢くなった気がする。 やったー!

TE0720 No.4 (BNN-PYNQを動かしてみる 2)

TE0720でBNN-PYNQを動かすことが出来た。 以下は前回に続いてBNN-PYNQが動くまでの記録。 gdb (GNU debugger)で例外が出る原因を調べてみた。 例外が発生しているのはシェアードライブラリ(python_hw-cnv-pynq.so)の中であ...