## Avr studio and FMUL

32 posts / 0 new
Author
Message

Hello all,..

I tried to do a simple fractional multiplication by Atmega32 :

ldi r17,0b01000000
ldi r16,0b00000110
fmul r16,r17

0.5*6 = 3

So the final result (3) should be stored in the low byte (R0) but i found it stored in the high byte (R1) !!

Is that true or there is something wrong ??

Thanks 8).

Take a look at the application note AVR201: Using the AVR Hardware Multiplier:

http://www.atmel.com/dyn/resourc...

and the example program code:

http://www.atmel.com/dyn/resourc...

no there is nothing wrong. you are multiplying a 1.7 by a 1.7 number, the result is a 2.14 number FMUL brings this back to a 1.15 number by shifting the result left by 1.

Let's look at in binary
0b01000000 (0x40) * 0b00000110 (0x06) => 0b0000000110000000 (0x0180)
and then FMUL shifts left by 1
0b0000000110000000 (0x0180) => 0b0000001100000000 (0x0300)

In actuality you are multiplying 0.5 with 0.0234375 the result of which is 0.01171875

Alternatively you can look at it as multiplying a 1.7 number with a 8.0 number, the result of wich is a 9.7 number, and then shifted left, giving you a 8.8 number. So the "whole" part is in the upper byte of the 16 bit result, and as you can see in the binary abov, is your desired value of 3.

Writing code is like having sex.... make one little mistake, and you're supporting it for life.

Last Edited: Thu. Feb 14, 2008 - 10:43 PM

Yes i got it now, thanks guys for help.

Sorry but if i want to multiply float no as 0.5 to real number as 4 how can i do it!!

Or float * float is the only allowed to multiply by fmul?

Last Edited: Thu. Feb 14, 2008 - 10:50 PM

BTW, this link documents the fmul instruction (as well as the rest of the AVR instructions):

http://www.atmel.com/dyn/resourc...

black-code wrote:
Yes i got it now, thanks guys for help.

Sorry but if i want to multiply float no as 0.5 to real number as 4 how can i do it!!

Or float * float is the only allowed to multiply by fmul?

First read my edit, second fmul is NOT FLOAT, as I discussed earlier. Obviously you did not understand FMUL from the previous thread on this. FMUL simply takes A*B and then shifts it left by one, or if you like think of the result as A*B*2. How you interpret A&B and the result is up to you. Now FMUL is specifically designed to make working with 1.7 format numbers easier (hence the shift left by 1) however you are free to interpret the data however you like. As I said, if you multiply the 1.7 number by a 8.0 number, the result is an 8.8 number.

so 0.5(1.7) * 6(8.0) => 3.0(8.8), and that is EXACTLY the result that you got.

Fixed point numbers (1.7, 8.8, 8.0 etc) are all scaled values. You are taking your "real" rational numbers and converting them to an integer that is simply the rational number multiplied by some scaling factor. For a 1.7 number, the scaling factor is 128, for a 8.0 number the scaling factor is 1 (an 8.0 number is simply a natural integer, it has no fractional component. I use 8.0 here, so you can see how it nets out)

Now when you multiply two 8 bit values, you get a 16 bit value. When working with fixed point values (n.q) the result is in the form of (n1+n2.q1+q2) it's still 16 bits in size (assuming the fixed point values were each 8 bits in size). So as you can see multiplying a 1.7 number by an 8.0 number results in a 9.7 number. FMUL, is optimized for 1.7 format numbers, as a result it shifts left by 1 (multiplies by 2) in order to give you a result that is more easily interpreted again as a 1.7 number. In the case of our 1.7*8.0 this results in an 8.8 result. So if you want to convert back to a rational number, we have to divide by 256 (128*2), or simply look at the high byte of the result, if we don't care about the fractional part of the result.

I suggest reading the instruction set description of FMUL again, and also using google for learn more about "fixed point mathematics" or "fixed point numbers"

Writing code is like having sex.... make one little mistake, and you're supporting it for life.

Thanks glitch very much for your help :)

Glitch sorry :oops: :oops: :oops:

I totally understand what you said but i want to ask you if i want to do such operation (0.5 * 13) = (6.5) is it possible?

I performed it as following :

ldi r17,0b01000000
ldi r16,0b00001101
fmul r17,r16

R0=80h
r1=06h

So how it will be calculated to get the expected result if it is possible ?

Thanks man.

Any help PLZ about that :(

Quote:
I totally understand what you said but i want to ask you if i want to do such operation (0.5 * 13) = (6.5) is it possible?

If you are still asking this question, then you did not "totally understand" what Glitch said.

Regards,
Steve A.

The Board helps those that help themselves.

black-code wrote:
Glitch sorry :oops: :oops: :oops:

I totally understand what you said but i want to ask you if i want to do such operation (0.5 * 13) = (6.5) is it possible?

I performed it as following :

ldi r17,0b01000000
ldi r16,0b00001101
fmul r17,r16

R0=80h
r1=06h

So how it will be calculated to get the expected result if it is possible ?

Thanks man.

but your result IS 6.5, Remember the result is 8.8 format, when you multiply a 1.7 by an 8.0 using FMUL. The upper byte contains your whole number (6), and the lower byte contains the fractional portion 0x80 which is 0.5.

in fixed point math, the weights of the bits go as follows

```                              1 1
1 1 1 / /
1                 1 1 1 / / / 1 2
2 6 3 1           / / / 1 3 6 2 5
8 4 2 6 8 4 2 1 . 2 4 8 6 2 4 8 6
---------------------------------
0 0 0 0 0 1 1 0 . 1 0 0 0 0 0 0 0
6 . 5
```

Writing code is like having sex.... make one little mistake, and you're supporting it for life.

Thanks Glitch for your great help, so the only allowed operations in the fractional numbers are :
1.7 format (0.x or 1.x) with either 1.7 format or 8.0 format.

So that i can't perform such operation 0.5 * 3.5 as it not allowed by fmul so i need to use another techniques for that.

I am correct man (reply with yes or no)?

Thanks Glitch again.

NO THAT IS NOT WHAT I SAID! Go back and read it all, this thread, and the other one you started earlier.

Also do as I suggested earlier about reading up on fixed point mathematics.

Then after you've done that, go read the description of FMUL again, it should make more sense then.

So far you keep asking the SAME question over and over again, while the numbers are changing, THE QUESTION REMAINS THE SAME.

Writing code is like having sex.... make one little mistake, and you're supporting it for life.

Goodness, glitch, you've really done a good job explaining this, but it doesn't seem to be getting through. Looking at this thread, I keep wondering if I should add a visualizer to kavrcalc for fractional multication, but I'm not sure it would really help in this case.

I'm trying, but I'm running out of rope with this one. I can only think of one more thing to add.

As long as one of the numbers is in 1.7 format the result will be in a format that is the same as the other number plus 8 more bits of fractional data with FMUL.

thus:

```1.7 x 0.8 => 0.16 (0.8+8)
1.7 x 1.7 => 1.15 (1.7+8)
1.7 x 2.6 => 2.14 (2.6+8)
1.7 x 3.5 => 3.13 (3.5+8)
1.7 x 4.4 => 4.12 (4.4+8)
1.7 x 5.3 => 5.11 (5.3+8)
1.7 x 6.2 => 6.10 (6.2+8)
1.7 x 7.1 => 7.9  (7.1+8)
1.7 x 8.0 => 8.8  (8.0+8)
```

As you can see, if you look at only the high byte of the result after the multiplication, your result is in the exact same format as the 2nd operand to FMUL.

Writing code is like having sex.... make one little mistake, and you're supporting it for life.

I have a feeling it's because black-code doesn't like the answer. The name "FMUL" sounds like something that might be offering full floating point multiplication. It isn't. However many times you ask the question the situation won't change. True it will aid someone implementing a floating point maths lib but I think that's what black-code is really looking for. Now while there may well be fplibs in Asm for the AVR the usual solution is either to look towards a scaled integer (fixed point) solution in Asm or to switch to C where the C author has already implemented a float lib. Now, as it happens, the source code (in asm) for one of thse IS in the public domain (the float lib for the AVR GCC compiler) so if one really wanted a full AVR float lib this might make a good starting point. (or simply use it in the C context)

Cliff

:oops: really thanks glitch about that, now i am very shame to make you get out of your mode by my multi repeated questions, i read about fixed points many documents but the formats you inserted above wasn't found in those documents so i thought that the only available formats are 1.7 and 8.0 so don't be angry from me, you do a very great help making me understand this process (Thanks man for your great help), but now FMUL becomes very clear to me :).

Thanks.

clawson wrote:
I have a feeling it's because black-code doesn't like the answer. The name "FMUL" sounds like something that might be offering full floating point multiplication. It isn't. However many times you ask the question the situation won't change. True it will aid someone implementing a floating point maths lib but I think that's what black-code is really looking for. Now while there may well be fplibs in Asm for the AVR the usual solution is either to look towards a scaled integer (fixed point) solution in Asm or to switch to C where the C author has already implemented a float lib. Now, as it happens, the source code (in asm) for one of thse IS in the public domain (the float lib for the AVR GCC compiler) so if one really wanted a full AVR float lib this might make a good starting point. (or simply use it in the C context)

Cliff

Thanks cliff about your comment but i was really unable to understand what was the meaning of fixed point (although i read many documents about that), also the avr instruction set not really illustrate the FMUL instruction in a good way so this is the reason of my repeated questions that makes Glitch thinks that i am a hopeless case :(.

but now every thing is clear.
Thanks for all.

black-code wrote:
:oops: really thanks glitch about that, now i am very shame to make you get out of your mode by my multi repeated questions, i read about fixed points many documents but the formats you inserted above wasn't found in those documents so i thought that the only available formats are 1.7 and 8.0 so don't be angry from me, you do a very great help making me understand this process (Thanks man for your great help), but now FMUL becomes very clear to me :).

Thanks.

That would be because you are concentrating too much on the format of the numbers, and not the concept. No matter what the format of the fixed point number is, the concept of how they work is exactly the same, all that changes is the number of bits dedicated to each component of the value.

Writing code is like having sex.... make one little mistake, and you're supporting it for life.

black-code,

I wonder if it'd help if you said exactly what problem it is you are trying to solve by attempting to use FMUL. Could it have anything to do with converting ADC readings into a displayable range by any chance?

black-code, I added an FMUL calculator to KAVRCalc so perhaps that will help you better understand how to use FMUL: https://www.avrfreaks.net/index.p...

Edit: Oh, and black-code, maybe you wouldn't mind editing the subject of your thread and removing the "!!" because there is really nothing very exciting about the proper results that FMUL supplied.

kmr wrote:
Edit: Oh, and black-code, maybe you wouldn't mind editing the subject of your thread and removing the "!!" because there is really nothing very exciting about the proper results that FMUL supplied.

Ta da!...

Thanks Cliff, I don't know why, but there seems to be a lot of exclamation marks appended to fairly mundane subject lines recently.

Walmart were having a special on them last week!!!! (see)

I've heard they may be doing a deal on ???? next week.

Recall Pterry's warning - the use of excessive exclamation points is the sign of a diseased mind (oooer!) :mrgreen:

This thread got me interested in the FMUL instruction. So I went off to read the Instruction Summary (several times). I'm writing this just to verify my understanding.

While the document is pretty clear about most of it, I think it fails to state one thing.

Radix interpretation is in the eye of the programmer.

The instruction itself has no "radix interpretation" built into it. If the two numbers supplied are 0xF0 and 0x73, the instruction always gives the same 16-bit result, 0xD7A0.

If the programmer decides the first number is in a 2.6 format (giving 3.75) and the second is a 3.5 format (giving 3.59375), then he must interpret the result as a 5.11 format (13.4765625000).

However, he could just as easily say the first number was a 1.7 format (giving 1.875) and the second a 0.8 format (giving 0.44921875). Result is in a 1.15 format, giving 0.8422851600.

Same numbers into the FMUL. Same result. However, the interpretation of the result is different.

In essence, this is really just an integer multiply, with the fractional interpretation tacked on. I think... :?

BTW, thanks Kevin for adding the FMUL page to your KAvrCalc -- it made this clear for me!

Stu

Engineering seems to boil down to: Cheap. Fast. Good. Choose two. Sometimes choose only one.

Newbie? Be sure to read the thread Newbie? Start here!

stu_san wrote:
thanks Kevin for adding the FMUL page to your KAvrCalc -- it made this clear for me!
That's nice to hear that it made it clear to you, Stu. Also, I think your description of radix interpretation is of value to people are new to using fixed point scaling.

stu_san wrote:
Radix interpretation is in the eye of the programmer.

The instruction itself has no "radix interpretation" built into it. If the two numbers supplied are 0xF0 and 0x73, the instruction always gives the same 16-bit result, 0xD7A0.

Absolutely correct.

stu_san wrote:
If the programmer decides the first number is in a 2.6 format (giving 3.75) and the second is a 3.5 format (giving 3.59375), then he must interpret the result as a 5.11 format (13.4765625000).

Well not quite... FMUL adds a twist of a final shift left (multiply by 2) at the end [this is what differentiantes it from the standard MUL instruction], so the result ends up being a 4.12 number (with the lsb always 0). FMUL is specificically optimized to work with a 1.7 format number in at least one of the operands. Though it works with any other format, you just have to compensate for the extra shift. Depending on what you're doing, you might be better served using the regular MUL instruction for other formats.

Writing code is like having sex.... make one little mistake, and you're supporting it for life.

glitch wrote:
the result ends up being a 4.12 number
Good catch!

Hi, where can I download KAVRCalc by Kevin Rosenberg? Thanks.

 "Experience is what enables you to recognise a mistake the second time you make it." "Good judgement comes from experience.  Experience comes from bad judgement." "Wisdom is always wont to arrive late, and to be a little approximate on first possession." "When you hear hoofbeats, think horses, not unicorns." "Fast.  Cheap.  Good.  Pick two." "We see a lot of arses on handlebars around here." - [J Ekdahl]