cancel
Showing results for
Show  only  | Search instead for
Did you mean:
Visitor
14,899 Views
Registered: ‎11-20-2008

## Microblaze Floating Point Representation

Hi everyone,

I have an IP design which needs some floating point input values in order to produce results.

However, I'm not sure what kind of FP representation is being used by Microblaze. For example:

float x = 1.0f;

xil_printf(" 0x%08x \r\n",x);

The output should be 3F800000, instead of 3FF00000.

The Microblaze manual says that floating point numbers are in IEEE 754 Single Precision Format,

but as far as I know the above result should be 3F800000.

What am I missing here?

EDK 11.1 + Virtex 5 ML507.

Tags (4)
1 Solution

Accepted Solutions
Visitor
18,378 Views
Registered: ‎11-20-2008

Solved!

The idea is to declare an union:

union ufloat

{

float f;

unsigned u;

} x;

then:

x.f = 1.0f;

xil_printf(" %08x ",x.u);

The output is correct: 3F800000

Also, any data that should be passed through FSL (or PLB, etc) must be assigned as follows:

unsigned int input[8];

input[0] = x.u; // the unsigned representation

That is it!

Message Edited by alexandre.solon on 11-16-2009 07:37 AM
10 Replies
Xilinx Employee
14,884 Views
Registered: ‎04-23-2008
The compiler has probably not done the most intelligent job of type conversion.  Try this instead:

printf("0x%08x %f\n\r", *(unsigned*)(&f), f);

-Brian

Visitor
14,881 Views
Registered: ‎11-20-2008

Hello Brian,

Still, no sucess.

The major problem is that Microblaze seems to be performing Double Precision operations.

Example:

float input[8];

float output[8];

input[0[ = 0.0F;
input[1] = 2.0F;

input[2] = 2.0F;

etc...

my_fsl(
XPAR_MY_FSL_FSL_0_INPUT_SLOT_ID,
XPAR_MY_FSL_FSL_0_OUTPUT_SLOT_ID,
input,
output
);

The result that I am getting is incorret.

However, the following works:

unsigned int input[8];

unsigned int output[8];

input[0[ = 0x00000000;
input[1] = 0x40000000;

input[2] = 0x40000000;

etc...

my_fsl(
XPAR_MY_FSL_FSL_0_INPUT_SLOT_ID,
XPAR_MY_FSL_FSL_0_OUTPUT_SLOT_ID,
input,
output
);

Then the expected result is correct.

Visitor
18,379 Views
Registered: ‎11-20-2008

Solved!

The idea is to declare an union:

union ufloat

{

float f;

unsigned u;

} x;

then:

x.f = 1.0f;

xil_printf(" %08x ",x.u);

The output is correct: 3F800000

Also, any data that should be passed through FSL (or PLB, etc) must be assigned as follows:

unsigned int input[8];

input[0] = x.u; // the unsigned representation

That is it!

Message Edited by alexandre.solon on 11-16-2009 07:37 AM
Scholar
14,797 Views
Registered: ‎08-14-2007

why the union representation??, i think the right way is that if a number is float then is single precision(32 bits) and if the number is double then is double precision(64 bits), is not??

so if i have a 32-bit FPU and a 64-bit FPU, both made them with core generator, how can i provide right values for each one from microblaze application??

how can i obtain a double precision representation (64 bit)??

double a=1.0;   ??

best regards
Scholar
14,796 Views
Registered: ‎08-14-2007

by the way,

1.0 in single precision is  3F800000 and

1.0 in double precision is 3FF00000

and when i do this:

float      a=1.0;

double  b=1.0;

xil_printf("a = %x",a);

xil_printf("b = %x",b);

in BOTH cases i got   3FF00000, so microblaze always use double-precision representation??, but if is double-precision it must be a number of 64 bits right?? (i.e. 3FF0000000000000)

so i am confuse!!!

how i get a single precision number (32-bit) and how i get a double precision number (64-bit) in microblaze??

Xilinx Employee
14,794 Views
Registered: ‎08-06-2007

Hi,

By default all constants are double-precision unless specified as single-precision.

So to get single-precision constant you should add 'f' to the constant.

Like this:

float a=1.0f;

Furthermore printf will always convert all float to double precision before printing.

So If you want to print a single-precision, you need to convert the single precision to integer before calling printf.

Göran

Message Edited by goran_bilski on 11-20-2009 09:55 AM
Scholar
14,780 Views
Registered: ‎08-14-2007

how i convert single precision to integer, with a cast???

float a=3.2f;

xil_printf("a = %x",(int)a);

i only have the integer part of a, i did not get that part

the sinle representation of 3.2 in hexadecimal is 0x404CCCCD, how can i print that value??

Visitor
14,775 Views
Registered: ‎11-20-2008

Hi pumaju,

"Unions allow one same portion of memory to be accessed as different data types, since all of them are in fact the same location in memory." (from cplusplus.com)

In my case, it worked.

union my_union

{

float f;

unsigned u;

}a;

a.f = 1.0f;

xil_printf("a = %x",a.u);

If you need 64-bit floating point, then:

union my_union

{

double d;

unsigned long u;

}a;

a.d = 1.0;

xil_printf("a = %x",a.u);

Scholar
14,770 Views
Registered: ‎08-14-2007

thanks Alexandre, now i can view my single precision number

well now i want to view the single precision number that my FPU (made with core generator) , i got correctly the hexadecimal representation of my resul, i mean, my result in decimal is 4.515625 and its single representation is 0x40908000, so when i print "fval" variable i get 0x40908000, so that is correct, but when i try to print "4.515625" using whole and thousandths variables i got a rare number, how can i print "4.515625"???

float  fval;

xil_printf("\r\nResHW=%x",(u32)fval);

whole = fval;
thousandths = (fval - whole) * 1000;
xil_printf("\r\nResHW=%d.%3d\n", whole, thousandths);

thanks

Visitor
4,370 Views
Registered: ‎11-20-2008

Hi pumaju,

I haven't tried to print floating-point values, yet. (Only in hexa).

I guess that xil_printf("%f", fval.f) should have worked (with fval as a union).

Just in case, take a look at the floating point operator data sheet (page 19):

Floating Point Operator V5.0

I hope that it can be helpful,