2023年8月7日月曜日

BlackFinを使ってみるなり(6) FIRフィルタの演算

こんちわー.小学生から回路ヲタクのひらりんです.

BlackFinのreferenceを読んでポエムを呟きます.

パソコンのCPUは浮動小数点演算をするので、sin,cosみたいな関数も浮動小数点を突っ込んで浮動小数点が出てきます.浮動小数点は贅沢なゆえに扱いは楽です.

一方でBlackFinは固定小数点方式のDSPです.固定小数点はhardwareが軽くて済むのですが、位取りとか桁溢れを設計者がケアしてやらないと、信号処理中にdataがサチったりして死んじゃいます.
わたしはかつてLSI設計をやっていて、FIRだのIIRだのを固定小数点演算回路(verilog)で実装するのが仕事でした.当ブログで「固定小数点演算シリーズ」を少し書いて尻切れになってしまっていますが、そこに書いたようなかったるさが固定小数点演算回路にはつきまといます.

今回はBlackFinの固定小数演算界隈がどーなってるのかを調べました.

ポエム1
固定小数点のデータ形式について.
dataのbit assignはこんなものがあるそうです.特に疑問はないです.
16bitだけど、複素数を扱えるのはイイね!
例として1.31の意味は、MSBが符号bitで、残り31bitは0.999...~-0.999を表現する二進小数です.

掛け算したらどうなるか?
1.31 signed fractional × 1.31 signed fractional = 1.63
32.0 signed or unsigned × 32.0 signed or unsigned = 64.0
桁溢れ無しということですが、Cで書く人はこれらを人力でどの程度ケアせないかんのか、そこは不明です.

1.63なんか出て来られても次の演算が困るので1.31に丸め(切り捨て)ないかんわけですが、Cで書く時に人力ケアがどの程度必要なのかも不明です.丸めを指定するレジスタが在るようです.

丸めの際に四捨五入を自動的にやってくれるとかないのかな?
「Biased Rounding」という言葉が出てきます.これって四捨五入のことっぽいです.つまりhardwareで四捨五入もやってくれるみたいな感じがする.こうゆうところはCPUには無いDSPゆえの工夫かなと思ふ.

演算をMACでやるかALUでやるかをC sourceで明示するものなのか?

Accumulator Registerをどうやって使うのかな?

判らないことがたくさんです.


ポエム2
ネットで拾ったFIR codeを見よう.
GithubのこれがBlackFinのFIR codeの例です.
FIR filterのキモの部分はここですが、上で疑問を呈したような、固定小数点演算をケアするような操作は一切やってません.intでベタな演算してるだけです.こんなんでいいの? コンパイラ任せってこと?
  output += Coefficients[Index][i]* Buffer[(currIndex - i + LEN) % LEN];


ポエム3
別の例を探しました.
金子システムという会社がBF706のプリント基板を販売しています.
そのsample codeページにFIRがあります.
「fir_fr32関数を使ったFIRフィルタのコード例です」
というのをDLすると、、、FIRのキモのところがこうなっています.
 fir_fr32(sf_input, sf_output, NUM_SAMPLES, &sf_fir_state);
要はfir_fr32という関数を呼び出しているのですが、これの正体は何でしょうか?

CrossCoreで提供されている様々なヘッダファイルがここにあります.
C:\Analog Devices\CrossCore Embedded Studio 2.11.1\Blackfin\include
この中の、filter.hというのに、AD社提供のフィルタ関連関数がたくさんあります.
ほんの一例ですが、
 fir_fr32() ←FIR filter
 iir_fr32() ←IIR filter
 cfft_fr32() ←複素FFT
便利じゃんこれ.
これらの関数に固定小数点演算の厄介事が詰め込まれているのだと想像します.具体的に何をやっているのか知りたくて、filter.cを探したのだけど見つかりませんでした.binaryで提供されてるのかな.

というわけで固定小数点演算の厄介事をどう処理しているのかは迷宮入りでした.残念.

ポエム3
固定小数点の諸関数はどうなってるんでしょう?
上のと同じincludeフォルダに、math_bf.hというのがあります.
この中に固定小数点の関数がいろいろあります.例えばsin,cosはこんなのがあります.
 fract16 sin_fr16 (fract16 _x);
 fract32 sin_fr32 (fract32 _x);
 fract16 cos_fr16 (fract16 _x);
 fract32 cos_fr32 (fract32 _x);

これらも中身は不明なんですが、便利に使わせてもらいます.

5へ    7へ

かしこ

6 件のコメント:

  1. 入力は正規化して、フィルタ係数もステップ応答が1を超えないようにしてやれば、とりあえずオーバーフローはしないですね。
    関数の中身はアセンブラで書かれてるんでしょう。Cで書いて1Tap/CycleのFIRが出来たらすごい(笑)。しかし、ライブラリの形でちゃんと提供されてるのは良いですね。

    返信削除
    返信
    1. >ライブラリの形でちゃんと提供

      そうですね、とても助かります.それを使わしてもらいましょう.でもsourceが見当たらないのがちょっとかったるいかなぁ.円満に使えると良いのですが.

      早いの好きよ.

      削除
    2. >円満に使えると良い
      dsPICにも、同様に、MicroChip提供ライブラリがあるのですが、
      「遅くて使えない」ということで、自分で書いてる人が居ました。

      削除
    3. あははー
      tuneが足りないライブラリとは.

      削除
  2. >16bitだけど、複素数を扱える
    これはなにげにスゴイですね。I/Q信号の計算とか、一発で出来ちゃう。これで、SDR作りたくなってきた・・・
    (でも、趣味に「こんなに高い開発環境」は買えないので、暫くはガマンするか・・・)
    つか「開発ソフト」まで有償って、結構強気ですね。最近は、メーカー品も、コンパイラはGNUだったりして、「無償」のモノも多いのですが。

    返信削除
    返信
    1. いまどき環境はfreeでお願いしたいです.
      もしかしたらVScodeとかのような別の環境があるのかもしれません.調べてないだけで.

      ちなみに、金子システムはBF706基板を¥6800で売ってるみたいです.
      http://dsps.shop-pro.jp/?pid=95105364

      削除