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.

CLAsqrt problems

Other Parts Discussed in Thread: CONTROLSUITE

I'm using F28069 and have been using the CLA and CLA math library to compute RMS in the following way:

VinRMS = CLAsqrt(VinSqSum / BUF_LEN);

where VinSqSum is a running sum of squares, and BUF_LEN is the number of samples ... this has been working fine and I get normal RMS calculations.

I read about CLAdiv in the CLA documentation and I wanted to try it because I thought it might be faster.  To avoid nested function calls (as advised to in the CLA documentation), I do the following:

float32 temp1;
temp1 = CLAdiv(VinSqSum, BUF_LEN);
VinRMS = CLAsqrt(temp1);

Now, VinRMS is coming out with unreasonable calculations.  Instead of the ~120Vrms, now it is calculating some huge number like 3.402823e+38 which seems like an overflow.

I checked the values being computed by CLAdiv, and they seem ok .. it seems the CLAsqrt() is causing things to blow up?

I double-checked and VinSqSum is always positive, and BUF_LEN is #define to be a positive integer, so the argument to CLAsqrt is never negative.

  • Hi,

    Can you post the disassembly for the code. Id like to take a look at what the compiler is doing with the arguments

    Also, can you try declaring temp as volatile and see if that changes anything?

  • Vishal, thank you for taking the time to respond.  Here is my C code 

        /*volatile*/ float32 temp1;
        /*volatile*/ float32 temp2;
        __mdebugstop();
        temp1 = CLAdiv(VoutSqSum, 268.0);
        VoutRMS = CLAsqrt(temp1);
    
        temp1 = CLAdiv(VinSqSum, 268.0);
        VinRMS = CLAsqrt(temp1);
        __mdebugstop();

    and disassembly:

    000099ea:   7F600000    MDEBUGSTOP 
    000099ec:   7FA00000    MNOP       
    000099ee:   7FA00000    MNOP       
    000099f0:   7FA00000    MNOP       
    000099f2:   7FA00000    MNOP       
    000099f4:   799F0212    MCCNDD     0x212, UNCF
    000099f6:   7FA00000    MNOP       
    000099f8:   73C01514    MMOV32     MR0, @0x1514, UNCF
    000099fa:   78414386    MMOVIZ     MR1, #0x4386
    000099fc:   74C08EE2    MMOV32     @0x8ee2, MR0
    000099fe:   799F01E4    MCCNDD     0x1e4, UNCF
    00009a00:   7FA00000    MNOP       
    00009a02:   7FA00000    MNOP       
    00009a04:   7FA00000    MNOP       
    00009a06:   74C01488    MMOV32     @0x1488, MR0
    00009a08:   799F01FE    MCCNDD     0x1fe, UNCF
    00009a0a:   7FA00000    MNOP       
    00009a0c:   78414386    MMOVIZ     MR1, #0x4386
    00009a0e:   73C0150E    MMOV32     MR0, @0x150e, UNCF
    00009a10:   74C08EE2    MMOV32     @0x8ee2, MR0
    00009a12:   799F01D0    MCCNDD     0x1d0, UNCF
    00009a14:   7FA00000    MNOP       
    00009a16:   7FA00000    MNOP       
    00009a18:   7FA00000    MNOP       
    00009a1a:   74C0148A    MMOV32     @0x148a, MR0
    00009a1c:   7FA00000    MNOP       
    00009a1e:   7FA00000    MNOP       
    00009a20:   7FA00000    MNOP       
    00009a22:   7F600000    MDEBUGSTOP 
    00009a24:   7FA00000    MNOP       
    00009a26:   7FA00000    MNOP       
    00009a28:   7FA00000    MNOP       
    00009a2a:   7FA00000    MNOP       

    now with volatile on temp1 temp2

        volatile float32 temp1;
        volatile float32 temp2;
        __mdebugstop();
        temp1 = CLAdiv(VoutSqSum, 268.0);
        VoutRMS = CLAsqrt(temp1);
    
        temp1 = CLAdiv(VinSqSum, 268.0);
        VinRMS = CLAsqrt(temp1);
        __mdebugstop();

    and disassembly:

    000099ea:   7F600000    MDEBUGSTOP 
    000099ec:   7FA00000    MNOP       
    000099ee:   7FA00000    MNOP       
    000099f0:   7FA00000    MNOP       
    000099f2:   7FA00000    MNOP       
    000099f4:   799F0212    MCCNDD     0x212, UNCF
    000099f6:   7FA00000    MNOP       
    000099f8:   73C01514    MMOV32     MR0, @0x1514, UNCF
    000099fa:   78414386    MMOVIZ     MR1, #0x4386
    000099fc:   74C08EE2    MMOV32     @0x8ee2, MR0
    000099fe:   799F01E4    MCCNDD     0x1e4, UNCF
    00009a00:   7FA00000    MNOP       
    00009a02:   7FA00000    MNOP       
    00009a04:   73C08EE2    MMOV32     MR0, @0x8ee2, UNCF
    00009a06:   74C01488    MMOV32     @0x1488, MR0
    00009a08:   799F01FE    MCCNDD     0x1fe, UNCF
    00009a0a:   7FA00000    MNOP       
    00009a0c:   78414386    MMOVIZ     MR1, #0x4386
    00009a0e:   73C0150E    MMOV32     MR0, @0x150e, UNCF
    00009a10:   74C08EE2    MMOV32     @0x8ee2, MR0
    00009a12:   799F01D0    MCCNDD     0x1d0, UNCF
    00009a14:   7FA00000    MNOP       
    00009a16:   7FA00000    MNOP       
    00009a18:   73C08EE2    MMOV32     MR0, @0x8ee2, UNCF
    00009a1a:   74C0148A    MMOV32     @0x148a, MR0
    00009a1c:   7FA00000    MNOP       
    00009a1e:   7FA00000    MNOP       
    00009a20:   7FA00000    MNOP       
    00009a22:   7F600000    MDEBUGSTOP 
    00009a24:   7FA00000    MNOP       
    00009a26:   7FA00000    MNOP       
    00009a28:   7FA00000    MNOP       
    00009a2a:   7FA00000    MNOP       

    Now this is interesting because I do not have any compiler optimizations turned on.  Making them volatile seems to work correctly now.  However, I thought volatile shouldn't matter since no optimizations are turned on?

  • Any thoughts Vishal?

  • Are you using lib 4.0.1.0? It was released on the last controlSUITE revision. I think i fixed an issue with the sqrt and div functions on that version. Im not sure if its the same issue...but could you give it a try and let me know

  • Thanks Vishal, I just updated it.  It looks like CLAdiv is slower than in-line divide anyway.  But, things seem to be working now.  Thank you.

  • Ok, thats good news. Just FYI, there was a bug in the old lib where the flags were carried over from subsequent function calls... so in your case the flag status was carried over from cladiv to clasqrt and the sqrt function was incorrectly interpreting the flag.

    The reason you weren't seeing the issue when you declare the variable as volatile is that volatile forces the compiler to save the result to memory and then load it again for the next operation (loading is what sets the flag); without volatile the results were just kept in registers and the flags weren't being reset. 

    I had fixed this issue in the new version of the library so you dont have to declare locals as volatile