何の事は無い、積和演算を高速で処理したいが為の DSP命令です。
そして DSP命令をしないと普通の 16bit/PICマイコンです。
其れが DSP命令をした途端に、DSPエンジンに火が入り変貌します。
当然の如く DSP命令が終ると・・・普通のPICマイコンに戻ります。
以上で DSPの話は終りです。(・・・オイオイ)
そして DSP命令をしないと普通の 16bit/PICマイコンです。
其れが DSP命令をした途端に、DSPエンジンに火が入り変貌します。
当然の如く DSP命令が終ると・・・普通のPICマイコンに戻ります。
以上で DSPの話は終りです。(・・・オイオイ)
では具体例を示して進みます。
DSP命令のプログラムは全てアセンブラでしか書けません。
私は素人なのでインライン・アセンブラを使いました。
メーカでは推奨しない asm("*********");形式ですね。
私は素人なのでインライン・アセンブラを使いました。
メーカでは推奨しない asm("*********");形式ですね。
DSP演算で扱える「数」の範囲は 16bit/正負・固定小数点表示で、具体的には (+1~0~-1)の狭い範囲です。
下に前回の (k0)~(k10)の値を16進・固定小数点に変換したデータを書いておきます。
下に前回の (k0)~(k10)の値を16進・固定小数点に変換したデータを書いておきます。
k0=-0.005---->0xFF5C
k1=-0.007---->0xFF1B
k2=0.015----->0x01EC
k3=0.104----->0x0D50
k4=0.233----->0x1DD3
k5=0.296----->0x25E3
k6=0.233----->0x1DD3
k7=0.104----->0x0D50
k8=0.015----->0x01EC
k9=-0.007---->0xFF1B
k10=-0.005--->0xFF5C
k1=-0.007---->0xFF1B
k2=0.015----->0x01EC
k3=0.104----->0x0D50
k4=0.233----->0x1DD3
k5=0.296----->0x25E3
k6=0.233----->0x1DD3
k7=0.104----->0x0D50
k8=0.015----->0x01EC
k9=-0.007---->0xFF1B
k10=-0.005--->0xFF5C
そして上記の係数データを予めデータメモリに格納します。
アドレスは 0x1600からにしました。
方法は色々有るようですが、一番原始的なやり方で・・・
asm("mov #0x1600,W1");
asm("mov #0xFF5C,W0\nmov W0,[W1++]");
asm("mov #0xFF1B,W0\nmov W0,[W1++]");
asm("mov #0x01EC,W0\nmov W0,[W1++]");
asm("mov #0x0D50,W0\nmov W0,[W1++]");
asm("mov #0x1DD3,W0\nmov W0,[W1++]");
asm("mov #0x25E3,W0\nmov W0,[W1++]");
asm("mov #0x1DD3,W0\nmov W0,[W1++]");
asm("mov #0x0D50,W0\nmov W0,[W1++]");
asm("mov #0x01EC,W0\nmov W0,[W1++]");
asm("mov #0xFF1B,W0\nmov W0,[W1++]");
asm("mov #0xFF5C,W0\nmov W0,[W1++]");
}
asm("mov #0xFF1B,W0\nmov W0,[W1++]");
asm("mov #0x01EC,W0\nmov W0,[W1++]");
asm("mov #0x0D50,W0\nmov W0,[W1++]");
asm("mov #0x1DD3,W0\nmov W0,[W1++]");
asm("mov #0x25E3,W0\nmov W0,[W1++]");
asm("mov #0x1DD3,W0\nmov W0,[W1++]");
asm("mov #0x0D50,W0\nmov W0,[W1++]");
asm("mov #0x01EC,W0\nmov W0,[W1++]");
asm("mov #0xFF1B,W0\nmov W0,[W1++]");
asm("mov #0xFF5C,W0\nmov W0,[W1++]");
}
一応、DAT()と云う関数の形で書きました。
尚、固定小数点に付いての疑問は有ると思いますが、此処で其れを解説すると終らなくなるのでやりません。(解説したいですが、よく解らない)
興味の有る方は専門書をお読み下さい。
興味の有る方は専門書をお読み下さい。
此処から、お待ちかねの DSP命令・積和演算に入ります。
では、いきなり・・・
では、いきなり・・・
mac W4*W5,A,[W8]+=2,W4,[W10]+=2,W5・・・です。
mac :通称マックと呼ばれる?積和演算の大本命です。
他の命令は此の mac命令をスムーズに働かせる為にあると云っても過言ではない?
Wn :ワーキング・レジスタと呼ばれ、W0~W15まで有り数値の出し入れに使いますが、特に mac命令では W4~W11が特別な意味を持ちます。
[Wn] :Wnで指定したデータアドレス内容を示します。
A :アキュムレータと呼ばれ A/B2個有り、一時的補助タンクの役目をします。
でも容量?は 40bitあり(たぶん)かなり加算しても大丈夫です。
しかも取り出すときは肝心な部分を 16bitで取り出します。
しかも取り出すときは肝心な部分を 16bitで取り出します。
W4*W5,A :W4とW5を掛け算(積)した結果を Aに格納する。
macの場合は格納前 Aに存在したデータに加算する形で格納します。
つまり此の部分だけで積和演算が成立です。
尚、使えるレジスタは W4,W5,W6,W7です。
つまり此の部分だけで積和演算が成立です。
尚、使えるレジスタは W4,W5,W6,W7です。
[W8]+=2,W4 :W8で指定されたアドレス内容を W4にコピーして、其の後 W8を+2する。
時系列で積和演算の後なので W4の内容は此処で上書きされます。
尚、使えるレジスタは Xメモリ用で W8,W9です。
時系列で積和演算の後なので W4の内容は此処で上書きされます。
尚、使えるレジスタは Xメモリ用で W8,W9です。
[W10]+=2,W5 :同上ですが、使えるレジスタは Yメモリ用で W10,W11です。 今回は Yメモリを使わないので macの此の部分は使いません。
因みに以上の事柄を mac命令は 1サイクル/40MHzでこなします。
さすが dsPICです・・・速いですね~。
この辺までの内容でしたらネットで何とか拾えますが、此の後の「実際のプログラムはドウヤルの~」は残念ながら極端に情報が減ります。
次回は実際に mac命令を動かす事を考えます。
前後に配置される命令との絶妙なバランスに苦心しました。
by JA1QVM
PS:全くの素人爺さんが趣味でやってる内容です。パクる人は自己責任で・・・