This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] MSP430FR5994:LEA Q15 MAC 运行、返回值为预期值的两倍

Guru**** 2390755 points


请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/1022250/msp430fr5994-lea-q15-mac-operation-with-return-value-twice-the-expected

器件型号:MSP430FR5994

你好!

 在相关线程中、我能够确认是否有可能使用 MSP_Mac_Q15通过 LEA 应用具有 940个样本的两个矢量的 MAC 操作、因为它至少需要一个 Q31变量将结果存储在.leaRAM 中。 再次感谢 TI 的支持!

但我在测试中看到错误的结果。 例如、使用一个一向量+一个直流值为10的向量执行 MAC 操作、这两个向量都具有940个样本、它将返回18800、是预期值9400的两倍。

示例代码:

#define LEN 940
DSPLIB_DATA(x, 4)
static int16_t x[940];
DSPLIB_DATA(y, 4)
static int16_t y[940];
DSPLIB_DATA(mac, 4)
static int32_t mac;
static msp_status Status;
static msp_mac_q15_params MacSumParams;

for (uint16_t i = 0; i < LEN; i++) {
    x[i] = 10;
    y[i] = 1;
}

MacSumParams.length = LEN;
Status = msp_mac_q15(&MacSumParams, x, y, &(mac));
msp_checkStatus(Status); // Breakpoint here and watch mac

我已经阅读 了有关 MSP DSP 库:真实矢量(TI.com)的文档 、它显示了以下预期操作:

伪代码:   result = sum(srcA .* srcB)

为什么我看到这种错误的结果?  

Thank you and best regards,

-

罗德里戈

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    罗德里戈、您好!

    感谢您的详细博文。

    首先、在"MSP_MAC_Q15()"中使用"x"和"y"输入之前、我看不到您将"x"和"y"输入转换为_Q15的位置。 您的"mac"结果也应采用_IQ31格式。

    其次、"MacPower2SumParams"和"MacSumParams"不匹配。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    感谢 James 的两点。

    我被用来在函数参数中进行显式转换、即使这不是必需的。 由于 AFAIK 是  同一类型、所以编译器不会进行转换。 我已按照建议更改了代码、以避免误解。

    "mac"变量不需要转换、因为它是 int32_t

    DSPLib_types.h

    2.谢谢。 我没有粘贴实际使用的代码、这个"伪代码"(它没有主函数)示例出现了一些错误。

    由于这是一个非常简单的实验、而且函数在 DSPLIB 文档中没有任何示例、因此 TI 的支持能否提供 MSP_MAC_Q15的工作示例?

    我仍然有这个"加倍"的值问题。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我不确定您的结果为何会翻倍。 请给我一两天时间来尝试重复此操作。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您对输入和输出数据的描述在我看来有点奇怪。 Q15类型的范围是+/- 1.0、或多或少。 也许您说您正在将整数类型的数据放入向量中?

    两个 Q15值的乘法与两个整数的乘法不同。 结果必须向右移位、以使二进制点返回到 Q15的正确位置。 假设您需要 Q15。 对于 Q31类型、结果必须向左移动一次。 这是因为乘法的结果有30个小数位、而 Q31有31个小数位。

    由于听起来您不使用 Q15或 Q31数据、这可能是您的问题。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    感谢 David 的分析。

    这正是我的错误、也是 MSP_Mac_qXX 方法中定点变量乘法的错误陈述。

    我已将此问题标记为已解决。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    罗德里戈、您好!

    David 对其进行了很好的总结。 基本上、LEA 旨在实现 Q15格式的输入、但我了解您为什么要"欺骗"LEA 并将其用于整数向量 Mac。

    我能够复制您的结果。 对于 inputX[]= 10和 inputY[]= 1,结果始终是预期结果的2倍。 例如、每个输入数组中的12个元件将产生240而不是120。

    在进行一些挖掘后、我认为这可以归因于 LEA 从 Q15转换为 IQ31。 在正常的 IQMath 中、将两个 IQ15值相乘会得到一个 Q30值、而不是 Q31。 因此、您将提供两个输入、LEA 认为它们是 Q15、结果是 IQ31而不是 IQ30。 因此、IQ31结果为2倍(向左移1)。 您应该能够将结果向右移动1、以获得正确的 IQ30值、该值已经是整数格式。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    对于未来的读者、这里是 MSP_MAC_Q15 ()的示例代码。 您可以将"iq31ResultVector"添加到表达式窗口中,并停止 while ()循环中的代码以查看结果。 请注意、我没有将其向右移动1。

    /* --COPYRIGHT--,BSD
     * Copyright (c) 2017, Texas Instruments Incorporated
     * All rights reserved.
     *
     * Redistribution and use in source and binary forms, with or without
     * modification, are permitted provided that the following conditions
     * are met:
     *
     * *  Redistributions of source code must retain the above copyright
     *    notice, this list of conditions and the following disclaimer.
     *
     * *  Redistributions in binary form must reproduce the above copyright
     *    notice, this list of conditions and the following disclaimer in the
     *    documentation and/or other materials provided with the distribution.
     *
     * *  Neither the name of Texas Instruments Incorporated nor the names of
     *    its contributors may be used to endorse or promote products derived
     *    from this software without specific prior written permission.
     *
     * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
     * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
     * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
     * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
     * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
     * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     * --/COPYRIGHT--*/
    //******************************************************************************
    #include "msp430.h"
    
    #include <math.h>
    #include <stdint.h>
    #include <stdbool.h>
    
    #include "DSPLib.h"
    
    /* Input signal parameters */
    #define SAMPLES             12
    
    /* Constants */
    #define PI                  3.1415926536
    
    /* Input vector X */
    DSPLIB_DATA(inputX,4)
    _q15 inputX[SAMPLES];
    
    /* Input vector Y */
    DSPLIB_DATA(inputY,4)
    _q15 inputY[SAMPLES];
    
    /* Result value */
    DSPLIB_DATA(iq31ResultVector,4)
    _iq31 iq31ResultVector;
    
    /* Benchmark cycle counts */
    volatile uint32_t cycleCount;
    
    void main(void)
    {
        uint16_t i;
        msp_status status;
        msp_mac_q15_params macParams;
        
        /* Disable WDT. */
        WDTCTL = WDTPW + WDTHOLD;
    
    #ifdef __MSP430_HAS_PMM__
        /* Disable GPIO power-on default high-impedance mode for FRAM devices */
        PM5CTL0 &= ~LOCKLPM5;
    #endif
        
        /* Initialize the arrays. */
        for (i = 0; i < SAMPLES; i++)
        {
            inputX[i] = 10;
            inputY[i] = 1;
            //inputX[i] = _Q15(0.5);
            //inputY[i] = _Q15(0.1);
        }
    
        /* Initialize the parameter structure. */
        macParams.length = SAMPLES;
        
        /* Invoke the msp_mac_q15 API. */
        msp_benchmarkStart(MSP_BENCHMARK_BASE, 1);
        status = msp_mac_q15(&macParams, inputX, inputY, &iq31ResultVector);
        cycleCount = msp_benchmarkStop(MSP_BENCHMARK_BASE);
        msp_checkStatus(status);
        
        /* End of program. */
        while(1)
        {
            __no_operation();
        }
    }