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.

DSP28035CLA的几个问题



有个问题看CLA的DATSHEET百思不得其解,就是几条指令之间,什么情况下使用MNOP指令,有的是在指令MCMPF32,MBCNDD前后加上三条MNOP指令,举个例子:有的前一条指令使用的是MCMPF32,后一条使用MTESTF指令,二者之间没有使用MNOP指令,只在MTESTF指令后使用了一条MNOP指令。还有一个例子,就是有的前一条指令使用的是MUI16TOF32,后一条使用MMOV32指令,二者之间使用了两条MNOP指令,MMOV32后没有使用MNOP指令

对何时使用MNOP规则不是很清楚,求助于各位大侠了,小弟在此先行谢过。

  • 这个问题的关键在于对流水线(pipeline)的理解。

    首先,CLA有自己独立的流水线,与C28x的流水线一样,都是8级,但不同的是,单步运行时,CLA是运行一步,流水线往前走一步,当在调试环境下运行到当前语句时,实际上它只执行到D2阶段,而C28x的流水线是会完全冲掉流水线,也即直接执行到E阶段,比branch为例,下图说明了调试时运行到跳转语句时对应的结果。那么对应实际运行在Flash上的代码,也会存在相同的问题,因而带来的结果是,C28x运行到当前语句,结果立即显示出来,而CLA则需要三条指令以后才可以得到。

    (http://processors.wiki.ti.com/index.php/Control_Law_Accelerator_(C2000_CLA)_FAQ#Q:_What_are_the_main_differences_between_the_CLA_and_the_C28x.2BFPU.3F)

    Single Step Moves pipeline ahead 1 cycle Completely flushes the pipeline

    由于这个原因,在CLA上,任务结束,调试暂停,跳转,函数调用和返回(MSTOP (end of task), MDEBUGSTOP (debug halt), MBCNDD(branch), MCCNDD (call), or MRCNDD (return))等几种情况下,其前后都需要各加入3个MNOP指令,以防止意外操作。

    同理,如果你的代码在当前语句要得到一个结果,并且接下来的语句需要利用该结果,正常来讲是没问题的,但如果是load或move而后一句又是直接赋值就有会有异常了,具体可以在CLA user guide里搜索一下“Pipeline Activity”了解。

    以CLA user guide的一个例子来看(搜索“MADDF32 MRa, MRb, #16FHi 32-bit Floating-Point Addition”指令说明后的example 1),下面标红的部分分别就对应于上面的两种情况。

  • 谢谢您的回复,解答了一些疑问,还有些疑惑,例如这一句“但如果是load或move而后一句又是直接赋值就有会有异常了”这里的“load或move而后一句又是直接赋值”是指对同一个寄存器赋值吗。举个例子比如一次移位操作中用到了MR0寄存器,接下来又是一个移位语句,是不是不能直接使用MR0寄存器了,需要在两条指令见加三条入MNOP指令。

  •  

    MMOVZ16    MR0,  @_ConversionCount

           MMOV16     MAR1, MR0, #_VoltageCLA  

        MUI16TOF32 MR0,  MR0 

     MADDF32    MR0,  MR0, #1.0                

        MCMPF32    MR0,  #NUM_DATA_POINTS.0       

     MF32TOUI16 MR0,  MR0                      

        MNOP                                      

        MMOVZ16    MR2,  @_AdcResult.ADCRESULT1   

        MMOV16     *MAR1, MR2                     

        MBCNDD     _RestartCount, GEQ             

        MMOVIZ     MR1,  #0.0                     

        MNOP

        MNOP

    MSTOP

    _RestartCount

    MMOV16      @_ConversionCount, MR1        

    MSTOP

        MNOP

        MNOP

        MNOP

    以上面的代码举个例子(CLA user guide P103页),MF32TOUI16 MR0,  MR0与MMOVZ16    MR2,  @_AdcResult.ADCRESULT1之间为什么用了一条MNOP指令?

    MBCNDD     _RestartCount, GEQ后不是应当有三条MNOP指令,而此处是MMOVIZ     MR1,  #0.0与两条MNOP指令,此处的MMOVIZ  MR1, #0.0是不是等同于一条MNOP指令?望您不吝赐教。

     

  • yi wang4 说:

    谢谢您的回复,解答了一些疑问,还有些疑惑,例如这一句“但如果是load或move而后一句又是直接赋值就有会有异常了”这里的“load或move而后一句又是直接赋值”是指对同一个寄存器赋值吗。举个例子比如一次移位操作中用到了MR0寄存器,接下来又是一个移位语句,是不是不能直接使用MR0寄存器了,需要在两条指令见加三条入MNOP指令。

    你引用的这一句中赋值指的是将前一句中的辅助寄存器MAR1里的内容赋给另一个结果寄存器MR1里时,由于流水线的操作,实际前面的结果还没出来,所以后面没法使用,才需要加入延时,请再次确认你根据我的提示搜索了"Pipeline Activity”了解了这个流程。

    你后面的例子不需要加入空指令。

  • yi wang4 说:

     

    MMOVZ16    MR0,  @_ConversionCount

           MMOV16     MAR1, MR0, #_VoltageCLA  

        MUI16TOF32 MR0,  MR0 

     MADDF32    MR0,  MR0, #1.0                

        MCMPF32    MR0,  #NUM_DATA_POINTS.0       

     MF32TOUI16 MR0,  MR0                      

        MNOP                                      

        MMOVZ16    MR2,  @_AdcResult.ADCRESULT1   

        MMOV16     *MAR1, MR2                     

        MBCNDD     _RestartCount, GEQ             

        MMOVIZ     MR1,  #0.0                     

        MNOP

        MNOP

    MSTOP

    _RestartCount

    MMOV16      @_ConversionCount, MR1        

    MSTOP

        MNOP

        MNOP

        MNOP

    以上面的代码举个例子(CLA user guide P103页),MF32TOUI16 MR0,  MR0与MMOVZ16    MR2,  @_AdcResult.ADCRESULT1之间为什么用了一条MNOP指令?

    MBCNDD     _RestartCount, GEQ后不是应当有三条MNOP指令,而此处是MMOVIZ     MR1,  #0.0与两条MNOP指令,此处的MMOVIZ  MR1, #0.0是不是等同于一条MNOP指令?望您不吝赐教。

     

    第一个MNOP与前面的有不同,可以说是第三种情况,你看user guide里的这个MNOP后有注释是"I7 Wait till I8 to read result",也就是等待读取ADC的结果,也就是说,如果不需要读ADC,那是可以不要这个空指令的,具体原因参考2.3 Shared Peripherals and EALLOW Protection的如下说明(需要等到第8个cycle才可以读ADC结果):

    第二个问题,你的理解正确,虽然说前后各需要三个MNOP,但实际上只要不是类似的跳转等指令,其它运行也是可以的,所以你可以把这些slots利用起来,做些其它事情的,并不一定都使用空指令。你可以看下P63的Example 2,其注释说明了是如何利用这些延时slots:This example is the same as Example1, except the code is optimized to take advantage of delay slots.

  • 谢谢您的回复。

  • 我想问下MBCNDD     _RestartCount, GEQ这处的跳转判断,是根据谁的值?

  • 您所说的“CLA上,任务结束,调试暂停,跳转,函数调用和返回(MSTOP (end of task), MDEBUGSTOP (debug halt), MBCNDD(branch), MCCNDD (call), or MRCNDD (return))等几种情况下,其前后都需要各加入3个MNOP指令”这只是在ccs单步调试时用加上3个MNOP指令,可以方便调试时直接看到运算结果,如果不是在单步调试,去掉仿真器连接,dsp板完全运行时,是可以不加这3个MNOP的是吧