Hello, I'm trying to use 2s complement fractional format in XC 167 a and I have following problem with multiplication:
/*2s complement fractional format - multiplication test*/ #include <XC167.h> #include <intrins.h> signed short int a = 1024; // = 0.03125 signed short int b = 1024; // = 0.03125 signed short int c, x; void main (void) { MCW = 0x0400; //MP = 1, automatic shift 1 bit left x = b * a; c = MDH; }
What made you think that shift by one would magically be applied for you without your code saying so? The code you've written makes assumptions that are plainly wrong for the actual data you're passing into and out of it. The code assumes the fixed-point numbers are shifted by 16 bits, but they're actually only shifted by 15 (plus a sign bit). Your best solution may be to drop the ties to a particular hardware and its registers, and use 32-bit integers and explicit shifts instead: c = ((signed long)a * b) >> 15; But make sure that C166 handles shifts of signed integers as expected before you use this.
Hi Pavel, your problem is that you have not used the MAC unit for multiplication: you should have used the CoMAC instruction to obtain the product and the shift at the same time. Please read the C166 V2 user's manual, chaper 8.2 (DSP Instruction Set) and take a look at the MAC.H file into the Keil C166 Include directory, which enables you to directly use the MAC unit in C. Ciao Bruno
I wanted to shift to left by one 32-bit result of multiplication. It should be ensured by setting of MAC Control Word (MCW_MP=1). Then high order 16 bits (reg. MDH) of shifted 32-bit result should be desired result. It is the same like shifting to right by 15 and using low order 16 bits. But your expression is independent on hardware. Thank you very much.
Maybe the best solution is to use the inline assembler. Take a look to: http://www.keil.com/appnotes/docs/apnt_178.asp This application note uses MAC instructions to implement a DSP algorithm.