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.

[参考译文] MSP430FR5992:当一个为负值且结果应四舍五入为零时、小值的 rsmpy (非 rmpy)中的 IQMath 饱和问题

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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/1295680/msp430fr5992-iqmath-saturation-problem-in-rsmpy-not-rmpy-for-small-values-when-one-is-negative-and-result-should-be-rounded-to-zero

器件型号:MSP430FR5992

尊敬的所有人:

我在使用定点数学时遇到了问题。 这可能是理解上的问题、但我认为它更像是实施中的问题-希望没有硬件问题。

我想用_iq15格式将两个数字相乘、并偶然发现以下明显的错误:

 _IQ15 (-0.0015)= A =-49
_IQ15 (0.0015)= b = 49

到目前为止还不错…… 但是、将这两个值相乘会得到:
_IQ15rsmpy (a、b)= c =-2147484E+09
_IQ15toF (c)=-65536.0 ... 但它应该是0.00000225、应四舍五入为0

 如果我使用_IQ15rmpy (a、b)、则它返回正确的值"0"。

*编辑*正如编辑后的标题所说,我缩小了范围:只有一个值为负值,如果结果应四舍五入为0时,才会出现这种情况。我尝试过的所有其他情况都能正常工作。

 

我忽视了什么或理解错了什么? 如果有人能向我指出正确的方向、我将不胜感激。

 

祝你一切顺利

托比亚斯

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

    尊敬的 Tobias:

    我假设您使用32位数据格式进行数据处理、所以我认为这与此相关。

    430device 是16位数据 MCU ,因此当您调用"_IQ15rsmpy"时,它会 出现饱和,这可能会造成一些错误(如果它不处理高16位和低16位的饱和处理 )。

    我发现如果将变量定义为"int"、则它能够处理正确的结果。

    因此、我建议您使用 Q 格式、或使用不 饱和的函数。

    B.R.

    萨尔

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

    尊敬的 Sal:

    非常感谢您的回答-遗憾的是、我不能正确理解它、或者它不直接适用(或至少不应适用)。

    我使用的 MSP450FR599x 包含一个32位硬件乘法器(我认为是使用64位结果寄存器)。 IQmath 应该使用它... 很遗憾、我没有找到 IQmath 的 c/asm 代码、因此我可以自行修复。

    Qmath 的动态对于我的情况是不够的,因此可悲的是,这是没有选择。

    我不明白的是、为什么饱和是一个问题/当结果舍入到0时不起作用。 如果它在我可能理解的大值下无法正常工作、但在0左右时、它不应该做任何事情。 因为我需要饱和完成,我不知道如何实现它否则...

    "如果将变量定义为"int"、我发现它在得到正确结果的情况下起作用、这是什么意思? IQ 被定义为 int32_t…。

    恐怕 IQmath 或乘法器中有一个错误。。。 希望 TI 的相关人员能够一展身手。

     

    再次感谢和最美好的祝愿

    托比亚斯

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

    尊敬的  Tobias:

    您的意思是什么?"如果将变量明确表示为"int",我发现它在正确的结果下工作。"? IQ 定义为 int32_t…。

    抱歉。 int 表示 MSP430器件中的16位、我不清楚。

    实际上、由于 MSP430的 IQmath 库是 静态的、所以我无法解释为什么会发生这种情况。 但是、 我还有另一个相关建议:您可以下载 mspm0 SDK 以检查 IQmath 库、其中列出了源.c 文件、因此可以进行一些验证。

    以下是 mspm0 SDK 的链接:

    https://www.ti.com/tool/MSPM0-SDK?keyMatch=MSPM0%20SDK 

    B.R.

    萨尔

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

    尊敬的 Sal:

    再次感谢您的答复。

    我是否可以询问您在哪里找到了此 c 文件? 我在此处浏览了所有 IQMath 目录: https://dev.ti.com/tirex/explore/node?node=A__AMztb67RYAJCCVC9dL423Q__MSPM0-SDK__a3PaaoK__LATEST
    但只能找到标题和示例... 从此没有什么新东西可学习。

    *编辑*安装.exe 后,我找到你的意思... 一定要来看看

    但我认为这可能不适用、因为 MSPM0基于 Arm (我认为)、因此实现可能不同->可能不会发生此错误(无法明显检查)。

    祝你一切顺利

    托比亚斯

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

    那么、我尝试了 M0 SDK 中的 C 代码、它工作正常。

    -->因此错误必须在 IQmath 实现为 MSP430FR599x (和其他)... 可能是如何使用 MPY 模块寄存器(可能是 MACS32或 RES3)的(但这只是一种猜测、因为我不能研究非 M0库的实现)。

    希望一些 TI 雇主可以调查并上报此故障、以便修复。

    祝你一切顺利,并期待雇主/管理员的回复。

    托比亚斯

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

    查看库代码并不是很难。 我从不使用该库(我倾向于使用库不支持的混合格式)、但很容易转储一些内容。 例如:

    Disassembly of section .text:_IQ15rmpy:
    
    00000000 <_IQ15rmpy>:
       0:   02 12           push    r2              ;
       2:   32 c2           dint                    
       4:   03 43           nop                     
       6:   12 12 5c 01     push    &0x015c         ;
       a:   82 43 5c 01     mov     #0,     &0x015c ;r3 As==00
       e:   82 4c 44 01     mov     r12,    &0x0144 ;
      12:   82 4d 46 01     mov     r13,    &0x0146 ;
      16:   82 4e 50 01     mov     r14,    &0x0150 ;
      1a:   82 4f 52 01     mov     r15,    &0x0152 ;
      1e:   1e 42 54 01     mov     &0x0154,r14     ;0x0154
      22:   1c 42 56 01     mov     &0x0156,r12     ;0x0156
      26:   1d 42 58 01     mov     &0x0158,r13     ;0x0158
      2a:   3e 50 00 40     add     #16384, r14     ;#0x4000
      2e:   0c 63           adc     r12             ;
      30:   0d 63           adc     r13             ;
      32:   0e 5e           rla     r14             ;
      34:   0c 6c           rlc     r12             ;
      36:   0d 6d           rlc     r13             ;
      38:   b2 41 5c 01     pop     &0x015c         ;
      3c:   32 41           pop     r2              ;
      3e:   30 41           ret  

    这会将参数移动到硬件乘法器寄存器中、读取结果并进行舍入。  舍入是通过添加1/2LSB (在15位右移之前、以对齐二进制点)、即0x4000来完成的。

    另一版本:

    Disassembly of section .text:_IQ15rsmpy:
    
    00000000 <_IQ15rsmpy>:
       0:   02 12           push    r2              ;
       2:   32 c2           dint                    
       4:   03 43           nop                     
       6:   12 12 5c 01     push    &0x015c         ;
       a:   82 43 5c 01     mov     #0,     &0x015c ;r3 As==00
       e:   82 4c 44 01     mov     r12,    &0x0144 ;
      12:   82 4d 46 01     mov     r13,    &0x0146 ;
      16:   82 4e 50 01     mov     r14,    &0x0150 ;
      1a:   82 4f 52 01     mov     r15,    &0x0152 ;
      1e:   1e 42 54 01     mov     &0x0154,r14     ;0x0154
      22:   1c 42 56 01     mov     &0x0156,r12     ;0x0156
      26:   1d 42 58 01     mov     &0x0158,r13     ;0x0158
      2a:   3e 50 00 40     add     #16384, r14     ;#0x4000
      2e:   0c 63           adc     r12             ;
      30:   0d 63           adc     r13             ;
      32:   1f 42 5a 01     mov     &0x015a,r15     ;0x015a
      36:   3f 93           cmp     #-1,    r15     ;r3 As==11
      38:   18 38           jl      $+50            ;abs 0x6a
      3a:   03 20           jnz     $+8             ;abs 0x42
      3c:   3d 90 00 c0     cmp     #-16384,r13     ;#0xc000
      40:   14 28           jnc     $+42            ;abs 0x6a
    
    00000042 <IQNrsmpy_5$55$>:
      42:   0f 93           cmp     #0,     r15     ;r3 As==00
      44:   04 38           jl      $+10            ;abs 0x4e
      46:   0a 20           jnz     $+22            ;abs 0x5c
      48:   3d 90 00 40     cmp     #16384, r13     ;#0x4000
      4c:   07 2c           jc      $+16            ;abs 0x5c
    
    0000004e <IQNrsmpy_6$55$>:
      4e:   0e 5e           rla     r14             ;
      50:   0c 6c           rlc     r12             ;
      52:   0d 6d           rlc     r13             ;
      54:   b2 41 5c 01     pop     &0x015c         ;
      58:   32 41           pop     r2              ;
      5a:   30 41           ret    

    包括舍入步进在内的起始方式相同。 我将剩下的代码留给其他人分析。 我假设它有饱和。

    当完整的64位产品不是全部为1并且32位 IQ15格式 结果为时、就会出现问题。 舍入无法解决这个问题。

    通过添加0x4000来完成舍入。 如果结果中的特定位不是1、则不会发生进位。 对于小的负数、这将使为 IQ15格式结果选择的所有位保持为1。 不是你想要的

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

    尊敬的 Tibias:

    -->因此错误必须发生在针对 MSP430FR599x 的 IQmath 实施中(以及其他)... 可能是如何使用 MPY 模块寄存器(可能是 MACS32或 RES3)的(但这只是猜测、因为我不能查看非 M0库的实现)。

    至于430库代码、我想我们最近没有更新计划。  但我会 将该主题转发给我们的软件团队、他们可能会在可用时努力解决该问题。

    由于430 IQmath 库不可编辑。 在我这边、你可以将_IQ15rsmpy 函数从 M0迁移到430、并 根据结果进行一些修改。

    B.R.

    萨尔