2013年2月27日水曜日

Zynq-7000ファミリ

昨日(2012/2/26)のマイナビニュースの記事によると、Zynq-7000ファミリのすべてのデバイスが量産に入ったんだそうな。 同記事によると、Zynq-7000ファミリは2011年12月の提供開始以降、2万個以上のデバイスと4000枚を越す開発ボードが出荷されているんだとか。。。でも、これって全世界での数量なんだよな? それにしてはちょっと少ない印象を受けるが。。。 全デバイスが量産に入ったことで、これから価格も下がるんだろうか? DigkeyでZynqのデバイスが購入できるようだが一番規模の小さいやつでも1万6千円以上もする。こういう所から1個単位で買う値段と、企業が量産のために仕入れる値段とは全然違うんだろうとは思うが、幾らくらいになるんだろう?
今はDual Core ARM Corte-A9 1.6GHzを積んだタブレットが1万円以下で購入できてしまう。
Zynqのターゲットとしている市場は、車載、産業向け、通信、データセンター、防衛などの市場のようだが、価格次第ではメーカーはタブレット用SOC+安価なFPGAでシステムを構築するようにならないだろうか?  (まぁ、さすがに防衛向けでそれはないと思うが。)  PCIEとかRapidIOみたいな高速シリアルI/Fを持ったSOCがあればそのI/FでFPGAと繋げば広いバンド幅も確保できそうな気がするし、うーん、どうなんでしょう??

2013年2月23日土曜日

ブログを書いている理由


このブログをやっているのは一言では語れないくらい様々な理由があるが、その中の一つに文章力の向上というのがある。ボキャブラリが貧弱なせいか、自分の考えを言葉や文章で表すのが非常に下手で苦手で、いつももどかしい思いをしている。  ブログを書くことで少しでも文章力がつけばと考えた。 頭の中では具体的なイメージが描けているのだが、いざそれを言葉にしようとすると言葉が出てこない。むぐぐぅ、むぎぎぎっ、あ゛ー、このもどかしさを君と分かち合いたいみたいな感じでいつもモガいている。  VerilogやCよりも日本語が一番難しい。  いや、マジで。

3Dレンダリングパイプライン 2

ジオメトリ演算部で行う処理はアフィン変換という行列演算で以下のような演算式になる。
注. 以降では、さも、知った風に書いているが、書籍等を学習して自分なり解釈したことを書いているのであって、間違っていたり、適当でなかったりする可能性があります。


[x,y,z,1]^t が元の頂点座標、 [x',y',z',1]^t が変換後の頂点座標、左端の4x4の行列が変換行列である。 座標変換には、平行移動(モデルのグローバル座標への配置という表現の方が自分としてはしっくりくる。)や、スケーリングや回転等がある。

また、任意軸のまわりの回転は以下のようになる。

複数の変換を同時に行う場合は、各々の変換行列を掛け合わせて一つの行列にする。この時、変換順序に合わせて掛け算を行う必要がある。(例えば、平行移動してからの回転と、回転してからの平行移動は等価では無い) ただし、これは変換行列の値を決定するための処理であって、座標変換演算、つまり、ジオメトリパイプラインで行う演算は冒頭の演算で良い筈だ。
しかしながら、この変換行列の値決定のための乗算をソフトウェアで行うと時間が掛かる可能性もあるので、ハードウェアによる外積演算機能も実装したほうがいいかも知れない。

2013年2月22日金曜日

FPGAはハードかソフトか

FPGA(の開発)はハードかソフトかっていう議論をたまに見聞きする。
私がこれまで接してきた人々にしても、年配の技術者(特にアナログ系)にはソフトウェア開発と写るようだし、ソフトウェア技術者には自分たちの分野とは違うと写るようだ。ソフトのようでソフトでなく、ハードのようでハードではなく、その中間的なものだから言ってみればニューハーフみたいなもんか。 いやんっ! ってな感じだな。  な~んて言うのは勿論冗談だ。 ハードかソフトかなんてどうでもいいよね、そんな議論。 技術をソフトだ、ハードだと区別する事自体間違っていると思う。


2013年2月16日土曜日

開発環境等

今週はジオメトリ演算関係を書籍やインターネットから入手した資料から勉強しながら、PC環境の整備や、Android OSのお勉強も始めようと思ってAndroid OSのビルドに挑戦したりを片手間でやったものだから、色々とハマってしまった。

・開発環境
私は自宅では専らLinux OS (現在は Linux Mint 64bit版)を使っている。当然、FPGAの開発環境やシミュレーション環境もLinux OS上だ。 FPGA開発ツールは、 一応、XilinxのISE(含むplanAhead, Vivado)、ALTERAのQuartus、LatticeのDiamondはインストールしてある。私はどちらかと言えばXilinxのFPGAの愛用派(といっても仕事ではFPGAは触っていないので、あくまで趣味上の話)だが、宗教みたいに特定メーカに拘るのはあまり意味がないと考えていて、ALTERAのデバイスもLatticeのデバイスも使いたいと考えている。それに、実際各社の開発ツールやデバイスを使ってみても、それほど大きな差異を感じた事はない、強いて例えればSpartan3とSpartan6程度の違いじゃないだろうか。もっとも、私の場合、ツールの機能として使用しているのは合成からビットストリーム生成までの必要最小限の機能だけなので、差異を感じにくいのかもしれない。  FPGA Editor等のバックエンド的なツールのお世話になることも滅多にないし(決して使えないわけではない。)、ChipscopeやSignalTap等に頼るようになったら負けだと思っている。。。(なんのこっちゃ) 必要最小限の合成制約とDefaultのツールオプションで最高性能を出せる回路記述を出きるようになることが自分自身のテーマだ。キリッ、(再び、なんのこっちゃ) 

ツール類は、/usr/local/edaというディレクトリ下に配置するようにしており、各ツールとも1~2世代前迄のバージョンは残すようにしている。

これらのツール全てを同時に使うことは無いので、環境変数やパスの設定も必要に応じてそれぞれのツール用に行うようにしている。 具体的には各ツール用の設定スクリプトをscriptディレクトリに配置しておいて、必要な時に必要なスクリプトをsourceするようにしている。


Xilinxの場合はインストールディレクトリ・ISE_DS下に標準のスクリプト settings[32|64].[sh|csh]があるが、以下のように若干の変更を加えて使用している。

具体的な変更点は、オリジナルのスクリプトはスクリプトがインストールディレクトリにあることが前提で作成されていて、XIL_SCRIPT_LOCの決定に面倒くさい処理をしているが、これをコメントアウトして、ベタ書きで値(/usr/local/eda/Xilinx/14.4/ISE_DS)を入れるようにしているのと、最下行にsetenv DISPLAY  :0を追加している点だ。 DISPLAY変数の設定はスタンドアローン環境でFPGA Editorを使用する場合に必要で、これを設定しておかないと起動してくれない。ネットワーク越しで使用する場合は逆に悪さする可能性もあるが、自分の環境ではそんな使い方はしないのでこのようにベタ書きしている。

Latticeの場合もインストールディレクトリ・diamond/x.y/bin/lin64/下に標準のスクリプト setupenvがあるが、これも以下のように若干の変更を加えて使用している。

具体的には、set bindir=`pwd`をコメントアウトして、ベタ書きでパス名を設定している。

ALTERA用のスクリプトは以下のようになっている。


Icarus verilog, gtkwave, gpl-cver用のスクリプトはそれぞれ以下のようになっている。

これらのツールには非常に愛着があり、ツールが公開され出した頃からだから、もう10年以上も使い続けている。  gtkwave等は出始めの頃はnull pointer参照に対するケアがされていなくて頻繁に落ちたりしていたのだが今では非常に安定している。開発は今でも継続しているようで最近バージョンが3.3.43に上がった。 圧縮形式の波形ダンプフォーマットであるFST形式をサポートしてくれているのも非常に有難い。 FST形式はIcarus verilogもサポートしているし、gpl-cverについてはPragmatic C社(現 Tachyon Design Automation社)は開発を終了してしまったが、gtkwaveの作者がFST対応させた版を公開している。
http://gtkwave.sourceforge.net/gplcver-2.12a_fst.src.tar.gz
modelsim等の商用シミュレータには独自の圧縮フォーマットがあり、FST形式には対応していないようだ。 gtkwaveのソースツリーを見るとFST dumperのvpiタスクのソースも含まれているのだが、まだ完成形ではないようだ。自分でも色々試行錯誤してコンパイルに成功して、modelsimに組み込んで見たのだが、まともに機能しなかった。(深追いはしていない。)
このvpiタスクが使えるようになると、私としては有難いので、完成版のリリースを楽しみにしている。

Icarus verilogには一つ残念なバグがある。それは、wireネットに対するforceが機能しないというバグだ。 Verilog-HDLにはforce文というのがあって、モジュールを統合した状態で特定のモジュール部のみを検証したい場合や、モジュール間の信号の状態を細かく振りたい場合などに便利な機能だ。例えで言うと、プリント基板に実装された部品の足を浮かせてそこに別の信号をジャンパーで接続する、見たいなことができる。Verilogの規約上はwireに対しても適用可能な筈なのだが、Icarus Verilogはreg属性の信号にしか適用されないようだ。

例えば、上記のコードをmodelsimやgpl-cverでシミュレーションすると以下のような結果になる。

w1をzにforceし、これがw2にまで伝搬しており期待通りの動作だ。
ところが、Icarus verilogの場合は以下のような結果になる。

この問題について、バグレポートを出したところ、暫くして対策版のverilog-20120501が公開されたのだが、その後の公式リリース版であるverilog-0.9.6版では元に戻ってしまった。故に、私は今だに20120501版を使い続けている。バグレポートの提出が最近なのは、それまでforce文は使わないようにしていたのだが最近横着を覚えてしまって、テストベンチのタスク等でforce文を使うようになってしまったからだ。(本業ではFPGAの開発もHDL記述も行っていないのであくまでも趣味上の話だ。) gpl-cverにはそのようなバグは無く、インタプリタなので手軽にシミュレーションできる点が良いのだが、プログラム自体が古く、verilog-2001等の最近(・・・でもないが)の言語規約への対応が不完全だ。 generate文等に対応していないが、これを使わなくても回路記述はできるので、私はHDLを記述する時はなるべくこれらの構文は使わず、どのシミュレータでもシミュレーション出来るようなレベルで記述するように心がけている。

で、環境整備の何にハマったかと言うと、ALTERAのjtagdをudevを使った自動起動に変えようとしてハマってしまった。これまでは、root権限でjtagdを起動してからユーザ権限に戻り、quartus IIやプログラマを起動していた。  udevによる方法はALTERAのドキュメントにも記載されている方法なのだが、何故か私のPC環境では上手く行かず、OSを起動するとUSBキーボードやマウスが使えなくなってしまう。結局、このサイト(https://help.ubuntu.com/community/QuartusII)を参考にして、OS起動時にjtagdを起動して常駐させておくようにした。

・Android
Androidのビルドでもハマった。 最近AvnetのZynq搭載ボード(ZedBoard)に関心が芽生え始めている。このボードでAndroidを動かして見ようかしら、それが可能ならボードを購入しようかどうしようかと思案している。その前にAndroidのビルドがどんなものか体験しようと思って、Linux上でのビルドに挑戦してみたのだがなかなか成功しない。私はシェルはtcshを使っているのだが、Androidをビルドする場合はbashにする必要がある。が、それだけでは不十分で、環境変数であるSHELLにもbashのパスを設定しておく必要があった。私の場合は、この変数がtcshのままになっていたために、ビルドの途中で32bit版コンパイラでコンパイルしたオブジェクトを64bit版アーカイバ(ar)でアーカイブしようとして失敗するという訳の判らない状態になってしまっていた。 SHELLの設定を修正したら無事ビルドできるようになった。で、Zynqボードだが、高いんだよねー。4万円強だもんなー。どこかがもっと安い奴を出してくれないかな。

だらだらと書いてきたら長くなってしまった。ジオメトリ演算関係は別記事に書くことにしよう。


2013年2月9日土曜日

3Dレンダリングパイプライン

ということで、次は3Dレンダリングパイプライン(3Dレンダラー)の作成に挑戦してみることになった。 匿名の方から3Dレンダリングパイプラインをやったらというコメントを頂いた。 3Dグラフィック関係は本を読んだり、OpenGLで少し遊んだ程度の知識しか無いが、面白そうだし、いつかやってみたいと思っていた。また、数値演算回路ももっと経験したいので、次のテーマとして選んだ。

上に書いたとおり3Dグラフィクスの描画回路というのは経験ないのだが、2Dの超簡単なものなら経験している。dvi_encにはデモ機能として以下のようなスプライトが組み込まれている。
これは、64x64ピクセルのTux(Linuxのマスコット)君の画像が回転しながら画面内を移動するというもので、VRAMやフレームバッファを使わずに動的に座標計算しながら表示している。
video

以下がその部分のRTLだ。


原点に対する座標(x,y)の回転は、回転後の座標をx', y' とすると、

   x' = x cosΘ - y sinΘ
   y' = x sinΘ + y cosΘ

で求まる。上記RTLでは基本的にこの計算を行っている訳だが、同期信号生成部からは入力として回転後の座標が入ってくるので、イメージ的に逆方向の演算を行っている。つまり、入力された座標値(x', y')からx, yを求め、これがTux画像の範囲に入っているか否かを判定し入っている場合は対応するピクセル値を出力している。

さて、3次元グラフィクスだが、Wikipediaの「グラフィクスパイプライン」やその他サイト等の情報から、3次元グラフィクス描画処理はジオメトリ演算とピクセル演算に大別されるようだ。モデル(描画する物)は個々に幾何的情報(寸法等)と色、質感(光の反射率等)の情報を持つ。これらのモデルを共通の3次元空間(ワールド座標系)に配置し、それらが視線方向に直角な平面(スクリーン座標系)に投影されることで立体的な画像になる。ジオメトリ演算はこれらの座標の演算処理で、モデリング変換(ローカル座標系からワールド座標系への変換→物体をワールド座標に配置)、陰影づけ、視点変換(視点座標系への変換)、投影変換(クリッピング処理)、ビューポート変換等を行うようである。その後のラスタライゼーション処理でピクセル演算処理が行われるらしい。

まずはジオメトリ演算系の検討から始めようと思う。


2013年2月3日日曜日

DFT IPの作成 21

あっ! ....................................................................................................... っと言う間にもう2月だ。


DFT IPの作成を開始したのが昨年の10月27日だからもう4ヵ月近くやってるのか。
前回、固定小数版は32bit版でまっいっか!ということにしたので、後回しにしていたメモリへの書き込み機能をやろうかと考えた。DFTの結果をメモリに書き出してどうしたいかというと、最終的に以下のような3D表示をなるべくリアルタイムに近い速度でやって見たかったからだ。


このDFT IPはサンプリング周期毎に1024@CH分のスペクトル値が算出されるので、これをメモリに書出しておいて、CPUで上記のような3Dグラフに変換して描画できれば面白いかなと考えたのだが、よくよく考えると、Atlysボードのメモリ容量が全然足りない。   Atlysボードには128MByteのDDR2 SDRAMが搭載されている。 スペクトルデータは32bit floatで複素数形式なので、1024点で 4Byte x 2 x 1024 = 8KByteになり、サンプリングレートを最高の48KHzとした場合は秒当たり 8K x 48000 = 375MByteと、かる~く 128MByteを越えてしまう。。。間引くかサンプリングレートを下げるかしないととても無理だ。 また、間引いてメモリに書き込んだとして、今度はメモリのデータをPCにどう転送するかが問題になる。現状USB-Serialは1Mbps(100KByte/sec)弱しか出せていないので、帯域が全然たりない。。。

ということで、メモリ書き込み機能へのモチベーションが失せてしまった。

ここらでDFTネタは一区切りして、他のネタに移ろうかな? それとも、DFT-IPのALTERA版(DE0への実装)をやってみようか?。。。


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

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