Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

[PIC] Why no Multiply and Divide for Q15 Fixed Point?

Status
Not open for further replies.

chinuhark

Member level 5
Joined
Aug 16, 2014
Messages
88
Helped
1
Reputation
2
Reaction score
1
Trophy points
8
Activity points
1,051
After spending the past few days getting the fixed point library to actually build, I was shocked to see that there are only Add and Subtract functions in the libq.h

First question is why no Multiply and Divide?

After playing around, I did get the the following code to multiply and give the correct result:

Code:
_Q15 a1 = _Q15ftoi(0.25);
_Q15 a2 = _Q15ftoi(0.45);
_Q15 a3;

long test1, test2, temp;

    test1 = a1;
    test2 = a2;
    temp = test1*test2;
    temp = temp>>15;
    a3 = temp;
    product = _itofQ15(a3);


The calculated value is correct (at least for these values) and measuring the speed shows the above multiplication takes about 0.5usec as opposed to 2.25usec for floating point. So atleast the purpose is not defeated.

But seriously, am I missing something? Is there no official super optimized function for Q15 multiplication and division from Microchip?

Also what trouble can I expect to run into if I use the above code...(calculation errors, overflows etc)?
 

First question is why no Multiply and Divide?
Probably because the uC family at question doesn't have the hardware to implement these operations efficiently.
 

Some Microchip fixed point libraries do provide multiply and division. The question would be much clearer if you mention the processor family and exact library version respectively give a Micrcochip link to it.
 

dsPIC33EP256MC202

XC16 1.25
MPLAB 3.10

libq.h
 

Thanks. I'm also using XC16 V1.25 and see _Q15 functions in the libraries manual and libq.h include file, but must confess wasn't even aware of it's existence.

I agree that a _Q15mul() and _Q15div() functions might be useful. The code shown in #1 misses handling of the overflow with -1.0 * -1.0 respectively 0x8000*0x8000.
The code can be also shortened by omitting various alias variable copies.


Code C - [expand]
1
2
3
4
if (a1 == 0x8000 && a2 == 0x8000)
      a3 = 0x7fff;
    else
      a3=(_Q15)((long)a1*(int)a2>>15);



Using optimization level 2, the code becomes quite compact, particularly any unnecessary long loads and zero multiplies are avoided. There won't be much improvement by referring to assembler coding.

Code:
                	  a3=(_Q15)((long)a1*(int)a2>>15);
  0548  B9C001     mul.ss 0x0010,0x0002,0x0000
  054A  DD0941     sl 0x0002,#1,0x0004
  054C  DE004F     lsr 0x0000,#15,0x0000
  054E  710000     ior.w 0x0004,0x0000,0x0000
  0550  DE88CF     asr 0x0002,#15,0x0002

compared to the situation with all optimizations turned off
Code:
                	  a3=(_Q15)((long)a1*(int)a2>>15);
  0552  90001E     mov.w [0x001c+2],0x0000
  0554  B90161     mul.su 0x0000,#1,0x0004
  0556  90002E     mov.w [0x001c+4],0x0000
  0558  DE80CF     asr 0x0000,#15,0x0002
  055A  B99A00     mul.ss 0x0006,0x0000,0x0008
  055C  780204     mov.w 0x0008,0x0008
  055E  B98B02     mul.ss 0x0002,0x0004,0x000c
  0560  780286     mov.w 0x000c,0x000a
  0562  420205     add.w 0x0008,0x000a,0x0008
  0564  B81000     mul.uu 0x0004,0x0000,0x0000
  0566  420201     add.w 0x0008,0x0002,0x0008
  0568  780084     mov.w 0x0008,0x0002
  056A  DD0941     sl 0x0002,#1,0x0004
  056C  DE004F     lsr 0x0000,#15,0x0000
  056E  710000     ior.w 0x0004,0x0000,0x0000
  0570  DE88CF     asr 0x0002,#15,0x0002
  0572  780F00     mov.w 0x0000,[0x001c]
 

Thanks FvM. Tried your function and not only is it foolproof and always gives the correct result but it also reduced the execution time from 0.5us to 0.36us. Being an electrical engineer, not studying basic C programming when I had the time always comes back to bite me in the @$$...

Just give me something similar for division now:lol:
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top