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.

C5505 vs floating point operations

My previous experience is based on floating point DSPs, so it was just the matter of time when I will meet efficiency problems. Using CSL i have written application with DMA ping-pong buffering. When one buffer is transfered to codec, other is being processed. In case of simple loopback (input buffer is copied to output pong buffer while output ping buffer is transmitted) i can hear sound correct. Problem appears, when I try to make fir filtration. Coefficients are stored in float table and buffers of samples are Int32, so mac operation looks like : Int32+=Int32*float. Of course that operation takes too many clock cycles, and buffer is not ready for time. Is there any state of art for that problem? I thought that DSPLIB would be goo solution, bu it support only Q.15/Q.31 types.Since these types have range (-1:1) and Int32 samples have values (0:FFFFFFFF), fallowing steps would be needed:

1.Convert and cast range of sample from Int32 to Q.31

2.make multiplication  (LDATA)sample*(LDATA)coefficient

3.Convert result from LDATA (Q.31) to Int32

 

but I don't know how to do that. Or maybe there is some better way? Such operation is vital for dsp, so I hope that it won't be any problem to provide some good solution.

Thanks in advance.

  • Conversion from Int32 to Q.31 is basically just a change in how you're thinking about the data. TI's C compiler doesn't have any real support for fractional types, so you have to keep track of the radix position on your own. Comment your code! Now if your signal is sitting in the bottom bits of your Int32, you'd be well-advised to shift it up into the top bits before calling functions that assume Q.xx data. Such functions are written to do word-length reduction at the right side, whereas integer functions do it at the left side. But a simple left shift is typically all you need to do.

    Now if by Int32, you're also implying offset-binary then, yes, you do need to convert to 2's complement before continuing.

    Does your application really require a 32*32 multiply? Probably not, if you're using properly-normalized fractional data handling. That's why Q.xx representations are popular. At the very least, its likely your coefficients could be Q.16, and maybe your data could be too. You don't actually have a 32-bit ADC, do you? If it's a 12 or 16 bit part, then going with a Q.16 data representation will allow you to use the FIR filtering function in DSPlib, which will be far, far, faster than anything you could code up in C. If you really do need to use Q.32 data, you'll have to write your own Q.32*Q.16 multiply. It's pretty straight-forward in assembly language, but doing it C usually takes me all day and gives me a splitting headache. If you must do it, it may be helpful to use TI's intrinsic functions, which map onto actual assembly language instructions. But beware: when you copy a long or long long into shorter type, the C compiler assumes you're doing integer math, not fractional, so it copies the bottom bits, not the top.

    You probably don't need to convert back to Int32 for the reasons stated earlier.

    David L. Rick

    Hach Company

     

  • Thanks for help, David. I have tested it with simple loopback with attenuation (fraction multiplying) and sounds fine. Still use mul32 function, but later I will try to use 16-bit  type instead. And of course this is much faster that virtual floating point operations, about 3-4 times less clock cycles.

  • I refresh topic, because I have new doubts. My current problem is - how to implement sin() and cos() functions using fixed point DSP (C5505 in this case)? Of course I'm not interested in using these functions in double type version. I suppose there is some fast solution, because there are e.g. FFT and IFFT transforms in DSPLIB, but I can't locate place where cos/sin result appears in assembler source code.

     Thanks for help in advance.

     

    EDIT:

    I've found that solution is quite simple - evaluation of certain function by Taylor  series.

  • Hello Michal,

    On "catalog" versions of the 55xx, there is a sin/cos table in ROM. You may need to change the state of the MC/MP bit before this will show up in your memory map. If I'm recalling correctly, there's only a quarter-cycle of data, so you'll have to do range-reduction using standard trig identities -- no big deal. I think the ROM table is not particularly large, but if you need better resolution, you can interpolate between values. A simple linear interpolation might do the job,  or you could use cubic interpolation, since derivatives at the end points are easy to find in this case.  This method will produce good results over a wider range than a simple Taylor expansion.

    David L. Rick

    Hach Company

     

  • Thanks David. I will try that way for sure.