ホーム › フォーラム › Texas Instruments › マイコン › C2000 › IQ型のデジタル演算について
このトピックには4件の返信が含まれ、2人の参加者がいます。5 年、 3 ヶ月前に amatsu1 さんが最後の更新を行いました。
-
投稿者投稿
-
IQ型のデジタル演算について
デバイス型番:TMS320F28027いつも大変お世話になっております。
早速ですが、以下の件についてご回答願います。
(お忙しい中恐縮ですが、本日中にご回答いただけると幸いでございます)①以下のようなソースコードを書いて動かしていましたが、日本語マニュアルP78の__IQmpyに関する記載から
上位16bitしか取り出させておらず、HRPWMを活かせていない(整数部のみしか使っていない)のではないかと思い、
日本語マニュアルP134のCMPAのレジスタを見て、上記の16を24へ変更しました。
これでHRPWMを活かせると考えたのですが、出力が出なくなってしまいました。
何故動かなくなったかご教示願います。#define GLOBAL_Q 16
NxtCntVal_Ch1 = __IQmpy(K0,Ierror0_Ch1,16)+__IQmpy(K1,Ierror1_Ch1,16)+__IQmpy(K2,CtrlVal1_Ch1,16);
EPwm3Regs.CMPA.all=__IQsat(NxtCntVal_Ch1, MAX_CNTVAL, MIN_CNTVAL);
(全ての変数はIQ型です)②以下のソースコードはA,Bでどちらが高速でしょうか。
A. __IQmpy((600-EPwm3Regs.CMPA.half.CMPA),16384,16)
B. (600-EPwm3Regs.CMPA.half.CMPA) >> 2以上、宜しくお願い致します。
amatsu1さん
お問い合わせ①
GLOBAL_Qの値は16で問題ないものと考えます。
__IQmpy関数(アンダースコアが2つ)の場合には、IQmathライブラリではなく、組み込み関数(Intrinsics関数)が使用されます。この詳細動作につきましては、Compiler User’s Guideによると、以下の命令で構成されます。
long dst = __IQmpy( long A, long B, int N )
15 < N < 32 : ( 以下、XT = A が行われたあとの命令です)
IMPYL P, XT, B ; A * B の下位32bitの計算(結果はPレジスタへ)
QMPYL ACC, XT, B ; A * B の上位32bitの計算(結果はACCレジスタへ)
LSL64 ACC:P, #(32 – N) ; ACC:Pから(32-N)ビットを左シフトわかりやすく、1.5 * 1.5の計算を例に、どのような計算が行われているか考えてみます。
#define GLOBAL_Q 16
_iq A = _IQ(1.5);
_iq B = _IQ(1.5);
_iq result;result = __IQmpy( A, B, 16 );
1.5を固定小数点で表すと、0x00018000になります。
__IQmpy( A, B, GLOBAL_Q )を細かく見ていくと、IMPYL P, 0x00018000, 0x00018000 → P = 0x40000000
QMPYL ACC, 0x00018000, 0x00018000 → ACC = 0x00000002
LSL64 ACC:P, #(32-16) → ACC😛 << 16 = (0x0000000240000000 << 16) = 0x0002400000000000
ACC = 0x00024000となります。CMPA.all(CMPA(16bit):CMPAHR(8bit))と同じフォーマットで小数点以下(CMPAHR)も設定できる構成になっています。
GLOBAL_Qは、少数ビットに何ビット使用するかを表すものですから、24を設定すると、32ビット中下位24ビットが小数部として使用されます。このとき、上記と同様に計算してみます。
#define GLOBAL_Q 24
_iq result;
result = __IQmpy( _iq(1.5), _iq(1.5), 24)結果は、result = 0x02400000となります。
この値をそのまま、CMPA.allに設定すると、整数部が期待値と異なってしまい、飽和処理でも正しい結果が出ないものと考えます。
お問い合わせ②
上記にも記載しましたが、__IQmpy関数では、3つの命令で構成されております。整数部しか使用されないのであれば、Bのシフト命令により1/4される方が、1命令少なくなりますので、その分高速になるものと考えます。
以上、ご確認のほど、よろしくお願いいたします。
- この返信は5 年、 3 ヶ月前に Yojiro さんが編集しました。理由: Underline(Ctrl-u)が正しく反映されないため
お世話になります。
ご回答いただき、誠にありがとうございます。①についてですが、私の記載が間違っており、大変恐縮なのですが、#define GLOBAL_Q 16はそのままで__IQmpyの第三引数を24に変えた方が良いのではないか?というご質問でした。
と言いますのも、せっかくHRPWMにしたのに、第三引数が16では__IQmpyの結果が整数部だけになってしまい、
EPwm3Regs.CMPA.allに上位16bitのみ数字が入り、下位16bitが0になってしまうと考えました。
この理解は違いますでしょうか。以上、宜しくお願い致します。
- この返信は5 年、 3 ヶ月前に amatsu1 さんが編集しました。
__IQmpyの第三引数は、小数部のビット数を表します。先程の回答に計算結果を記載しておりますが、第三引数を16とした場合、1.5 (0x00018000) * 1.5 (0x00018000) = 0x00024000と 整数部0x0002, 小数部0x4000となり、2.25という小数部を含む結果が得られます。整数部のみとなることはございません。
GLOBAL_Qを16として、__IQmpyのみ24とすると、ACC:Pが 0x00000002_40000000に対して8ビット左シフトとなりますので、resultは 0x0000_0240 と整数部が0、つまりCMPA=0, CMPAHR=0x02という値となります。
ご確認のほど、よろしくお願いいたします。
内容承知致しました。
ご対応いただき、誠にありがとうございました。 -
投稿者投稿