2012年12月1日土曜日

DFT IPの作成 7


乱れている~、乱れている~、検量線っがー、
おーかしいよとー、言われるけどー、しーかたがない~のー

っていうフレーズが何故か頭の中でリフレインしている今日この頃如何お過ごしでしょうか?
あれは、黒木真由美の感情線だっけか?、懐かしいなぁー、あの頃は俺も若かったぁ、
色んなとこブヒブヒ言わせてさぁー、、、、太ってたからねぇー
それが、今じゃ、こんなに痩せ細っ・・・、あれ?、細ってない。むしろ増えてる!!! おっかしいなー

なーんて言うおバカキャラはこれぐらいにして、DFT IPのデバッグだ。
いやー、ストレスが溜まってるときはこの位バカして発散しないと、ねぇ?

元々考えていた方式でやると、入力がゼロになってもアキュムレータRAMに値が残り、時間経過と
共に増加していくという問題が出た。以下はその様子だ。

画像では、入力値がゼロになってからのスペクトルの成長が分かり辛いが、じっと眺めてると、
所々で少しずつ成長しているのが分かる。
入力値がゼロになっていく過程で、アキュムレータRAMの値も減少していく筈なので、値が残るという事自体おかしな事なんだが。

やっている事(回路で処理している事)は、


という演算で、入力値ゼロの状態が継続すると、Xp-Xp-Nは0-0になるから、S(f,p)は増えもしなけりゃ、減りもしない筈で、正に何も足さない・何も引かない状態になる筈だ。が、その絶対値であるスペクトルが徐々に成長するってことは、上記演算過程で何らかの要因でプラス方向の誤差が発生していると考えられる。また、S(f,p)は複素数であり、これに複素数の定数が掛かる訳だから、exp(jα) x exp(jβ) = exp(j(α+β))な訳で、複素平面で考えると、ベクトルを常に回転させていることになるが、これが誤差により外側に膨らんでいっていると考えられる。

そこで、S(f,p)に1.0より小さい縮小係数を乗じて見ることにした。但し、その為に態々乗算器を追加するのは回路の無駄なので、正弦波テーブル(exp(j2πf/N)のテーブル)の値を縮小することにした。具体的には以下のプログラムでテーブルを作り直した。

0.9999fが縮小係数だ。 上図の通り、これ以外の値も試してみたが0.9999より大きいと効果が弱かったり、まったく効かなかったりだった。

このテーブルを使って上記と同じデータを再生してみたのが以下の画像だ。

でも、良く良く考えてみると、何かおかしい。 Cモデルでの検証ではこういう現象は出てなかった。
32bit浮動小数点データは仮数部が24bit(省略されている最上位の1を含む)のみであり、位の違う数値同士を演算した場合、当然ながら、その有効桁の範囲外に値が出ることもある。この場合に丸め処理を行う訳であるが、これは「最近点への丸めモード」としてIEEE754で規定されている。っていうことが色んな文献に書いてあるが、CQ出版の「ディジタル数値演算回路の実用設計」という書籍の表6-2がとても解りやすい。 この丸め処理がcoregenで生成した浮動小数演算器と、Cの処理系とで違うのかな?と考えて検証してみたが同等だった。

それではということで、単一正弦波のデータを作って再生させて線スペクトルになるかを見てみた。


その結果が上記画像で、線スペクトルになっているが、右端にも想定外のスペクトルがいる。
DFTは2048点で演算していて、その内の半分の1024点を表示しているので、折り返しは表示されない筈だし、Cモデルによる検証でも、また、DFTモジュールの単体シミュレーションでも表示されていない。
おまえ・・・誰? (-_-;
ってな感じだ。

どっかバグってんのかな?、全体でシミュレーションやってみるか。


0 件のコメント:

コメントを投稿

自作CPUで遊ぶ 25

まだ制御ソフトが完成していないので今まではスピンドルを移動するために一々簡単なプログラムを書いて移動させていたのだが、非常に面倒なのでCNCペンダント的なものを作ることにした。 右側の縦に2つ並んでいるスイッチ...