dsPIC33AKシリーズ⑤DSPについて

dsPIC33Aシリーズ

概要

今回はdsPIC33AKシリーズの強化されたDSPの性能について検証します。

更新日更新内容
24/8/21初版
25/3/24リンク先追加

関連記事

内部リンク

記事リンク
第1回dsPIC33AKシリーズについてdsPIC33Aシリーズに関して – ぴくおの電子工作的な何かWP (electricpico.com)
第2回開発ボード、コンフィグレーション設定、クロック設定についてdsPIC33AKシリーズ②開発ボード,コンフィグレーション設定,クロック設定について – ぴくおの電子工作的な何かWP (electricpico.com)
第3回CPU性能についてdsPIC33AKシリーズ③CPU性能について – ぴくおの電子工作的な何かWP (electricpico.com)
第4回FPU性能についてdsPIC33AKシリーズ④FPU性能について – ぴくおの電子工作的な何かWP (electricpico.com)
第5回 (本記事)DSPについてdsPIC33AKシリーズ⑤DSPについて – ぴくおの電子工作的な何かWP
第6回タイマー1割り込みの使い方dsPIC33AKシリーズ⑥Timer1割り込みの使い方 – ぴくおの電子工作的な何かWP (electricpico.com)
第7回PMUの使い方dsPIC33AKシリーズ⑦PMUの使い方 – ぴくおの電子工作的な何かWP (electricpico.com)
第8回高速ADCの使い方dsPIC33AKシリーズ⑧高速ADCの使い方 – ぴくおの電子工作的な何かWP (electricpico.com)
第9回高速OPAMPの使い方dsPIC33AKシリーズ⑨高速OPAMPの使い方 – ぴくおの電子工作的な何かWP (electricpico.com)
第10回DMAモジュールの使い方dsPIC33AKシリーズ⑩DMAモジュールの使い方 – ぴくおの電子工作的な何かWP (electricpico.com)
第11回WDTモジュールの使い方dsPIC33AKシリーズ⑪WDTモジュールの使い方 – ぴくおの電子工作的な何かWP (electricpico.com)
第12回DMTモジュールの使い方dsPIC33AKシリーズ⑫DMTモジュールの使い方 – ぴくおの電子工作的な何かWP (electricpico.com)
第13回I/Oインテグリティモニタモジュールの使い方dsPIC33AKシリーズ⑬I/Oインテグリティモニターモジュールの使い方 – ぴくおの電子工作的な何かWP (electricpico.com)
第14回QEIモジュールの使い方dsPIC33AKシリーズ⑭QEIモジュールの使い方 – ぴくおの電子工作的な何かWP (electricpico.com)
(fig.1-1)各関連記事リンク

外部リンク

タイトルリンク先
XC-DSCライブラリリファレンスマニュアル
(PDF)
MPLAB XC-DSC Libraries Reference Manual
XC-DSCライブラリリファレンスマニュアル
(オンライン)
https://onlinedocs.microchip.com/oxy/GUID-70ACD6B0-A33F-4653-B192-8465EAD1FD98-en-US-11/index.html
XC-DSCコンパイラユーザーズガイド
(オンライン)
MPLAB XC-DSC C Compiler User’s Guide

開発環境

開発環境を以下に示します。
今回はどちらのCPUボードでも動作いたします。

項目リンク
ベースボードdsPIC33A CURIOSITY PLATFORM
DEVELOPMENT BOARD
dsPIC33A Curiosity Platform Development Board User’s Guide (microchip.com)
CPUボード(EV68M17A)EV68M17A – dsPIC33AK128MC106 Motor Control DIMdsPIC33AK128MC106 Motor Control Dual In-Line Module (DIM) Information Sheet (microchip.com)
CPUボード(EV02G02A)dsPIC33AK128MC106 General Purpose Dual In-Line Module (DIM)dsPIC33AK128MC106 General Purpose Dual In-Line Module (DIM) | Microchip Technology
統合開発環境MPLAB X IDE v6.20MPLAB® X IDE | Microchip Technology
コンパイラMPLAB XC DSC v3.10MPLAB® XC DSC Compiler | Microchip Technology
(fig.2-1)本記事の動作確認環境

(fig.2-2)ベースボード+CPUボード

概要

dspPIC33AKシリーズのDSP(*1)の乗算器は33×33ビットをサポートするようになりました。アキュムレータも従来の2×40ビットから2×72ビットに拡張されているため、従来は演算が飽和していた処理でも、より演算が飽和しにくくなりました。またMAC命令も改良され任意のワーキングレジスタを利用可能、またプリフェッチも必要としないため、構文が大幅に改善されています。

(*1)DSPとは

DSP(Digital Signal Processor、デジタル信号プロセッサ)とは、デジタル信号処理に特化したマイクロプロセッサのことを指します。DSPは、音声、画像、ビデオ、センサーデータなどのデジタル信号をリアルタイムで処理するために設計されています。これにより、DSPは通信、マルチメディア、医療機器、産業オートメーションなど、幅広い応用分野で使用されています。

DSPブロック図

下記にDSPブロック図

(fig.4-1)DSPブロック図 (70005539B – p66より抜粋)

DSP命令

命令機能代数的等価
MAC乗算してアキュムレータに加算、
または二乗してアキュムレータに加算
a = a + b * c a = a + b2
MSC乗算とアキュムレータからの減算a = a – b * c
MPY乗算a = b * c
MPYN乗算と符号反転a = -b * c
SQR二乗a = b ^ 2
SQRAC二乗してアキュムレータに加算a = a + (b ^ 2)
ED差の二乗a = (b – c)2
EDAC差の二乗をアキュムレータに加算a = a + (b – c)2
(fig.5-1)DSP命令

DSPライブラリ

下記にDSPライブラリを示します。
<dsp.h>のインクルードと’libdsp-elf.a.’のライブラリ読込が必要です。

■ベクタ関数

関数名機能
VectorAddソース1ベクトル内の各要素の値を、ソース2ベクトル内の対応する要素と加算し、その結果をデスティネーションベクトルに配置します。
VectorConvolve2 つの入力ベクトル間の畳み込みを計算し、その結果を出力ベクトルに格納
VectorCopyソースベクトル内の各要素の値を、デスティネーションベクトル内の各要素にコピー
VectorCorrelate2 つの入力ベクトル間の相関を計算し、その結果を出力ベクトルに格納
VectorDotProductソース 1 およびソース 2 ベクトルの対応する要素間の積の合計を計算
VectorMaxベクトル内の最大値を算出
VectorMinベクトル内の最小値を算出
VectorMultiplyソース1ベクトルの各要素の値とソース2ベクトルの対応する値を乗算し、
結果をデスティネーションベクトルの対応する要素に配置
VectorNegateソースベクトル内の各要素の値を、デスティネーションベクトル内の各要素に符号を反転してコピー
VectorPowerソース・ベクトルのパワーを、その要素の2乗の和として計算
VectorScaleソースベクトルのすべての要素の値をスケール値でスケーリング(乗算)し、その結果をデスティネーションベクトルに配置
VectorSubtractソース2ベクトルの各要素の値を、ソース1ベクトルの対応する値から引き、結果をデスティネーションベクトルに配置
VectorZeroPadVectorZeroPadは、コピー元ベクトルを(すでに存在する)コピー先ベクトルの先頭にコピーし、コピー先ベクトルの残りのnumZeros個の要素をゼロで埋める
(fig.6-1)ベクタ関数

■ウィンドウ関数

関数名機能
BartlettInitバーレット窓を初期化
BlackmanInitブラックマン窓を初期化
HammingInitハミング窓を初期化
HanningInitハニング窓を初期化
KaiserInitカイザー窓を初期化
VectorWindow指定された入力ベクトルにウィンドウを適用し、その結果生じるウィンドウ付きベクトルを出力ベクトルに格納
(fig.6-2)ウィンドウ関数

■マトリックス関数

関数名機能
MatrixAdd入力行列 1 の各要素の値を、入力行列 2 の各要素の値と加算し、その結果を出力行列に格納
MatrixMultiply入力行列 1 と入力行列 2 の間の行列乗算を実行し,結果を出力行列に格納
MatrixScale入力行列のすべての要素の値をスケール値でスケーリング(乗算)し,その結果を出力行列に配置
MatrixSubtract入力 2 行列の各要素の値を,入力 1 行列の各要素の値から減算し,その結果を出力行列に格納
MatrixTranspose入力行列の行を列で転置し,その結果を出力行列に配置
MatrixInvert入力行列の逆行列を計算し,その結果を出力行列に格納
(fig.6-3)マトリックス関数

■フィルター関数

関数名機能
FIRFIRフィルターの実行
FIRDecimateFIRフィルターとデシメーションの実行
FIRDelayInitFIRStructフィルター構造体の遅延値をゼロに初期化
FIRInterpolateソースサンプルをアップサンプルしFIRフィルターを実行
FIRInterpDelayInitIR補間フィルター用に最適化されたFIRStructフィルター構造体の遅延値を
ゼロに初期化
FIRLattice格子構造の実装を使用して、ソースサンプルのシーケンスにFIRフィルタを適用
FIRLMS適応FIRフィルタの実行
フィルタ係数は、参照サンプルの値に応じて適用される最小平均二乗アルゴリズムを使用して、サンプルごとに更新
FIRLMSNorm適応FIRフィルタの実行
フィルタ係数は、参照サンプルの値に応じて適用される正規化最小平均二乗アルゴリズムを用いて、サンプルごとに更新
FIRStructInitFIRStruct FIRフィルター構造体のパラメーターの値を初期化
IIRCanonicソースサンプルのシーケンスに、カノニック(直接形II)2次セクションのカスケードを使用して、IIR フィルタを適用
IIRCanonicInitIIRCanonicStructフィルター構造体の遅延値をゼロに初期化
IIRLattice格子構造の実装を使用して、ソースサンプルのシーケンスに IIR フィルタを
適用
IIRLatticeInitIIRLatticeStructフィルター構造体の遅延値をゼロに初期化
IIRTransposedソースサンプルのシーケンスに、転置された(直接形式II)2次セクションの
カスケードを使用して、IIRフィルタを適用
IIRTransposedInitIIRTransposedStructフィルター構造体の遅延値をゼロに初期化
(fig.6-4)フィルター関数

■変換関数

関数名機能
BitReverseComplex複素数ベクトルの要素をビット逆順に並べ替えを実行
BitReverseReal32bIP32ビット実数ベクトルの要素をビット逆順に並べ替えを実行
CosFactorInitII型離散コサイン変換で必要とされるコサイン係数のセットの前半を生成し、その結果を複素数の出力ベクトルに配置
DCTソースベクトルの離散コサイン変換を計算し、その結果をデスティネーションベクトルに格納
DCTIPソースベクトルの離散コサイン変換を計算
FFTComplexソース複素数ベクトルの高速フーリエ変換を計算し、結果をデスティネーション複素数ベクトルに格納
FFTReal32b32ビット実数ソースベクトルの32ビット高速フーリエ変換を計算し、結果を32ビット実数デスティネーションベクトルに格納
FFTComplexIPソース複素数ベクトルの高速フーリエ変換を計算
FFTComplex32bIPソース複素数ベクトルの32ビット高速フーリエ変換を計算
FFTReal32bIP32ビット実数ソースベクトルの32ビット高速フーリエ変換を計算
IFFTComplexソース複素数ベクトルの逆高速フーリエ変換を計算し、結果をデスティネーション複素数ベクトルに格納
IFFTReal32b32ビット実数ソースベクトルの32ビット逆高速フーリエ変換を計算し、結果を32ビット実数デスティネーションベクトルに格納
IFFTComplexIP複素数ベクトルの逆高速フーリエ変換を計算
IFFTComplex32bIP複素数ベクトルの32ビット逆高速フーリエ変換を計算
IFFTReal32bIP2ビット実数ソース・ベクトルの32ビット逆高速フーリエ変換をその場で計算
SquareMagnitudeCplx複素ソース・ベクトルの各要素の大きさの2乗を計算
MagnitudeCplx32bIP32 ビット複素ソース・ベクトルの各要素の 32 ビット二乗マグニチュードを計算
TwidFactorInit離散フーリエ変換または離散コサイン変換で必要とされるトウィドル因子のセットの前半を生成
(fig.6-5)変換関数

■制御関数

関数名機能
PIDInitcontrolHistory が指す 3 要素配列の遅延線要素をクリア
PIDCoeffCalcPID係数の初期化
PIDPIDの実行
(fig.6-6)制御関数

■変換関数

関数名機能
Fract2Floatfractional をfloatに変換
Float2Fractfloatをfractional に変換
(fig.6-7)変換関数

■スタック関数

関数名機能
SetStackGuardスタックガード値を変更

DSPビルトイン関数

下記にビルトイン関数を示します。DSP命令を出力する関数は青字で示しています。

No.ビルトイン関数機能機械語
28.2.3__builtin_add_16シフトされた値をアキュムレータに加算add
28.2.4__builtin_add_32シフトされた値をアキュムレータに加算add
28.2.7__builtin_and_RCR浮動小数点コントロール・レジスタ( FCR )のビットクリアand
28.2.11__builtin_btg_32ビット反転btg
28.2.12__builtin_clrアキュムレータクリアclr a
28.2.18__builtin_div_321632bitと16bitの固定小数点除算divs.l
28.2.20__builtin_divf_1616bit同士の固定小数点除算divf.w
28.2.21__builtin_divf_3232bit同士の固定小数点除算divfl
28.2.22__builtin_divf_3216混合固定小数点除算divf.l
28.2.23__builtin_divmod_3216混合固定小数点除算と余りを出力divs.l
28.2.24__builtin_divmodf32bit固定小数点除算と余りをキャプチャdivfl
28.2.25__builtin_divmodf_1616bit固定小数点除算と余りをキャプチャdivf.w
28.2.34__builtin_ed_16(x-y)2の部分ユークリッド距離を計算し
結果をアキュムレータに格納 (16bit)
ed.w
28.2.35__builtin_ed_32(x-y)2の部分ユークリッド距離を計算し
結果をアキュムレータに格納 (32bit)
ed.l
28.2.37__builtin_edac_16(x-y)2の部分ユークリッド距離を計算し
アキュムレータに加算 (16bit)
edac.w
28.2.38__builtin_edac_32(x-y)2の部分ユークリッド距離を計算し
アキュムレータに加算 (32bit)
edac.l
28.2.42__builtin_fbcl値の左(Msb)から最初のビット変化を見つけるfbcl
28.2.43__builtin_fbcl_16符号ビットを飛ばして、左から最初のビット変化を見つける(16bit)fbcl
28.2.44__builtin_fbcl_32符号ビットを飛ばして、左から最初のビット変化を見つける(32bit)fbcl.l
28.2.45__builtin_ff1l値の左(Msb)から最初の1を見つける(32bit)ff1l
28.2.45__builtin_ff1r値の右(Lsb)から最初の1を見つける(32bit)ff1r
28.2.46__builtin_ff1l_16値の左(Msb)から最初の1を見つける(16bit)ff1l
28.2.47__builtin_ff1l_32値の左(Msb)から最初の1を見つける(32bit)ff1l.l
28.2.48__builtin_ff1r_16値の右(Lsb)から最初の1を見つける(16bit)ff1r
28.2.49__builtin_ff1r_32値の右(Lsb)から最初の1を見つける(32bit)ff1r.l
28.2.51__builtin_flim_32強制(符号付き)データ範囲制限(32bit)flim.l
28.2.53__builtin_flim_excess_32強制(符号付き)データ・レンジ・リミットとリミット超過結果flim.l
28.2.55__builtin_flimv_excess_32強制(符号付き)データ・レンジ・リミットとリミット超過結果flim.lv
28.2.56__builtin_fmax強制(符号付き)最大リミットfmax
28.2.57__builtin_fmax_excess強制(符号付き)最大リミットとリミット
超過結果
fmax.v
28.2.58__builtin_fmaxv_excess強制(符号付き)最大リミットとリミット
超過結果
fmax.v
28.2.59__builtin_fmin強制(符号付き)最小リミットfmin
28.2.60__builtin_fmin_excess強制(符号付き)最小リミットとリミット
超過結果
fmin.v
28.2.61__builtin_fminv_excess強制(符号付き)最小リミットとリミット
超過結果
fmin.v
28.2.62__builtin_get_isr_state現在のCPU割り込み状態の取得
28.2.63__builtin_ior_FCR浮動小数点制御(FCR )レジスタのビット設定ior
28.2.65__builtin_lac_16シフトおよびアキュムレータロード(16bit)lac
28.2.66__builtin_lac_32シフトおよびアキュムレータロード(32bit)lac
28.2.70__builtin_mac_16アキュムレート付き 16 ビット乗算mac
28.2.71__builtin_mac_32アキュムレート付き 32 ビット乗算mac.l
28.2.73__builtin_max_16最大値選択(16bit)max.w
28.2.73__builtin_max_32最大値選択(32bit)max.l
28.2.77__builtin_min_16最小値選択(16bit)min.w
28.2.77__builtin_min_32最小値選択(32bit)min.l
28.2.80__builtin_mod_3216混合モード整数モジュラス演算divs.l
28.2.85__builtin_mpy_16アキュムレータへの 16 ビット乗算mpy
28.2.86__builtin_mpy_32アキュムレータへの 32 ビット乗算mpy.l
28.2.88__builtin_mpyn_1616 ビットの乗算とアキュムレータへのネゲートmpyn
28.2.89__builtin_mpyn_3232 ビットの乗算とアキュムレータへのネゲートmpyn.l
28.2.91__builtin_msc_16アキュムレータからの 16 ビット乗算および減算msc
28.2.92__builtin_msc_32アキュムレータからの 32 ビット乗算および減算msc.l
28.2.94__builtin_mulss_1616ビット符号付き乗算(出力32ビット)mulss.w
28.2.95__builtin_mulss_3232ビット符号付き乗算(出力64ビット)mulss.d
28.2.97__builtin_mulsu_16混合符号の16ビット乗算(出力32ビット)mulsu.w
28.2.98__builtin_mulsu_32混合符号の64ビット乗算(出力32ビット)mulsu.d
28.2.100__builtin_mulus_16混合符号の16ビット乗算(出力32ビット)mulus.w
28.2.101__builtin_mulus_32混合符号の64ビット乗算(出力32ビット)mulus.d
28.2.103__builtin_muluu_1616ビット符号なし乗算(出力32ビット)muluu.w
28.2.104__builtin_muluu_3232ビット符号なし乗算(出力64ビット)muluu.d
28.2.110__builtin_pwrsavパワーセーブpwrsav
28.2.111__builtin_repeat_nop繰り返しNop生成repeat * nop
28.2.114__builtin_sac_16シフト(切り捨て)と16ビットへの丸めsac
28.2.115__builtin_sac_32シフト(切り捨て)と32ビットへの丸め?
28.2.118__builtin_sacr_16シフト(ラウンド)と16ビットへの丸めsac.r
28.2.119__builtin_sacr_32シフト(ラウンド)と32ビットへの丸めsacr.l
28.2.122__builtin_set_isr_state現在のCPU割り込み状態のセット
28.2.123__builtin_set_FCR浮動小数点コントロール・レジスタ(FCR)に値をセットmov.l
28.2.124__builtin_sftacアキュムレータのシフトsftac
28.2.128__builtin_swap_32バイトスワップswap.l
28.2.141__builtin_udiv混合モードの符号なし除算(16bit)divu.l
28.2.142__builtin_udivmod_3216混合モードの符号なし除算divu.l
28.2.143__builtin_umod_3216混合モードの符号なしモジュラス演算divu.l
28.2.144__builtin_write_ACCHアキュムレータ書込みlac.l
28.2.145__builtin_write_ACCLアキュムレータ書込みllac.l
28.2.146__builtin_write_ACCUアキュムレータ書込みluac.l
28.2.149__builtin_write_DISICTL閾値以下の割り込み禁止disictl
(fig.7-1)ビルトイン関数

扱う数値について

従来のdsPICは下記のとおり、-1 ~0.999969482 の範囲をQ15フォーマットで表現していました。

項目
フォーマットQ15(1.15)
範囲-1.0 ~ 0.999969482
ビットポジション
整数⇔fractional
対応 表
(fig.8-1)Q15表現

dspPIC33AKシリーズのDSPの乗算器は33×33ビットをサポートするようになったため、Q31フォーマットで表現します。

項目
flactionalQ31(1.31)
範囲-1.0 ~ 0.9999999995343387
ビットポジション
整数⇔fractional
対応 表
(fig.8-2)Q31表現

私が最初にDSPを上手く動かせなかった原因の一つが、この意識の違いでした。例えば、-0.3 * 0.5のような計算をビルトイン関数を使って整数で表現する場合、下表のとおり非常に大きな値が必要になることがあります。

dsPIC33 F/E/C シリーズdsPIC33Aシリーズ
__builtin_mulsu( -9830, 16384) >> 15__builtin_mulsu(-644245094 ,1073741824 ) >> 31
(fig.8-3)コード例

記事についての注意点

本記事は慎重に内容を検討し正確さに努めておりますが、もし内容に誤りがあったとしても、この記事を参考にして生じた損害等については一切の責任を負いません。

コメント

タイトルとURLをコピーしました