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.

cc4306137 fractional mode,Q15 multipication

Other Parts Discussed in Thread: CC430F6137

Hi,

I cannot understand how the fractional mode of the hardware multiplier of cc430f6137 work. So I need some help.

It is introduced in cc430 family user guide. And here is the source code for cc430f6137 fractional mode multiplication in CCS.

I want to know why we just can get the result from RESHI and meanwhile ignoring RESLO?

//******************************************************************************
//   CC430F613x Demo - Fractional mode, Q15 multiplication
//
//   Description: The example illustrates multiplication of 2 Q15 numbers in
//   fractional mode. The result is a Q15 (15 bit) number stored in the RES1
//   register. It can be viewed in the debugger window.
//
//
//   ACLK = 32.768kHz, MCLK = SMCLK = default DCO
//
//                CC430F6137
//             -----------------
//         /|\|                 |
//          | |                 |
//          --|RST              |
//            |                 |
//            |                 |
//
//   M Morales
//   Texas Instruments Inc.
//   April 2009
//   Built with CCE Version: 3.2.2 and IAR Embedded Workbench Version: 4.11B
//******************************************************************************

#include "cc430x613x.h"

unsigned int Result_Q15;

void main(void)
{
  WDTCTL = WDTPW+WDTHOLD;                   // Stop WDT

  MPY32CTL0 = MPYFRAC;                      // Set fractional mode

  MPYS = 0x7D70;                            // Load first operand
  OP2 = 0x1000;                             // Load second operand

  Result_Q15 = RESHI;                       // Q15 result

  MPY32CTL0 &= ~MPYFRAC;
 
  __bis_SR_register(LPM4_bits);             // Enter LPM4
  __no_operation();                         // For debugger
}

Please explain more detailed.

Regards,

Can

  •  Hi Can, did you know about what fractional math signify?

     You are multiplying two number where bit are not integer so weight is not power progression from 2^0 to 2^14 (1, 2 , 4 , 8, 16,32...16384) but negative power less than 0 so 2^-1 is half 2^-2 is a quarter and so on...(1/2,1/4,1/8,1/16,...1/16384..) so number are less than 1 and multiply of two less than one number result in more less than one number.. Number are Q15 so result is less than Q15 no problem lose one bit

  • Hi Reberto,
    Thanks for replying!
    Yes, I do know that the Q15 format numbers are in the range of -1 to 0.9999……But what confused me is that the two numbers in the example is 0x7D70 and 0x1000, and they are hexadecimal numbers, right? And in the mode of fractional, the result is 0x0FAE. But in the normal multiplication mode, the result is 0x07D70000. So I just cannot understand why multiply the two hexadecimal numbers in Q15 format? What is it for?

    Regards,
    Can
  • Q-values are used with Fixed-point calculations to get a higher resolution (decimals) of your calculation. Q15 is an integer value between 0 and 1.9999, 0x8000 = 1, or 1 left shifted by 15 = 0x8000.

    Therefore the final result of the calculation is Q15 or 15-bits too much shifted to the left. To get the correct value you need to Right shift the value back with 15, ‘MPYFRAC’ does this automatically for you.
    0x7d70 * 0x1000 = 0x7D70000 Right shift (>>) by 15 (MPYFRAC) = 0x0FAE.

    In your code you use two Q15 numbers, Q15*Q15=Q30, so your final result here –after one Q15 correction- is still a Q15 number
  • Can Chen1 said:
    But what confused me is that the two numbers in the example is 0x7D70 and 0x1000, and they are hexadecimal numbers, right?

     Right remember also a normalization apply to save one bit so

    0X7D70 is binary 0111 1101 0111 0000 and its value is .25 + .125 + .0625 + .03125 + .....

    0x1000 is binary  0001 0000 0000 0000 equivalent to 1/16 so it is equivalent to shift right 4 places number minus one for normalization so

    0111110101110000 become

    0000111110101110 xxx ->  0000 1111 1010 1110 xxx -> 0FAE

    Integer fractional math is important to speed up calculation but seems is forever forgot in favour of floating point has some advantages but caveat too better handled by integer/fractional math.


     Is this ok or is more bit confusing bits? ;)

  • Hi Leo,

    Thanks for explaining and I understand more about it.

    But I still have a doubt.When I give two numbers 0x7d70 and 0x1000.

     If I donot enable the flag and just do the multiplication, that is 0x7d70*0x1000=0x07d70000 and equals 32112*4096=131530752.

    And if I enable fractional mode, that 0x7d70*0x1000=0x0FAE and equals 0.97998047*0.125=0.12249755??

    Am I right?

  • Can Chen1 said:

    And if I enable fractional mode, that 0x7d70*0x1000=0x0FAE and equals 0.97998047*0.125=0.12249755??

     Right, so fractional number (Q)  are the number at right of decimal point or rational fraction of, Integers are at left of point and are usual integers. Fractional never are zero and as explained by Leo are to be used for IQ (integer fractional Math), I span from -32768 to 32767, Q span from  1/32768 to 1- 1/32768.

    refer to Q number

    http://en.wikipedia.org/wiki/Q_%28number_format%29

    and also to fixed point mathematics theory:

    en.wikipedia.org/.../Fixed-point_arithmetic

  •  Hi Can, please check also Leo answer as verified, it used precise mathematical wording as I removed to try be more basic explanation but first answer was correct. We are here to share knowledge and have other understanding than just asking, thank for your application, this is your gratitude of our work and is forever better than solving problems for free.

  • Yes, he explained right too except the Q15 format numbers' range. The range is -1 to 0.999……
  • This depends on how you use this. You can create a precision between Q1 and Qnnn..., Q15 is mostly used as an unsigned integer high precision factor (at least by me) for example a calibration value. I don't know situations where an signed 16-bit Q15 value has sense.
  • Roberto Romano said:
    please check also Leo answer as verified

    Roberto, thanks but I'm not hunting for points or 'Verified Answers', I just tries to help! Sometimes successful sometime partly or not, ho cares. Anyhow thanks.

  • Oh, yes. If it is used as unsigned ,its range will be 0 to 1.9999! Got it. Thanks very much!
    And my code used it as signed 16-bit Q15 format for a hardware filter. But I still cannot understand why it uses fractional mode. Just for precision?
  • Can Chen1 said:
    ut I still cannot understand why it uses fractional mode. Just for precision?

     HI, precision can be comparable to floating point too but math involved is much more simple and faster too, so we can use IQ number on integer processor where we need a fast response without using expensive and power hungry too floating point unit.

     Floating point numbers are treated like fractional so it is a part called significand, mantissa or coefficient, it is also a fractional number but another part of number is dedicated to exponent, this require  to handle them across operation applied to numbers.

     Integer IQ are still extended integer so you still can sum them and just remember Q is a fraction so multiplication move to right when Q applied and  move to left when I applied(division is opposite direction shifting).

     As Leo say there is no sense apply signed complement to fractional so it can just be added to.

    On number theory check also this about floating point and forever if you get time visit Konrad Zuse page to remember his great work.

    http://en.wikipedia.org/wiki/Floating_point

  • The use is especially for filters, for calculations with 'unsigned' high resolution Coefficients.
    Maybe you can show your code.
  • Leo Bosch said:
    Roberto, thanks but I'm not hunting for points or 'Verified Answers', I

     Hi Leo, this is clear from how you answer to question.

    Leo Bosch said:
    I just tries to help! Sometimes successful sometime partly or not, ho cares

     And this is why I asked to check your answer, I am proud you helped me pointing level and argument to provide as hint. So you provided language, I provided text to read and I see our poster show us is wanting to learn than just ask solution ready, this way I feel both of us provided successful help so imho half of success is due to you. ;)

  • void b_filter(signed int *d, signed int *t, unsigned short first_loop)
    {
    unsigned short i,j;
    signed int R=0;

    WDTCTL = WDTPW+WDTHOLD; // Stop WDT
    MPY32CTL0 = MPYFRAC; // Set fractional mode

    // initialize data
    if(first_loop==1)
    {
    for(i=0;i<24;i++)
    {
    *(t+i)= *(d+26+i);
    }
    }
    else
    {
    for (i=0;i<24;i++)
    {
    *(d+i) = *(t+i);
    *(t+i) = *(d+26+i);
    }
    }

    for(j=24;j<50;j++)
    {
    R=0;
    for(i=0;i<25;i++)
    {
    MPYS = FILTER_COEFF_b[i]; // Load first operand
    OP2 = d[j-i]; // Load second operand
    R += RESHI;
    }
    d[j-24]=R;
    }

    MPY32CTL0 &= ~MPYFRAC;
    }



    void b2_filter(signed int *d, signed int *t, unsigned short first_loop)
    {
    unsigned short i,j,nn=26;
    signed int R=0;

    WDTCTL = WDTPW+WDTHOLD; // Stop WDT
    MPY32CTL0 = MPYFRAC; // Set fractional mode

    // initialize data
    if(first_loop==1)
    {
    for(i=0;i<12;i++)
    {
    *(t+i)= *(d+14+i);
    }
    }
    else
    {
    for (i=0;i<12;i++)
    {
    *(d+i) = *(t+i);
    *(t+i) = *(d+26+i);
    }
    nn=38;
    }

    for(j=12;j<nn;j++)
    {
    R=0;
    for(i=0;i<13;i++)
    {
    MPYS = 0x09D8; // Load first operand
    OP2 = d[j-i]; // Load second operand
    R += RESHI;
    }
    d[j-12]=R;
    }

    MPY32CTL0 &= ~MPYFRAC;
    }


    Can you explain more for me?
  • Leo Bosch said:
    The use is especially for filters, for calculations with 'unsigned' high resolution Coefficients.

     And when just using only integer non fractional scaled number require too many bit and tend to overflow or loss resolution, this is a particular integer math.

  • Ok, thanks very much! Pls give me a second to digest about this part of floating point and IQ, etc…………
  • The most interesting part is missing, the definitions for 'FILTER_COEFF_b' and the use of 'd[]'.
  • Can Chen1 said:
    Can you explain more for me?

     Hi Can, this is not so simple as fractional number, I try the simplest way but this is complex theory of digital filter.

     The two function you posted apply a FIR filter to some data in repetitive way, the seconf one seems a chebychev filter, I have no idea of what are they doing in your code, result is to have your sampled data filtered out of some frequency and if played thru a scope appear smoothed like they passed on an analog filter. Best of these filter they are more and more selective than analog counterpart at expense of math behind them...

     I know what I wrote is not mathematically precise but I think using all Z transform and discrete transformation theory get unreadable too

    en.wikipedia.org/.../Finite_impulse_response

    It is well done but all Analytical Function theory and all complex math is in place so try google also FIR filter and browse all you find, I seen a You tube video too I don't like as teaching media but may be is more fine for you assist from speaker than read about a so not simple to grasp. A full college course and all math involved is required to understand convolution but just do a try...

     www.youtube.com/watch

    and this from element14 also is a good teaching material.

    https://www.youtube.com/watch?v=loHy8v9A8LY

  • Hi Leo,

    I am sorry but I cannot show more. Pls forgive. And the two filters are both Savitzky-Golay filters. They are used to smoothed sample data. I just don't know why it uses fractional mode.

    Regards,
    Can
  • Hi Roberto,

    Thanks for the resources you show me. I learned a lot.

    Regards,
    Can
  • Can Chen1 said:
    They are used to smoothed sample data. I just don't know why it uses fractional mode.

     Hi Chen, this is due to a property of mathematical series theory about convergence, using Integer number some care must be applied to prevent result from overflow, fractional number converge, in case of too small number converge to 0 but never overflow,.

     If you need a complete understanding of I fear is impossible without complete college course so some snapshot of all math theory can just give you an idea.

     If you just need use leave coefficient as they are, I am sorry but fractional theory require small knowledge FIR and IIR is a complex topic (not only in term of complex number, they are simplest in itself when used for phasor theory).

     Have fun with your code.

  • Can Chen1 said:
    I am sorry but I cannot show more. Pls forgive. And the two filters are both Savitzky-Golay filters. They are used to smoothed sample data. I just don't know why it uses fractional mode.

    I was just curious what Q-value they were using in the filters coefficients and the calculation result.

    But I see the Savitzky-Golay filter doesn’t use coefficients >0.999 or <-0.999 this makes the use of a signed Q15-value possible or in this case even necessary. And I must conclude: using signed 16-bit Q15-values has sense.

     

    There are two ways to perform a CPU calculation;

    Using a floating point processor which’s keeps automatically track of the decimal point, you can say a processor for dummy’s.

    Or using a fixed point (or Integer) processor. But here you must keep track of the value expression and the size or format (8, 16, 32 or 64-bit) of the result. But using this way it can give you better control over the Value size/format and program execution speed.

     

    Let’s try to explain with a simple filter example (not related to yours);

    You have 3 ADC values (E), your coefficients are: 0.3, 1.5 and -1.8. And the result must be: (E(n)*Coef1)+(E(n-1)*Coef2)+(E(n-2)*Coef3).

    The coefficients here have decimals, without a floating point processor you can’t use these values, they become 0, 1 and -1.

    An easy Q-value is Q10. A ‘1’ in Q10 expression is 1024 near 1000 so when this would be a voltage and you read 1800 you can directly say this is (near) 1800mV (a Voltage with a 3 decimal precession) without doing a calculation. BTW CCS can convert Q-values in the debug windows for you to the real value, done with the Value options.

    The 3 Coefficients in Q10 format will be now: 300, 1500 and -1800 (to be precise: 307, 1536 and -1843).

    Now calculation all 3 ADC values Ex*Coefx gives a 10-bit higher value, leaving them and adding all 3 together gives you also a more precise addition, now shifting the Result 10-bits to the right gives the correct output. But sometimes you want to keep the Q10 value.

     

    Therefore Fractional numbers expressed in a Q-format.

    Hope this clarifies it a little (or more).

  • Leo Bosch said:

    I was just curious what Q-value they were using in the filters coefficients and the calculation result.

    But I see the Savitzky-Golay filter doesn’t use coefficients >0.999 or <-0.999 this makes the use of a signed Q15-value possible or in this case even necessary. And I must conclude: using signed 16-bit Q15-values has sense.

     Good, so coefficient has no more secret, here we can have all and also mathematical convolution I tried to pass around, second routine appear to me as not one of this filter set but maybe some low pass was added for other purposes.

    http://en.wikipedia.org/wiki/Savitzky%E2%80%93Golay_filter

    All DSP theory is more ancient than processor started to crunch in real time, some are from 1800 ages as also Jean-Baptiste Joseph Fourier 21 March 1768 – 16 May 1830 work on heat transfer founded all our modern base to telecommunication. It was aware of electromagnetic waves but mathematically all was greatly done.

**Attention** This is a public forum