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.

[参考译文] TMS320F28035:是否启用 F28035 CLA 浮点数学加速器

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1369322/tms320f28035-f28035-cla-floating-point-math-accelerator-enabled-or-not

器件型号:TMS320F28035

工具与软件:

尊敬的 TI 专家:

我目前使用 F28035 CLA 进行一些浮点计算、根据手册、这些计算受 CLA 硬件支持。

但是、我已经观察到单精度浮点乘法大约需要800ns。 我对此有几个问题:

  1. 浮点乘法实现 :浮点乘法是实际使用硬件浮点加速器,还是仍使用软件库? 如何验证使用的是哪一个?

  2. 启用硬件浮点加速器 :为了确保启用并正确使用硬件浮点加速器,我需要遵循哪些步骤?

此外、我已经在 CLA 中反汇编了浮点乘法运算、供您参考。

223 p->integralAccumulation += p->error * p->integralGain;


009402:0004推入 RPC
009403:7FF0 MOV *+XAR0[6]、AR7
009404:0000 ITRAP0
009405:7FA0 MOV @AR0、AR7
009406:0000 ITRAP0
009407:7FA0 MOV @AR0、AR7
009408:0000 ITRAP0
009409:7FA0 MOV @AR0、AR7
00940a:0000 ITRAP0
00940b:73D2添加*+ XAR2[2]、AH
00940c:00087FF0 BANZ 32752、AR0--
00940e:000A7FD0 BANZ 32720、AR2-
009410:0000 ITRAP0
009411:7FA0 MOV @AR0、AR7
009412:0000 ITRAP0
009413:7FA0 MOV @AR0、AR7
009414:0000 ITRAP0
009415:73E2地址*+XAR2[4]、AH
009416:0000 ITRAP0
009417:0691 MOVL ACC、*+ XAR1[AR0]
009418:0019 INTR INT10
009419:7C20 MOV @0x20、AR4
00941a:0000 ITRAP0
00941b:74D1 sub *+ XAR1[2]、AL
00941c:0000 ITRAP0
00941d:7FA0 MOV @AR0、AR7

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

    伊凡、您好!

    C28x 可以扩展以启用 FPU 支持(这允许使用 C28x 指令集加上 FPU 指令集。) 然而、CLA 是一个完全独立的处理器、有其自己的指令集。 CLA 指令集是 C28x+FPU 指令集的子集、因此它应该包含适用于大多数浮点指令(包括乘法)的等效数学指令。 这些浮点功能是 CLA 指令集固有的、因此无需执行任何操作即可启用它们。

    我在反汇编中看到的主要问题是有很多 ITRAP0指令。 ITRAP 指示提取了非法操作码、这意味着程序持续触发 ITRAP 中断并跳转到引导 ROM 中的 ITRAP ISR。 这可能会导致 CLA 程序存储器的映射方式出现问题。 需要检查的几个方面:

    1. 验证是否已选择 MMEMCFG。 PROGE 位被设定为1、这意味着 CLA 被授予到 CLA 程序存储器的访问权限。
    2. 请确保你正在将 CLA 程序存储器复制到一个可通过 CLA 访问的 LSRAM 中。 如果使用为 F2803x 提供的 CLA 链接器 cmd 文件、你应该在主 C 语言代码中有以下命令行来复制 CLA 程序:

    memcpy(&Cla1funcsRunStart, &Cla1funcsLoadStart,(Uint32)&Cla1funcsLoadSize);

    如果您有任何疑问或问题、请对这个回答进行投票表决、并告诉我。

    此致、

    德拉尼

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

    尊敬的 Delaney:感谢您的帮助。

    我已根据您的建议进行了检查。 看起来很好。 但 ITRAP 仍然存在。

    仅供参考、 CLA 中的代码 绝对有效、并且正确地控制 PWM、尽管计算很慢。 还有其他需要检查的东西吗?

    (1) MMEMCFG。 PROGGE 位。 它被置位。

    void cla_init(void)
    {
        EALLOW;
        Cla1Regs.MVECT1 = (Uint16)((Uint32)&Cla1Task1 - (Uint32)&Cla1Prog_Start);
        Cla1Regs.MVECT2 = (Uint16)((Uint32)&Cla1Task2 - (Uint32)&Cla1Prog_Start);
        Cla1Regs.MVECT3 = (Uint16)((Uint32)&Cla1Task3 - (Uint32)&Cla1Prog_Start);
    
        Cla1Regs.MPISRCSEL1.bit.PERINT1SEL = CLA_INT1_NONE;
        Cla1Regs.MPISRCSEL1.bit.PERINT2SEL = CLA_INT2_NONE;
        Cla1Regs.MPISRCSEL1.bit.PERINT3SEL = CLA_INT3_NONE;
        Cla1Regs.MIER.bit.INT1 = 1;
        Cla1Regs.MIER.bit.INT2 = 1;
        Cla1Regs.MIER.bit.INT3 = 1;
    
        Cla1Regs.MMEMCFG.bit.PROGE = 1;
        Cla1Regs.MCTL.bit.IACKE = 1;
        Cla1Regs.MMEMCFG.bit.RAM0E = 0;
        Cla1Regs.MMEMCFG.bit.RAM1E = 1;
        EDIS;
    }

    (2)存储器复制完成。 请在复制存储器后注意 cla_init()。 是问题吗?

        memcpy(&Cla1funcsRunStart, &Cla1funcsLoadStart, (Uint32)&Cla1funcsLoadSize);
        cla_init();

    (3).cmd 文件

    _Cla1Prog_Start = _Cla1funcsRunStart;
    -heap 0x200
    -stack 0x200
    
    CLA_SCRATCHPAD_SIZE = 0x100;
    --undef_sym=__cla_scratchpad_end
    --undef_sym=__cla_scratchpad_start
    
    MEMORY
    {
    PAGE 0:    /* Program Memory */
               /* Memory (RAM/FLASH/OTP) blocks can be moved to PAGE1 for data allocation */\
       RAMM1       : origin = 0x000750, length = 0x0000B0
       RAML3       : origin = 0x009000, length = 0x001000
    
       OTP         : origin = 0x3D7800, length = 0x000400     /* on-chip OTP */
       FLASHH      : origin = 0x3E8000, length = 0x002000     /* on-chip FLASH H*/
       FLASHCDEFG  : origin = 0x3EA000, length = 0x009FF0     /* on-chip FLASH CDEFG*/
    
       BEGIN	   : origin = 0x3F3FF0, length = 0x000004	   //App������ڵ�ַ
    
       ROM         : origin = 0x3FF27C, length = 0x000D44     /* Boot ROM */
       RESET       : origin = 0x3FFFC0, length = 0x000002     /* part of boot ROM  */
       VECTORS     : origin = 0x3FFFC2, length = 0x00003E     /* part of boot ROM  */
    
    PAGE 1 :   /* Data Memory */
               /* Memory (RAM/FLASH/OTP) blocks can be moved to PAGE0 for program allocation */
               /* Registers remain on PAGE1                                                  */
       BOOT_RSVD   : origin = 0x000000, length = 0x000050     /* Part of M0, BOOT rom will use this for stack */
       RAMM0       : origin = 0x000050, length = 0x000700     /* on-chip RAM block M0M1 */
    
       CLA1_MSGRAMLOW   : origin = 0x001480, length = 0x000080
       CLA1_MSGRAMHIGH  : origin = 0x001500, length = 0x000080
    
       RAML0L1     : origin = 0x008000, length = 0x000C00     /* on-chip RAM block L0L1L2 */
       CLARAM1     : origin = 0x008C00, length = 0x000400
    }
    
    /* Allocate sections to memory blocks.
       Note:
             codestart user defined section in DSP28_CodeStartBranch.asm used to redirect code
                       execution when booting to flash
             ramfuncs  user defined section to store functions that will be copied from Flash into RAM
    */
    
    SECTIONS
    {
       /* Allocate program areas: */
       .cinit              : > FLASHCDEFG      PAGE = 0, ALIGN(4)
       .pinit              : > FLASHCDEFG      PAGE = 0, ALIGN(4)
       .text               : > FLASHCDEFG      PAGE = 0, ALIGN(4)
       codestart           : > BEGIN       PAGE = 0, ALIGN(4)
    
       ramfuncs            : LOAD = FLASHCDEFG, ALIGN(4)
                             RUN = RAMM1,
                             LOAD_START(_RamfuncsLoadStart),
                             LOAD_SIZE(_RamfuncsLoadSize),
                             RUN_START(_RamfuncsRunStart),
                             PAGE = 0
    
       /* Allocate uninitalized data sections: */
       .stack              : > RAMM0       PAGE = 1, ALIGN(4)
       .ebss               : > RAML0L1      PAGE = 1, ALIGN(4)
       .esysmem            : > RAMM0       PAGE = 1, ALIGN(4)
    
       largeRAMData        : > RAMM0,   PAGE = 1
       .bss_cla		       : > CLARAM1,   PAGE = 1
       .scratchpad         : > CLARAM1,   PAGE = 1
    
       Cla1Prog            : LOAD = FLASHH,
                             RUN = RAML3,
                             LOAD_START(_Cla1funcsLoadStart),
                             LOAD_END(_Cla1funcsLoadEnd),
                             RUN_START(_Cla1funcsRunStart),
                             LOAD_SIZE(_Cla1funcsLoadSize),
                             PAGE = 0
    
       Cla1ToCpuMsgRAM     : > CLA1_MSGRAMLOW,   PAGE = 1
       CpuToCla1MsgRAM     : > CLA1_MSGRAMHIGH,  PAGE = 1
       Cla1DataRam1		   : > CLARAM1,		  PAGE = 1
    
       CLAscratch          :
                             { *.obj(CLAscratch)
                             . += CLA_SCRATCHPAD_SIZE;
                             *.obj(CLAscratch_end) } > CLARAM1,
    					     PAGE = 1
    
       /* Initalized sections go in Flash */
       /* For SDFlash to program these, they must be allocated to page 0 */
       .econst             : > FLASHCDEFG      PAGE = 0, ALIGN(4)
       .switch             : > FLASHCDEFG      PAGE = 0, ALIGN(4)
    
       /* .reset is a standard section used by the compiler.  It contains the */
       /* the address of the start of _c_int00 for C Code.   /*
       /* When using the boot ROM this section and the CPU vector */
       /* table is not needed.  Thus the default type is set here to  */
       /* DSECT  */
       .reset              : > RESET,      PAGE = 0, ALIGN(4), TYPE = DSECT
       vectors             : > VECTORS     PAGE = 0, ALIGN(4), TYPE = DSECT
    }
    

    (4)︎ 信息、基于此帖子(CLA 编译器所需的存储器大小大于 C28x - C2000微控制器论坛- C2000微控制器- TI E2E 支持论坛)、  

    "此处显示的汇编是 C28x 汇编、而不是 CLA。 我怀疑您在选择 C28x 调试抽头时从反汇编窗口复制了这个文件。 调试器窗口将尝试从 C28x 汇编助记符的角度解释 CLA 操作码;这就是为什么代码中有如此多的 ITRAP。"

    因此、对于同一行代码、以下内容应该是正确的 CLA 反汇编。 我可以看到很多 MNOP、我认为这是 CLA 的 NOP。 有任何改进建议吗?

    223 p->integralAccumulation += p->error * p->integralGain;
    
    000093e0:   7FF00004    MMOV16     MAR1, MR0, #0x4
    000093e2:   7FA00000    MNOP       
    000093e4:   7FA00000    MNOP       
    000093e6:   7FA00000    MNOP       
    000093e8:   73D20000    MMOV32     MR1, *MAR1, UNCF
    000093ea:   7FF00008    MMOV16     MAR1, MR0, #0x8
    000093ec:   7FD0000A    MMOV16     MAR0, MR0, #0xa
    000093ee:   7FA00000    MNOP       
    000093f0:   7FA00000    MNOP       
    000093f2:   73E20000    MMOV32     MR2, *MAR1, UNCF
    000093f4:   06910000    MMPYF32    MR2, MR2, MR1 || MMOV32    MR1, *MAR0
    000093f6:   7C200019    MADDF32    MR1, MR2, MR1
    000093f8:   74D10000    MMOV32     *MAR0, MR1

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

    伊凡、您好!

    感谢您分享自己的代码。 我看了看,明天再给你一个回应。

    此致、

    德拉尼

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

    伊凡、您好!

    内存复制完成。 请在复制存储器后注意 cla_init()。 是否有问题?

    不、这不应该是问题。 这是 建议的操作顺序。

    因此对于同一行代码,以下内容应该是正确的 CLA 反汇编。 我可以看到很多 MNOP、我认为这是 CLA 的 NOP。 是否有任何改进建议?

    我认为、是的、那么这应该是一个优化问题。 您可以尝试将优化更改为级别2或更高吗? 它将为并行指令提供更多机会、并且应该会提高性能。 可在工程的 Properties >> Build >> C2000 Compiler >> Optimization 中执行此操作。

    以下摘录自编译器指南( 此处链接)、并讨论了如何优化 CLA。

    此致、

    德拉尼