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.

CCS/TMS320F280049C: CLA Results are not Consistent

Part Number: TMS320F280049C

Tool/software: Code Composer Studio

Hi There!

I am trying to use CLA for implementing a filter in TMS320F280049C Launchpad. I had successfully implemented the filter and verified the results against my original MATLAB Algorithm. But after I ran my code in debug mode two to three times, I noticed that CLA was not producing the same results. The results were not consistent.

I tried several time but the could not find any reason for inconsistency. Earlier I thought, that my algorithm might be inconsistent. So, I verified my C Algorithm in Visula Studio but it was producing the consistent results. So the error seems to be in the platform implementation.

Some times, the kit produce the exact results while some times it produces wrong results.

I have attached a video with this post where I ran the code 4 to 5 times but only got the correct results on last attempt. 

Note: Ia m using 32 bit fpu and I have set it to relaxed mode. Also that, I am using level 4 optimization as depicted in the figure below.

Also that, Is this issue related with the debug mode of CLA in CCS?

The video was greater than 20MB so I here is the youtube link for the video. 

Regards,

Bilal

  • Hi,

    Which compiler version are you using? Please make sure you are using 18.12.1.

    There is a hardware bug with the MCMP and MSUB instructions which would be used for your integer comparison in your code.

    We have a compiler work around for this. Your issue may be due to this hardware bug and your integer comparison.

    Have you noticed if your comparison is not working proerly?

    sal
  • Sal!

    First, The compiler version that I am using is TI v18.1.2.LTS
    Second,
    By comparison, you mean, the calculation that I am doing in my code, in an if condition.
    I am doing two comparisons i.e.

    if(row >= Decimation_Factor)
    window = (window < (h_poly_len-1)) ? (window + 1) : 0;

    I have checked the results and both are working fine

    Thanks,

    Bilal
  • Yes, that was what I was referring too. OK. good that is working.

    How large are the differences in your results. Floating point will always yield some differences in results. This may be due to the rounding modes or the FPU implementation in the hardware. You always need to account for some variance or epsilon when using floating point.

    You can try to change the floating point round mode. It should be in the MSTF register.

    sal
  • Sal!

    Apologies for late reply. Can you tell me, where can I find the MSTF Register?
    I want to add more to the above question: I have been running CLA with level 4 optimization, 100 MHz Clock, and speed vs size trade off at maximum (5). With the above mentioned setting I was able to achieve 2.5us execution time on CLA and 1us on CPU. Both run in parallel. The problems/facts that I have noticed are as follow:

    -- When I run code with full optimization, I do not receive the exact answers each time.
    -- When I run the code without optimization, I achieve almost the exact results with a bit of consistency. the floating point is not that much precise but it is acceptable. I have already verified my algorithm on Visual Studio and the results are exact. But the code runs slower.

    -- Is there any collective problem with the debug mode and the optimization setting?

    -- I know that the debug capacity decreases when we increase the optimization level. But does it decrease below a level where it starts to produce wrong results?

    -- I can afford 5% variations in the results, but current results are not acceptable for me.

    -- Further that, With full optimization, when I try to pass information from one processor to another in debug mode( with manual start and stop on both processors i.e. breakpoints), the information does not flows. I am referring to Cla1ToCpuMsgRAM and CpuToCla1MsgRAM. The variables that I pass, are not received correctly. They remain at their initial values. Sometimes they jump out of range. I tried to synchronize the cpu with cla based on the message/flag from the cla. I wrote a simple code. My test code was as follow:


    In CLA task 1(): a variable flag is declared in Cla1ToCpuMsgRAM. When the CLA fires, triggered by the ADC interrupt (ADC is triggered by ePWM), is sets the
    ///////////////////////////////////////////////////////////////////////////
    CLA task 1()
    {
    flag = 1;
    processing....
    processing....
    processing....
    processing....
    processing....
    processing....
    processing....
    processing....
    flag = 0;
    }
    //////////////////////////////////////////////////////////////////////////
    In the main cpu:

    main()
    {
    initialization
    ....
    ...
    ...

    for(;;)
    {
    if(flag)
    {
    led on
    }
    else
    {
    led off
    }

    }
    ///////////////////////////////////////////////////////////////////////////

    Note: my entire code is based on example. Also that I have disabled the CLA_ISR(). I have also tried to store the value of flag in a variable and then check the value of that variable but it too did not work.

    Although I found a better way to synchronize the CLA and CPU i.e. the ADC interrupt that fires the cla. The same interrupt can also be written in the if condition in main CPU. This synchronization was working properly.
    But my concern in the above algorithm is, the information is not being shared between both the processors, with full optimization.I have no choice to turn off the optimization. the code is already too slow.

    I hope I was able to project the problem more clearly.
    I will also share my project fill in this thread, soon. Hopefully, if I am able to run the CLA, I am planing to make a video on my experience with CLA so others may benifit from it as well.

    Thanks,
    Bilal
  • First, the MSTF is an internal register to the CLA. You can find its information in the Technical Reference Manual. Just search for it in the CLA section.

    Second, the MIRUN register is readable by the C28 and can be used to indicate if the CLA is running. You won't need the flag variable for this then.

    Third, the int data sizes are different on CLA and C28. Make sure you use stdint.h data types when using shared variables.

    Fourth, Increasing optimizations may decrease the accuracy of the code. Also, as I mentioned floating point will not be exact on each device or core. There is a tolerance that needs to be accounted for.

    Fifth, compiler optimizations may remove some reads or writes if the compiler thinks it is safe to do so. If this is happening, then you probably aren't using the volatile key work for variables to make sure the reads and writes occur and are in order. You especially need to do this with shared variables and register accesses. This is basic MCU programming. You can find more information on the internet or related text books.

    Hope this helps,
    sal
  • Hi Sal!

    1) With full optimization, I was still unable to debug the code. I even disabled the CLA and just collected the samples from ADC in the CPU and the stored those in an array. After a while (1024 samples), When, I tried to read the array's content in debug mode, I found all zeros. So the error is no longer related to CLA and the shared variables.

    2) Later, I decided to use the Serial Communication Interface (SCI) and received data on serial monitor (Docklight) in computer. I integrated the SCI code at the bottom of my algorithm to send the final results to serial port on PC. I also turned ON the full optimization. The entire data was accurate (with 5% variation as you said, "the accuracy will decrease").

    So, I conclude that the debug mode does not support optimization (completely) and it was all debugger 's fault.

    3) About using the volatile keywork. I was using the volatile key word for the respective variables. But I found out that when I declare those variables as volatile, the execution times jumps to 10 - 20 folds (2.5us to 40us). So I eliminated the volatile declaration. Can you further comment on this behaviour? But never the less, without declaring the variables as volatile, I received the exact data at serial port.

    4) About using stdint.h, I will look into it. Thanks for sharing that information.

    Regards,
    Bilal
  • Hi Bilal,

    Glad you got this working. Interesting to see the debugger information may have changed the behavior in your case. That is surprising.

    Regarding (3). The volatile key word ensures that the writes and reads will happen in the exact order as written in C. Without the volatile keyword, the compiler is free to re-order the writes and reads and make more optimizations. This is why you are seeing the large difference in performance. Certain optimizations are being prevented by the volatile keyword.

    sal