コードの確認を開始

まやさんから預かったTOPPERS/JSPのBf506ポートのチェックをはじめました。
VDSP++でしかビルドを確認していないとのことで、まずはGCC用へコードの整形を開始しています。幸いなことに、現在プロジェクトのインストーラが使っているgnu toolchain 2010R1 は、BF50x, B59xまで対応しており、ビルドに当たって自分でレジスタアドレスを入力する必要はありません。
とりあえずコンパイルは通り、リンクでフェイルしています。LDスクリプトに何かある模様。

GDBによるターゲットのリセットに関する進展

これまで、TOPPERS/JSP for BlackfinアプリケーションはGDBからプログラムをロードする場合に非常に面倒な手続きが必要でした。
この理由は、GDBからのターゲットリセットがうまくいかないことになりました。TOPPERS/JSPアプリケーションはリセット状態から動作することを前提としているため、プログラムの実行開始状態が例外や割り込みといった実行レベルにあると、正しく動作しません。また、内部ペリフェラルレジスタの状態によっては、やはり正しく動作しないことが考えられます。
VisualDSP++のICEは、この点を明示的に操作できますし、きちんとリセットできます。しかし、これまでbfin-gdbproxyとbfin-elf-gdbのペアではきちんとしたリセットができませんでした。ツールチェーンのビルド/開発もとであるBlackfin Koopにも聞いてみましたが、要領をえませんでした。
さて、今回maduki_kさんによるADSP-BF506へのTOPPERS/JSPへの移植が行われていることを契機に、再度ブートコードやbfin-gdbproxy、bfin-jtagを見直しました。そして、bfin-jtagのコマンドのhelpからたどって、どうやら、bfin-elf-gdbを使ってターゲットを正常にリセットすることができたようです。
手順は以下のようになります。
最初にbfin-gdbproxyを使ってターゲットに接続します。
次にbfin-elf-gdbを起動し、以下のコマンドでターゲットに接続します。

(gdb) target remot localhost:2000

ここまでは今までと変わりません。ここで次のコマンドを発行します。

(gdb) monitor urjtag bfin reset

これで、gdbproxyに組み込まれているurjtagから、blackfinに向けてリセットコマンドを発行します。この後、アプリケーションをロードして実行すると、正しく実行されました。まだ短い試験しか行っていませんが、どうやら大丈夫のようです。
うまくいくならトリッキーなデバッグ時ブートに頼る必要がなくなります。

TOPPERS/JSP for Blackfin更新

いくつかの更新を行っています

Kobanzame用talkthrough

Kobanzameで動くTalkthroughコードのgcc版のCVSモジュールを作りました。

プログラムを展開し、make depend; makeでビルドが完了します。動作は検証済みです。

Toolchain 2010R1 RC4対応

昨年出たツールチェーンへの対応を怠っていましたが、インストールスクリプトを作り、ビルドしたアプリケーションのKobanzame基板での動作を確認しました。インストールスクリプトubuntu 10.04用のものです。スクリプトリリースファイルからダウンロードできます。

Real FFT補足

先日書いたReal FFTについて少し補足しておきます。
FFTのこのようなふるまいの背景は、基礎になるフーリエ変換カーネル

exp(-jwt)

の形を取る*1ことにあります。expt(-jwt)は、cos(wt)/2 - jsin(wt)/2ですから、変換結果の実分は偶関数に、虚部は奇関数になります。線対称、点対称といった性質はここからきています。

*1:ちょっとはしょりすぎてるけど

80bit += 32bit * 32bit

16bit DSPMAC演算の構成は念仏のように十年一日 40bit += 16bit * 16bitとなっています。符号付き16ビット固定小数点演算*1では、積の形式がQ30*2となります。これを32bitにそろえてQ31とし、あふれ対策に8ビットの整数ガードを追加すれば、40bitとなります。
この形式のMAC演算は

  • 256タップまでのFIRを実行しても、絶対に整数があふれない
  • FIR演算の途中では絶対に丸め誤差が発生しない

という二つの強力な特性があるため、黄金比のごとく扱われています。この思想は24bit DSPであるDSP56000では 56bit += 24bit * 24bitとなってその名前の由来となり、32bit DSPであるSHARCでは、80bit += 32bit * 32bit 構成を持たせるに至っています。
しかしながら、最近ではこの構成は劣勢になっています。まずLSI設計の面から言うと、80bitのアキュームレータを高速化するのはかなり面倒です。ピーク性能を追求したければパイプラインを伸ばして周波数を上げざるを得ず、消費電力も上がります。
さらに、アキュームレータがこういう構成だと、大並列のSIMDを組みにくくなります。
これに対して「いやそれではあふれや丸めの問題が」という声が上がるわけですが、本当に必要なのか考えてみろよ、と言われると答えに窮することになります。
16bit信号処理の場合、そもそもダイナミックレンジが96dBしかないため、演算精度に対して神経質にならざるを得ませんでした。仮に16bit += 16bit * 16bitの構成でMACを行う度に0.5LSBの雑音が追加されると、256タップのFIRフィルタでは実に雑音は8LSBに達します*3。有効ビットは13LSBとなり、Q12相当のデータになります。しかし、32bit += 32bit * 32bitの場合、同じ256タップFIRを実行しても、有効ビットは29bitあり、28bit相当精度です。
また、位相直線フィルタの伝達関数も自然信号の波形もそれほど突拍子もないものにはならないため、そもそも8bitものガードが必要である局面はわずかです。ないとは言い切れませんが、それほど特殊なアルゴリズムであれば特殊なプログラムをすればいいだけで、普通のアルゴリズムがそれにつき合ってハードウェアの足かせに賛同する義理はありません。
幸い、信号処理の代表的アルゴリズムは線形です。Q31でFFTとFIRを用意しておけば、信号側をスケーリングするだけで、Q23だろうがQ24だろうが、好きなフォーマットに対応できます。

*1: 1.15 または Q15フォーマット

*2:あるいは1.30

*3:同じ振幅の雑音を256回たすと、振幅はSQRT(256)=16倍になる。もちろんエネルギは256倍

gdbとブート

TOPPERS/JSPには「GDBデバッグ時リセット能力が弱いので」特別なコードを入れているのですが、今頃になって、これ、私が書いたJSPのリセット後初期化コードの問題じゃないかという気がしてきました。
今のところ「気がする」だけですが、時間を見てu-bootのリセット後初期化コードと比べてみます。