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.

TMS320F28034: Obtaining both integer and fractional portion from IQNmpyI32int()

Part Number: TMS320F28034

I have a function that mulitiplies an _iq18 type with a large integer. I need both the integer and fractional portion of the result for subsequet computations. Currently the code looks something like this:

int32 counts = 320000;
_iq18 scaler = _IQ(0.667);
int32 intResult = _IQ18mpyI32int(scaler, counts);
_iq18 remainder = _IQ18mpyI32frac(scaler, counts);

According to documentation on the IQ library, _IQNmpyI32int() and _IQNmpyI32frac() each take over 20 cycles to complete. This code is located in a tight loop that is continuously repeated and so I would like to cut down on the number of execution cycles as much as possible. Is there any way to optimize this code? I suspect that _IQNmpyI32int() and _IQNmpyI32frac() are performing very similar computations; so if there is someway I could "combine" them, I feel like I could squeeze out just a little bit more CPU time. 

I thought about using the plain _IQNmpyI32() and then extracting the integer and fractional components out of the result. However, `counts` frequently evaluates to a very large number, so that the product of `counts` and `scaler` would exceed the range of an _IQ18 type.

  • Please give me a day or so to analyze this issue and get back to you.

    Thanks,

    Sira

  • Hi cneshi,

    IQ number is real number * 2^N converted to integer. Back conversion would be (float)IQ / 2^N. So real non-IQ integer part is

    intResult = youriq / 2^18 = youriq >> 18;

    IQ remainder

    remainder = youriq - (intResult << 18);

    It shouldn't take long on machines with barrel shifter. C2000 is one of such machines, it ant can shift 32bit integers by so many bit positions quite fast.

    But there's a problem with overflow in your numbers. scaler is (int)(0.667 * 2^18) = 174850. You can verify the value of this IQ number dividing it back by 2^18, you get 0.66699981689453125. Not exactly 0.667 but quite close.

    Integer representation of result IQ should be

    174850 * 320000 = 55952000000, which can't fit 32bits variable! You need to chose different IQ format or somehow split your calculation so that overflow doesn't happen.

    If it would be 64bits integer then your intResult would be 55952000000 >> 18  = 213439

    IQ remainder 55952000000 - (213439 << 18) = 246784. Again, to check how much it is, divide by 2^18 and you get 0.94140625. Is it OK? Yes, since 0.66699981689453125 * 320000 = 213439.94140625.

    Hope this helps

    Edward

  • Indeed IQNmpyI32 would not work in your case because of the dynamic range required.

    You are right - there are common portions to the _frac and _int functions. We don't release the assembly implementations of the IQMath library. If you're interested in creating a custom function in assembly combining the two and using it in your app, I could check if I can release the source for these two functions to you on a private channel.

    Thanks,

    Sira

  • Oh, I missed original subject a bit. Two separate multiplication functions, one for integer part, another one for fractional part are about 2x more then we need here. I think it should be single multiply

    _iq _IQmpyl32(_iq A, long B)

    then extracting integer and fractional parts like I wrote, something like this I think

    _iq18 result =  _IQ18mpyl32(scaler, counts);

    int32 intResult = result >> 18;

    _iq18 remainder = result - (intResult << 18);

     

    but 32000* iq18(0.667) overflows.

     

    Regards,

    Edward

  • If you could point me in the right direction on how to implement such a custom function that would be great!

    Thanks,

    Dave

  • Dave,

    Please request the IQMath lib source through this URL. You can ignore the questions in that form related to it being a signed agreement.

    https://www.ti.com/licreg/docs/swlicexportcontrol.tsp?form_type=1&prod_no=C2000-IQMATH-SOURCE-CODE&ref_url=&form_id=167029

    Thanks,

    Sira